History

lavc/vaapi_encode: wrap slice codes into row slice functions

Wrap current whole-row slice codes into following functions: - vaapi_encode_make_row_slice() - vaapi_encode_init_row_slice_structure()

Linjie Fu committed 6 years ago

Commit 65f4d561 parent 2c1cc321 file · +109 −81Browse files

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

Unified · Split

libavcodec/vaapi_encode.c+109−81
@@ -163,6 +163,61 @@ static int vaapi_encode_wait(AVCodecContext *avctx, · 162 unmodified lines
163 return 0;163 return 0;
164}164}
165 165
166static int vaapi_encode_make_row_slice(AVCodecContext *avctx,
167 VAAPIEncodePicture *pic)
168{
169 VAAPIEncodeContext *ctx = avctx->priv_data;
170 VAAPIEncodeSlice *slice;
171 int i, rounding;
172
173 for (i = 0; i < pic->nb_slices; i++)
174 pic->slices[i].row_size = ctx->slice_size;
175
176 rounding = ctx->slice_block_rows - ctx->nb_slices * ctx->slice_size;
177 if (rounding > 0) {
178 // Place rounding error at top and bottom of frame.
179 av_assert0(rounding < pic->nb_slices);
180 // Some Intel drivers contain a bug where the encoder will fail
181 // if the last slice is smaller than the one before it. Since
182 // that's straightforward to avoid here, just do so.
183 if (rounding <= 2) {
184 for (i = 0; i < rounding; i++)
185 ++pic->slices[i].row_size;
186 } else {
187 for (i = 0; i < (rounding + 1) / 2; i++)
188 ++pic->slices[pic->nb_slices - i - 1].row_size;
189 for (i = 0; i < rounding / 2; i++)
190 ++pic->slices[i].row_size;
191 }
192 } else if (rounding < 0) {
193 // Remove rounding error from last slice only.
194 av_assert0(rounding < ctx->slice_size);
195 pic->slices[pic->nb_slices - 1].row_size += rounding;
196 }
197
198 for (i = 0; i < pic->nb_slices; i++) {
199 slice = &pic->slices[i];
200 slice->index = i;
201 if (i == 0) {
202 slice->row_start = 0;
203 slice->block_start = 0;
204 } else {
205 const VAAPIEncodeSlice *prev = &pic->slices[i - 1];
206 slice->row_start = prev->row_start + prev->row_size;
207 slice->block_start = prev->block_start + prev->block_size;
208 }
209 slice->block_size = slice->row_size * ctx->slice_block_cols;
210
211 av_log(avctx, AV_LOG_DEBUG, "Slice %d: %d-%d (%d rows), "
212 "%d-%d (%d blocks).\n", i, slice->row_start,
213 slice->row_start + slice->row_size - 1, slice->row_size,
214 slice->block_start, slice->block_start + slice->block_size - 1,
215 slice->block_size);
216 }
217
218 return 0;
219}
220
166static int vaapi_encode_issue(AVCodecContext *avctx,221static int vaapi_encode_issue(AVCodecContext *avctx,
167 VAAPIEncodePicture *pic)222 VAAPIEncodePicture *pic)
168{223{
@@ -346,57 +401,17 @@ static int vaapi_encode_issue(AVCodecContext *avctx, · 177 unmodified lines
346 if (pic->nb_slices == 0)401 if (pic->nb_slices == 0)
347 pic->nb_slices = ctx->nb_slices;402 pic->nb_slices = ctx->nb_slices;
348 if (pic->nb_slices > 0) {403 if (pic->nb_slices > 0) {
349 int rounding;
350
351 pic->slices = av_mallocz_array(pic->nb_slices, sizeof(*pic->slices));404 pic->slices = av_mallocz_array(pic->nb_slices, sizeof(*pic->slices));
352 if (!pic->slices) {405 if (!pic->slices) {
353 err = AVERROR(ENOMEM);406 err = AVERROR(ENOMEM);
354 goto fail;407 goto fail;
355 }408 }
356 409
357 for (i = 0; i < pic->nb_slices; i++)410 vaapi_encode_make_row_slice(avctx, pic);
358 pic->slices[i].row_size = ctx->slice_size;
359
360 rounding = ctx->slice_block_rows - ctx->nb_slices * ctx->slice_size;
361 if (rounding > 0) {
362 // Place rounding error at top and bottom of frame.
363 av_assert0(rounding < pic->nb_slices);
364 // Some Intel drivers contain a bug where the encoder will fail
365 // if the last slice is smaller than the one before it. Since
366 // that's straightforward to avoid here, just do so.
367 if (rounding <= 2) {
368 for (i = 0; i < rounding; i++)
369 ++pic->slices[i].row_size;
370 } else {
371 for (i = 0; i < (rounding + 1) / 2; i++)
372 ++pic->slices[pic->nb_slices - i - 1].row_size;
373 for (i = 0; i < rounding / 2; i++)
374 ++pic->slices[i].row_size;
375 }
376 } else if (rounding < 0) {
377 // Remove rounding error from last slice only.
378 av_assert0(rounding < ctx->slice_size);
379 pic->slices[pic->nb_slices - 1].row_size += rounding;
380 }
381 }411 }
412
382 for (i = 0; i < pic->nb_slices; i++) {413 for (i = 0; i < pic->nb_slices; i++) {
383 slice = &pic->slices[i];414 slice = &pic->slices[i];
384 slice->index = i;
385 if (i == 0) {
386 slice->row_start = 0;
387 slice->block_start = 0;
388 } else {
389 const VAAPIEncodeSlice *prev = &pic->slices[i - 1];
390 slice->row_start = prev->row_start + prev->row_size;
391 slice->block_start = prev->block_start + prev->block_size;
392 }
393 slice->block_size = slice->row_size * ctx->slice_block_cols;
394
395 av_log(avctx, AV_LOG_DEBUG, "Slice %d: %d-%d (%d rows), "
396 "%d-%d (%d blocks).\n", i, slice->row_start,
397 slice->row_start + slice->row_size - 1, slice->row_size,
398 slice->block_start, slice->block_start + slice->block_size - 1,
399 slice->block_size);
400 415
401 if (ctx->codec->slice_params_size > 0) {416 if (ctx->codec->slice_params_size > 0) {
402 slice->codec_slice_params = av_mallocz(ctx->codec->slice_params_size);417 slice->codec_slice_params = av_mallocz(ctx->codec->slice_params_size);
@@ -1840,6 +1855,54 @@ static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx) · 1437 unmodified lines
1840 return 0;1855 return 0;
1841}1856}
1842 1857
1858static av_cold int vaapi_encode_init_row_slice_structure(AVCodecContext *avctx,
1859 uint32_t slice_structure)
1860{
1861 VAAPIEncodeContext *ctx = avctx->priv_data;
1862 int req_slices;
1863
1864 // For fixed-size slices currently we only support whole rows, making
1865 // rectangular slices. This could be extended to arbitrary runs of
1866 // blocks, but since slices tend to be a conformance requirement and
1867 // most cases (such as broadcast or bluray) want rectangular slices
1868 // only it would need to be gated behind another option.
1869 if (avctx->slices > ctx->slice_block_rows) {
1870 av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
1871 "configured number of slices (%d < %d); using "
1872 "maximum.\n", ctx->slice_block_rows, avctx->slices);
1873 req_slices = ctx->slice_block_rows;
1874 } else {
1875 req_slices = avctx->slices;
1876 }
1877 if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1878#if VA_CHECK_VERSION(1, 8, 0)
1879 slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_MULTI_ROWS ||
1880#endif
1881 slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1882 ctx->nb_slices = req_slices;
1883 ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
1884 } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1885 int k;
1886 for (k = 1;; k *= 2) {
1887 if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
1888 break;
1889 }
1890 ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
1891 ctx->slice_size = k;
1892#if VA_CHECK_VERSION(1, 0, 0)
1893 } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1894 ctx->nb_slices = ctx->slice_block_rows;
1895 ctx->slice_size = 1;
1896#endif
1897 } else {
1898 av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
1899 "slice structure modes (%#x).\n", slice_structure);
1900 return AVERROR(EINVAL);
1901 }
1902
1903 return 0;
1904}
1905
1843static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)1906static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
1844{1907{
1845 VAAPIEncodeContext *ctx = avctx->priv_data;1908 VAAPIEncodeContext *ctx = avctx->priv_data;
@@ -1847,7 +1910,7 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) · 1 unmodified line
1847 { VAConfigAttribEncSliceStructure } };1910 { VAConfigAttribEncSliceStructure } };
1848 VAStatus vas;1911 VAStatus vas;
1849 uint32_t max_slices, slice_structure;1912 uint32_t max_slices, slice_structure;
1850 int req_slices;1913 int ret;
1851 1914
1852 if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {1915 if (!(ctx->codec->flags & FLAG_SLICE_CONTROL)) {
1853 if (avctx->slices > 0) {1916 if (avctx->slices > 0) {
@@ -1886,44 +1949,9 @@ static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx) · 32 unmodified lines
1886 return AVERROR(EINVAL);1949 return AVERROR(EINVAL);
1887 }1950 }
1888 1951
1889 // For fixed-size slices currently we only support whole rows, making1952 ret = vaapi_encode_init_row_slice_structure(avctx, slice_structure);
1890 // rectangular slices. This could be extended to arbitrary runs of1953 if (ret < 0)
1891 // blocks, but since slices tend to be a conformance requirement and1954 return ret;
1892 // most cases (such as broadcast or bluray) want rectangular slices
1893 // only it would need to be gated behind another option.
1894 if (avctx->slices > ctx->slice_block_rows) {
1895 av_log(avctx, AV_LOG_WARNING, "Not enough rows to use "
1896 "configured number of slices (%d < %d); using "
1897 "maximum.\n", ctx->slice_block_rows, avctx->slices);
1898 req_slices = ctx->slice_block_rows;
1899 } else {
1900 req_slices = avctx->slices;
1901 }
1902 if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1903#if VA_CHECK_VERSION(1, 8, 0)
1904 slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_MULTI_ROWS ||
1905#endif
1906 slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1907 ctx->nb_slices = req_slices;
1908 ctx->slice_size = ctx->slice_block_rows / ctx->nb_slices;
1909 } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1910 int k;
1911 for (k = 1;; k *= 2) {
1912 if (2 * k * (req_slices - 1) + 1 >= ctx->slice_block_rows)
1913 break;
1914 }
1915 ctx->nb_slices = (ctx->slice_block_rows + k - 1) / k;
1916 ctx->slice_size = k;
1917#if VA_CHECK_VERSION(1, 0, 0)
1918 } else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1919 ctx->nb_slices = ctx->slice_block_rows;
1920 ctx->slice_size = 1;
1921#endif
1922 } else {
1923 av_log(avctx, AV_LOG_ERROR, "Driver does not support any usable "
1924 "slice structure modes (%#x).\n", slice_structure);
1925 return AVERROR(EINVAL);
1926 }
1927 1955
1928 if (ctx->nb_slices > avctx->slices) {1956 if (ctx->nb_slices > avctx->slices) {
1929 av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "1957 av_log(avctx, AV_LOG_WARNING, "Slice count rounded up to "

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