|
|
|
@@ -218,6 +218,33 @@ static int vaapi_encode_make_row_slice(AVCodecContext *avctx, |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int vaapi_encode_make_tile_slice(AVCodecContext *avctx, |
|
|
|
VAAPIEncodePicture *pic) |
|
|
|
{ |
|
|
|
VAAPIEncodeContext *ctx = avctx->priv_data; |
|
|
|
VAAPIEncodeSlice *slice; |
|
|
|
int i, j, index; |
|
|
|
|
|
|
|
for (i = 0; i < ctx->tile_cols; i++) { |
|
|
|
for (j = 0; j < ctx->tile_rows; j++) { |
|
|
|
index = j * ctx->tile_cols + i; |
|
|
|
slice = &pic->slices[index]; |
|
|
|
slice->index = index; |
|
|
|
|
|
|
|
pic->slices[index].block_start = ctx->col_bd[i] + |
|
|
|
ctx->row_bd[j] * ctx->slice_block_cols; |
|
|
|
pic->slices[index].block_size = ctx->row_height[j] * ctx->col_width[i]; |
|
|
|
|
|
|
|
av_log(avctx, AV_LOG_DEBUG, "Slice %2d: (%2d, %2d) start at: %4d " |
|
|
|
"width:%2d height:%2d (%d blocks).\n", index, ctx->col_bd[i], |
|
|
|
ctx->row_bd[j], slice->block_start, ctx->col_width[i], |
|
|
|
ctx->row_height[j], slice->block_size); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static int vaapi_encode_issue(AVCodecContext *avctx, |
|
|
|
VAAPIEncodePicture *pic) |
|
|
|
{ |
|
|
|
@@ -407,7 +434,10 @@ static int vaapi_encode_issue(AVCodecContext *avctx, |
|
|
|
goto fail; |
|
|
|
} |
|
|
|
|
|
|
|
vaapi_encode_make_row_slice(avctx, pic); |
|
|
|
if (ctx->tile_rows && ctx->tile_cols) |
|
|
|
vaapi_encode_make_tile_slice(avctx, pic); |
|
|
|
else |
|
|
|
vaapi_encode_make_row_slice(avctx, pic); |
|
|
|
} |
|
|
|
|
|
|
|
for (i = 0; i < pic->nb_slices; i++) { |
|
|
|
@@ -1903,11 +1933,76 @@ static av_cold int vaapi_encode_init_row_slice_structure(AVCodecContext *avctx, |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static av_cold int vaapi_encode_init_tile_slice_structure(AVCodecContext *avctx, |
|
|
|
uint32_t slice_structure) |
|
|
|
{ |
|
|
|
VAAPIEncodeContext *ctx = avctx->priv_data; |
|
|
|
int i, req_tiles; |
|
|
|
|
|
|
|
if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS || |
|
|
|
(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS && |
|
|
|
ctx->tile_cols == 1))) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for " |
|
|
|
"current tile requirement.\n", slice_structure); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
} |
|
|
|
|
|
|
|
if (ctx->tile_rows > ctx->slice_block_rows || |
|
|
|
ctx->tile_cols > ctx->slice_block_cols) { |
|
|
|
av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) " |
|
|
|
"for configured number of tile (%d x %d); ", |
|
|
|
ctx->slice_block_rows, ctx->slice_block_cols, |
|
|
|
ctx->tile_rows, ctx->tile_cols); |
|
|
|
ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ? |
|
|
|
ctx->slice_block_rows : ctx->tile_rows; |
|
|
|
ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ? |
|
|
|
ctx->slice_block_cols : ctx->tile_cols; |
|
|
|
av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n", |
|
|
|
ctx->tile_rows, ctx->tile_cols); |
|
|
|
} |
|
|
|
|
|
|
|
req_tiles = ctx->tile_rows * ctx->tile_cols; |
|
|
|
|
|
|
|
// Tile slice is not allowed to cross the boundary of a tile due to |
|
|
|
// the constraints of media-driver. Currently we support one slice |
|
|
|
// per tile. This could be extended to multiple slices per tile. |
|
|
|
if (avctx->slices != req_tiles) |
|
|
|
av_log(avctx, AV_LOG_WARNING, "The number of requested slices " |
|
|
|
"mismatches with configured number of tile (%d != %d); " |
|
|
|
"using requested tile number for slice.\n", |
|
|
|
avctx->slices, req_tiles); |
|
|
|
|
|
|
|
ctx->nb_slices = req_tiles; |
|
|
|
|
|
|
|
// Default in uniform spacing |
|
|
|
// 6-3, 6-5 |
|
|
|
for (i = 0; i < ctx->tile_cols; i++) { |
|
|
|
ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols - |
|
|
|
i * ctx->slice_block_cols / ctx->tile_cols; |
|
|
|
ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i]; |
|
|
|
} |
|
|
|
// 6-4, 6-6 |
|
|
|
for (i = 0; i < ctx->tile_rows; i++) { |
|
|
|
ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows - |
|
|
|
i * ctx->slice_block_rows / ctx->tile_rows; |
|
|
|
ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i]; |
|
|
|
} |
|
|
|
|
|
|
|
av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n", |
|
|
|
ctx->tile_rows, ctx->tile_cols); |
|
|
|
|
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) |
|
|
|
{ |
|
|
|
VAAPIEncodeContext *ctx = avctx->priv_data; |
|
|
|
VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices }, |
|
|
|
{ VAConfigAttribEncSliceStructure } }; |
|
|
|
VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices }, |
|
|
|
{ VAConfigAttribEncSliceStructure }, |
|
|
|
#if VA_CHECK_VERSION(1, 1, 0) |
|
|
|
{ VAConfigAttribEncTileSupport }, |
|
|
|
#endif |
|
|
|
}; |
|
|
|
VAStatus vas; |
|
|
|
uint32_t max_slices, slice_structure; |
|
|
|
int ret; |
|
|
|
@@ -1925,7 +2020,7 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) |
|
|
|
ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) / |
|
|
|
ctx->slice_block_width; |
|
|
|
|
|
|
|
if (avctx->slices <= 1) { |
|
|
|
if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) { |
|
|
|
ctx->nb_slices = 1; |
|
|
|
ctx->slice_size = ctx->slice_block_rows; |
|
|
|
return 0; |
|
|
|
@@ -1949,7 +2044,25 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) |
|
|
|
return AVERROR(EINVAL); |
|
|
|
} |
|
|
|
|
|
|
|
ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure); |
|
|
|
if (ctx->tile_rows && ctx->tile_cols) { |
|
|
|
#if VA_CHECK_VERSION(1, 1, 0) |
|
|
|
uint32_t tile_support = attr[2].value; |
|
|
|
if (tile_support == VA_ATTRIB_NOT_SUPPORTED) { |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding " |
|
|
|
"pictures as multiple tiles.\n."); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
} |
|
|
|
#else |
|
|
|
av_log(avctx, AV_LOG_ERROR, "Tile encoding option is " |
|
|
|
"not supported with this VAAPI version.\n"); |
|
|
|
return AVERROR(EINVAL); |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
if (ctx->tile_rows && ctx->tile_cols) |
|
|
|
ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure); |
|
|
|
else |
|
|
|
ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure); |
|
|
|
if (ret < 0) |
|
|
|
return ret; |
|
|
|
|
|
|
|
@@ -1965,9 +2078,8 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) |
|
|
|
return AVERROR(EINVAL); |
|
|
|
} |
|
|
|
|
|
|
|
av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices " |
|
|
|
"(default size %d block rows).\n", |
|
|
|
ctx->nb_slices, ctx->slice_size); |
|
|
|
av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n", |
|
|
|
ctx->nb_slices); |
|
|
|
return 0; |
|
|
|
} |
|
|
|
|
|
|
|
|