History

lavc/vaapi_encode: add tile slice encoding support

Add functions to initialize tile slice structure and make tile slice: - vaapi_encode_init_tile_slice_structure - vaapi_encode_make_tile_slice Tile slice is not allowed to cross the boundary of a tile due to the constraints of media-driver. Currently adding support for one slice per tile. N x N tile encoding is supposed to be supported with the the capability of ARBITRARY_MACROBLOCKS slice structures. N X 1 tile encoding should also work in ARBITRARY_ROWS slice structure.

Linjie Fu committed 6 years ago

Commit a7c2cdf1 parent 65f4d562 files · +136 −8Browse files

Showing the changes to libavcodec/vaapi_encode.c (1 of 2 files). Show all

Unified · Split

libavcodec/vaapi_encode.c+120−8
@@ -218,6 +218,33 @@ static int vaapi_encode_make_row_slice(AVCodecContext *avctx, · 217 unmodified lines
218218 return 0;
219219 }
220220
221+static int vaapi_encode_make_tile_slice(AVCodecContext *avctx,
222+ VAAPIEncodePicture *pic)
223+{
224+ VAAPIEncodeContext *ctx = avctx->priv_data;
225+ VAAPIEncodeSlice *slice;
226+ int i, j, index;
227+
228+ for (i = 0; i < ctx->tile_cols; i++) {
229+ for (j = 0; j < ctx->tile_rows; j++) {
230+ index = j * ctx->tile_cols + i;
231+ slice = &pic->slices[index];
232+ slice->index = index;
233+
234+ pic->slices[index].block_start = ctx->col_bd[i] +
235+ ctx->row_bd[j] * ctx->slice_block_cols;
236+ pic->slices[index].block_size = ctx->row_height[j] * ctx->col_width[i];
237+
238+ av_log(avctx, AV_LOG_DEBUG, "Slice %2d: (%2d, %2d) start at: %4d "
239+ "width:%2d height:%2d (%d blocks).\n", index, ctx->col_bd[i],
240+ ctx->row_bd[j], slice->block_start, ctx->col_width[i],
241+ ctx->row_height[j], slice->block_size);
242+ }
243+ }
244+
245+ return 0;
246+}
247+
221248 static int vaapi_encode_issue(AVCodecContext *avctx,
222249 VAAPIEncodePicture *pic)
223250 {
@@ -407,7 +434,10 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 183 unmodified lines
407434 goto fail;
408435 }
409436
410− vaapi_encode_make_row_slice(avctx, pic);
437+ if (ctx->tile_rows && ctx->tile_cols)
438+ vaapi_encode_make_tile_slice(avctx, pic);
439+ else
440+ vaapi_encode_make_row_slice(avctx, pic);
411441 }
412442
413443 for (i = 0; i < pic->nb_slices; i++) {
@@ -1903,11 +1933,76 @@ static av_cold int vaapi_encode_init_row_slice_structure(AVCodecContext *avctx, · 1489 unmodified lines
19031933 return 0;
19041934 }
19051935
1936+static av_cold int vaapi_encode_init_tile_slice_structure(AVCodecContext *avctx,
1937+ uint32_t slice_structure)
1938+{
1939+ VAAPIEncodeContext *ctx = avctx->priv_data;
1940+ int i, req_tiles;
1941+
1942+ if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
1943+ (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
1944+ ctx->tile_cols == 1))) {
1945+ av_log(avctx, AV_LOG_ERROR, "Supported slice structure (%#x) doesn't work for "
1946+ "current tile requirement.\n", slice_structure);
1947+ return AVERROR(EINVAL);
1948+ }
1949+
1950+ if (ctx->tile_rows > ctx->slice_block_rows ||
1951+ ctx->tile_cols > ctx->slice_block_cols) {
1952+ av_log(avctx, AV_LOG_WARNING, "Not enough block rows/cols (%d x %d) "
1953+ "for configured number of tile (%d x %d); ",
1954+ ctx->slice_block_rows, ctx->slice_block_cols,
1955+ ctx->tile_rows, ctx->tile_cols);
1956+ ctx->tile_rows = ctx->tile_rows > ctx->slice_block_rows ?
1957+ ctx->slice_block_rows : ctx->tile_rows;
1958+ ctx->tile_cols = ctx->tile_cols > ctx->slice_block_cols ?
1959+ ctx->slice_block_cols : ctx->tile_cols;
1960+ av_log(avctx, AV_LOG_WARNING, "using allowed maximum (%d x %d).\n",
1961+ ctx->tile_rows, ctx->tile_cols);
1962+ }
1963+
1964+ req_tiles = ctx->tile_rows * ctx->tile_cols;
1965+
1966+ // Tile slice is not allowed to cross the boundary of a tile due to
1967+ // the constraints of media-driver. Currently we support one slice
1968+ // per tile. This could be extended to multiple slices per tile.
1969+ if (avctx->slices != req_tiles)
1970+ av_log(avctx, AV_LOG_WARNING, "The number of requested slices "
1971+ "mismatches with configured number of tile (%d != %d); "
1972+ "using requested tile number for slice.\n",
1973+ avctx->slices, req_tiles);
1974+
1975+ ctx->nb_slices = req_tiles;
1976+
1977+ // Default in uniform spacing
1978+ // 6-3, 6-5
1979+ for (i = 0; i < ctx->tile_cols; i++) {
1980+ ctx->col_width[i] = ( i + 1 ) * ctx->slice_block_cols / ctx->tile_cols -
1981+ i * ctx->slice_block_cols / ctx->tile_cols;
1982+ ctx->col_bd[i + 1] = ctx->col_bd[i] + ctx->col_width[i];
1983+ }
1984+ // 6-4, 6-6
1985+ for (i = 0; i < ctx->tile_rows; i++) {
1986+ ctx->row_height[i] = ( i + 1 ) * ctx->slice_block_rows / ctx->tile_rows -
1987+ i * ctx->slice_block_rows / ctx->tile_rows;
1988+ ctx->row_bd[i + 1] = ctx->row_bd[i] + ctx->row_height[i];
1989+ }
1990+
1991+ av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d x %d tile.\n",
1992+ ctx->tile_rows, ctx->tile_cols);
1993+
1994+ return 0;
1995+}
1996+
19061997 static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
19071998 {
19081999 VAAPIEncodeContext *ctx = avctx->priv_data;
1909− VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices },
1910− { VAConfigAttribEncSliceStructure } };
2000+ VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
2001+ { VAConfigAttribEncSliceStructure },
2002+#if VA_CHECK_VERSION(1, 1, 0)
2003+ { VAConfigAttribEncTileSupport },
2004+#endif
2005+ };
19112006 VAStatus vas;
19122007 uint32_t max_slices, slice_structure;
19132008 int ret;
@@ -1925,7 +2020,7 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) · 11 unmodified lines
19252020 ctx->slice_block_cols = (avctx->width + ctx->slice_block_width - 1) /
19262021 ctx->slice_block_width;
19272022
1928− if (avctx->slices <= 1) {
2023+ if (avctx->slices <= 1 && !ctx->tile_rows && !ctx->tile_cols) {
19292024 ctx->nb_slices = 1;
19302025 ctx->slice_size = ctx->slice_block_rows;
19312026 return 0;
@@ -1949,7 +2044,25 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) · 17 unmodified lines
19492044 return AVERROR(EINVAL);
19502045 }
19512046
1952− ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
2047+ if (ctx->tile_rows && ctx->tile_cols) {
2048+#if VA_CHECK_VERSION(1, 1, 0)
2049+ uint32_t tile_support = attr[2].value;
2050+ if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
2051+ av_log(avctx, AV_LOG_ERROR, "Driver does not support encoding "
2052+ "pictures as multiple tiles.\n.");
2053+ return AVERROR(EINVAL);
2054+ }
2055+#else
2056+ av_log(avctx, AV_LOG_ERROR, "Tile encoding option is "
2057+ "not supported with this VAAPI version.\n");
2058+ return AVERROR(EINVAL);
2059+#endif
2060+ }
2061+
2062+ if (ctx->tile_rows && ctx->tile_cols)
2063+ ret = vaapi_encode_init_tile_slice_structure(avctx, slice_structure);
2064+ else
2065+ ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
19532066 if (ret < 0)
19542067 return ret;
19552068
@@ -1965,9 +2078,8 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) · 9 unmodified lines
19652078 return AVERROR(EINVAL);
19662079 }
19672080
1968− av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices "
1969− "(default size %d block rows).\n",
1970− ctx->nb_slices, ctx->slice_size);
2081+ av_log(avctx, AV_LOG_VERBOSE, "Encoding pictures with %d slices.\n",
2082+ ctx->nb_slices);
19712083 return 0;
19722084 }
19732085

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t