41 int type,
char *
data,
size_t bit_len)
45 VABufferID param_buffer, data_buffer;
47 VAEncPackedHeaderParameterBuffer params = {
49 .bit_length = bit_len,
50 .has_emulation_bytes = 1,
58 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
59 VAEncPackedHeaderParameterBufferType,
60 sizeof(params), 1, ¶ms, ¶m_buffer);
61 if (vas != VA_STATUS_SUCCESS) {
63 "for packed header (type %d): %d (%s).\n",
64 type, vas, vaErrorStr(vas));
69 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
70 VAEncPackedHeaderDataBufferType,
71 (bit_len + 7) / 8, 1,
data, &data_buffer);
72 if (vas != VA_STATUS_SUCCESS) {
74 "for packed header (type %d): %d (%s).\n",
75 type, vas, vaErrorStr(vas));
81 "(%zu bits).\n",
type, param_buffer, data_buffer, bit_len);
99 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
101 if (vas != VA_STATUS_SUCCESS) {
103 "(type %d): %d (%s).\n",
type, vas, vaErrorStr(vas));
122 VAEncMiscParameterBuffer
header = {
125 size_t buffer_size =
sizeof(
header) +
len;
132 VAEncMiscParameterBufferType,
154 if (vas != VA_STATUS_SUCCESS) {
156 "%d (%s).\n", vas, vaErrorStr(vas));
177 rounding =
ctx->slice_block_rows -
ctx->nb_slices *
ctx->slice_size;
185 for (
i = 0;
i < rounding;
i++)
188 for (
i = 0;
i < (rounding + 1) / 2;
i++)
190 for (
i = 0;
i < rounding / 2;
i++)
193 }
else if (rounding < 0) {
229 for (
i = 0;
i <
ctx->tile_cols;
i++) {
230 for (j = 0; j <
ctx->tile_rows; j++) {
236 ctx->row_bd[j] *
ctx->slice_block_cols;
240 "width:%2d height:%2d (%d blocks).\n",
index,
ctx->col_bd[
i],
305 if (
ctx->codec->picture_params_size > 0) {
310 ctx->codec->picture_params_size);
319 VAEncSequenceParameterBufferType,
320 ctx->codec_sequence_params,
321 ctx->codec->sequence_params_size);
327 for (
i = 0;
i <
ctx->nb_global_params;
i++) {
329 ctx->global_params_type[
i],
330 ctx->global_params[
i],
331 ctx->global_params_size[
i]);
337 if (
ctx->codec->init_picture_params) {
338 err =
ctx->codec->init_picture_params(avctx, pic);
341 "parameters: %d.\n", err);
345 VAEncPictureParameterBufferType,
347 ctx->codec->picture_params_size);
353 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
354 ctx->codec->write_sequence_header) {
355 bit_len = 8 *
sizeof(
data);
356 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
359 "header: %d.\n", err);
363 ctx->codec->sequence_header_type,
370 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE &&
371 ctx->codec->write_picture_header) {
372 bit_len = 8 *
sizeof(
data);
373 err =
ctx->codec->write_picture_header(avctx, pic,
data, &bit_len);
376 "header: %d.\n", err);
380 ctx->codec->picture_header_type,
386 if (
ctx->codec->write_extra_buffer) {
390 err =
ctx->codec->write_extra_buffer(avctx, pic,
i, &
type,
396 "buffer %d: %d.\n",
i, err);
407 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC &&
408 ctx->codec->write_extra_header) {
411 bit_len = 8 *
sizeof(
data);
412 err =
ctx->codec->write_extra_header(avctx, pic,
i, &
type,
418 "header %d: %d.\n",
i, err);
438 if (
ctx->tile_rows &&
ctx->tile_cols)
447 if (
ctx->codec->slice_params_size > 0) {
455 if (
ctx->codec->init_slice_params) {
456 err =
ctx->codec->init_slice_params(avctx, pic, slice);
459 "parameters: %d.\n", err);
464 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE &&
465 ctx->codec->write_slice_header) {
466 bit_len = 8 *
sizeof(
data);
467 err =
ctx->codec->write_slice_header(avctx, pic, slice,
471 "header: %d.\n", err);
475 ctx->codec->slice_header_type,
481 if (
ctx->codec->init_slice_params) {
483 VAEncSliceParameterBufferType,
485 ctx->codec->slice_params_size);
491 #if VA_CHECK_VERSION(1, 0, 0)
494 if (sd &&
ctx->roi_allowed) {
497 VAEncMiscParameterBufferROI param_roi;
502 av_assert0(roi_size && sd->size % roi_size == 0);
503 nb_roi = sd->size / roi_size;
504 if (nb_roi >
ctx->roi_max_regions) {
505 if (!
ctx->roi_warned) {
507 "supported by driver (%d > %d).\n",
508 nb_roi,
ctx->roi_max_regions);
511 nb_roi =
ctx->roi_max_regions;
520 for (
i = 0;
i < nb_roi;
i++) {
528 pic->
roi[
i] = (VAEncROI) {
539 param_roi = (VAEncMiscParameterBufferROI) {
541 .max_delta_qp = INT8_MAX,
542 .min_delta_qp = INT8_MIN,
544 .roi_flags.bits.roi_value_is_qp_delta = 1,
548 VAEncMiscParameterTypeROI,
556 vas = vaBeginPicture(
ctx->hwctx->display,
ctx->va_context,
558 if (vas != VA_STATUS_SUCCESS) {
560 "%d (%s).\n", vas, vaErrorStr(vas));
562 goto fail_with_picture;
565 vas = vaRenderPicture(
ctx->hwctx->display,
ctx->va_context,
567 if (vas != VA_STATUS_SUCCESS) {
569 "%d (%s).\n", vas, vaErrorStr(vas));
571 goto fail_with_picture;
574 vas = vaEndPicture(
ctx->hwctx->display,
ctx->va_context);
575 if (vas != VA_STATUS_SUCCESS) {
577 "%d (%s).\n", vas, vaErrorStr(vas));
591 vas = vaDestroyBuffer(
ctx->hwctx->display,
593 if (vas != VA_STATUS_SUCCESS) {
595 "param buffer %#x: %d (%s).\n",
607 vaEndPicture(
ctx->hwctx->display,
ctx->va_context);
630 VACodedBufferSegment *buf_list, *buf;
643 if (vas != VA_STATUS_SUCCESS) {
645 "%d (%s).\n", vas, vaErrorStr(vas));
650 for (buf = buf_list; buf; buf = buf->next)
651 total_size += buf->size;
659 for (buf = buf_list; buf; buf = buf->next) {
661 "(status %08x).\n", buf->size, buf->status);
663 memcpy(ptr, buf->buf, buf->size);
673 if (vas != VA_STATUS_SUCCESS) {
675 "%d (%s).\n", vas, vaErrorStr(vas));
702 "%"PRId64
"/%"PRId64
".\n",
721 if (
ctx->codec->picture_priv_data_size > 0) {
770 int is_ref,
int in_dpb,
int prev)
843 if (current_depth ==
ctx->max_b_depth || start->
next->
next == end) {
844 for (pic = start->
next; pic; pic = pic->
next) {
863 for (pic = start->
next; pic != end; pic = pic->
next)
865 for (pic = start->
next,
i = 1; 2 * i < len; pic = pic->next,
i++);
882 current_depth + 1, &next);
887 current_depth + 1, last);
896 int i, b_counter, closed_gop_end;
901 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
916 "encode next.\n", pic->
b_depth);
925 closed_gop_end =
ctx->closed_gop ||
926 ctx->idr_counter ==
ctx->gop_per_idr;
927 for (pic =
ctx->pic_start; pic; pic = next) {
937 if (b_counter ==
ctx->b_per_p)
941 if (
ctx->gop_counter + b_counter + closed_gop_end >=
ctx->gop_size)
945 if (next && next->force_idr)
951 if (!pic &&
ctx->end_of_stream) {
960 "need more input for reference pictures.\n");
963 if (
ctx->input_order <=
ctx->decode_delay && !
ctx->end_of_stream) {
965 "need more input for timestamps.\n");
973 ctx->idr_counter = 1;
974 ctx->gop_counter = 1;
976 }
else if (
ctx->gop_counter + b_counter >=
ctx->gop_size) {
977 if (
ctx->idr_counter ==
ctx->gop_per_idr) {
981 ctx->idr_counter = 1;
988 ctx->gop_counter = 1;
991 if (
ctx->gop_counter + b_counter + closed_gop_end ==
ctx->gop_size) {
1000 ctx->gop_counter += 1 + b_counter;
1013 --
ctx->next_prev->ref_count[0];
1015 if (b_counter > 0) {
1019 ctx->next_prev = pic;
1021 ++
ctx->next_prev->ref_count[0];
1033 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
1039 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
1046 for (pic =
ctx->pic_start; pic; pic = next) {
1053 ctx->pic_start = next;
1071 "frames ignored due to lack of API support.\n");
1072 ctx->crop_warned = 1;
1075 if (!
ctx->roi_allowed) {
1079 if (sd && !
ctx->roi_warned) {
1081 "frames ignored due to lack of driver support.\n");
1082 ctx->roi_warned = 1;
1121 if (
ctx->input_order == 0)
1122 ctx->first_pts = pic->
pts;
1123 if (
ctx->input_order ==
ctx->decode_delay)
1124 ctx->dts_pts_diff = pic->
pts -
ctx->first_pts;
1125 if (
ctx->output_delay > 0)
1126 ctx->ts_ring[
ctx->input_order % (3 *
ctx->output_delay)] = pic->
pts;
1131 if (
ctx->pic_start) {
1132 ctx->pic_end->next = pic;
1135 ctx->pic_start = pic;
1140 ctx->end_of_stream = 1;
1144 if (
ctx->input_order <
ctx->decode_delay)
1145 ctx->dts_pts_diff =
ctx->pic_end->pts -
ctx->first_pts;
1173 if (!
ctx->pic_start) {
1174 if (
ctx->end_of_stream)
1200 if (
ctx->output_delay == 0) {
1209 (3 *
ctx->output_delay)];
1228 ctx->global_params_type[
ctx->nb_global_params] =
type;
1230 ctx->global_params_size[
ctx->nb_global_params] =
size;
1232 ++
ctx->nb_global_params;
1245 {
"YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
1246 {
"YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
1247 {
"YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
1248 #if VA_CHECK_VERSION(1, 2, 0)
1249 {
"YUV422_10", VA_RT_FORMAT_YUV422_10, 10, 3, 1, 0 },
1251 {
"YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1252 {
"YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
1253 #if VA_CHECK_VERSION(0, 38, 1)
1254 {
"YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
1259 VAEntrypointEncSlice,
1260 VAEntrypointEncPicture,
1261 #if VA_CHECK_VERSION(0, 39, 2)
1262 VAEntrypointEncSliceLP,
1266 #if VA_CHECK_VERSION(0, 39, 2)
1267 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
1268 VAEntrypointEncSliceLP,
1276 VAProfile *va_profiles =
NULL;
1277 VAEntrypoint *va_entrypoints =
NULL;
1279 const VAEntrypoint *usable_entrypoints;
1282 VAConfigAttrib rt_format_attr;
1284 const char *profile_string, *entrypoint_string;
1285 int i, j, n, depth, err;
1288 if (
ctx->low_power) {
1289 #if VA_CHECK_VERSION(0, 39, 2)
1290 usable_entrypoints = vaapi_encode_entrypoints_low_power;
1293 "supported with this VAAPI version.\n");
1303 ctx->input_frames->sw_format);
1306 depth =
desc->comp[0].depth;
1307 for (
i = 1;
i <
desc->nb_components;
i++) {
1308 if (
desc->comp[
i].depth != depth) {
1317 n = vaMaxNumProfiles(
ctx->hwctx->display);
1323 vas = vaQueryConfigProfiles(
ctx->hwctx->display, va_profiles, &n);
1324 if (vas != VA_STATUS_SUCCESS) {
1326 vas, vaErrorStr(vas));
1332 for (
i = 0; (
ctx->codec->profiles[
i].av_profile !=
1335 if (depth !=
profile->depth ||
1338 if (
desc->nb_components > 1 &&
1346 #if VA_CHECK_VERSION(1, 0, 0)
1347 profile_string = vaProfileStr(
profile->va_profile);
1349 profile_string =
"(no profile names)";
1352 for (j = 0; j < n; j++) {
1353 if (va_profiles[j] ==
profile->va_profile)
1358 "is not supported by driver.\n", profile_string,
1366 if (!
ctx->profile) {
1375 profile_string,
ctx->va_profile);
1377 n = vaMaxNumEntrypoints(
ctx->hwctx->display);
1379 if (!va_entrypoints) {
1383 vas = vaQueryConfigEntrypoints(
ctx->hwctx->display,
ctx->va_profile,
1384 va_entrypoints, &n);
1385 if (vas != VA_STATUS_SUCCESS) {
1387 "profile %s (%d): %d (%s).\n", profile_string,
1388 ctx->va_profile, vas, vaErrorStr(vas));
1393 for (
i = 0;
i < n;
i++) {
1394 for (j = 0; usable_entrypoints[j]; j++) {
1395 if (va_entrypoints[
i] == usable_entrypoints[j])
1398 if (usable_entrypoints[j])
1403 "for profile %s (%d).\n", profile_string,
ctx->va_profile);
1408 ctx->va_entrypoint = va_entrypoints[
i];
1409 #if VA_CHECK_VERSION(1, 0, 0)
1410 entrypoint_string = vaEntrypointStr(
ctx->va_entrypoint);
1412 entrypoint_string =
"(no entrypoint names)";
1415 entrypoint_string,
ctx->va_entrypoint);
1419 if (rt_format->
depth == depth &&
1427 "found for profile %s (%d) entrypoint %s (%d).\n",
1428 profile_string,
ctx->va_profile,
1429 entrypoint_string,
ctx->va_entrypoint);
1434 rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1435 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1436 ctx->va_profile,
ctx->va_entrypoint,
1437 &rt_format_attr, 1);
1438 if (vas != VA_STATUS_SUCCESS) {
1440 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1445 if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1447 "supported by driver: assuming surface RT format %s "
1448 "is valid.\n", rt_format->
name);
1449 }
else if (!(rt_format_attr.value & rt_format->
value)) {
1451 "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1452 rt_format->
name, profile_string,
ctx->va_profile,
1453 entrypoint_string,
ctx->va_entrypoint);
1458 "format %s (%#x).\n", rt_format->
name, rt_format->
value);
1459 ctx->config_attributes[
ctx->nb_config_attributes++] =
1461 .type = VAConfigAttribRTFormat,
1462 .value = rt_format->
value,
1480 #if VA_CHECK_VERSION(1, 1, 0)
1485 #if VA_CHECK_VERSION(1, 3, 0)
1497 uint32_t supported_va_rc_modes;
1500 int rc_target_percentage;
1504 int64_t hrd_initial_buffer_fullness;
1506 VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1508 char supported_rc_modes_string[64];
1510 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1511 ctx->va_profile,
ctx->va_entrypoint,
1513 if (vas != VA_STATUS_SUCCESS) {
1515 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1518 if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1520 "supported rate control modes: assuming CQP only.\n");
1521 supported_va_rc_modes = VA_RC_CQP;
1522 strcpy(supported_rc_modes_string,
"unknown");
1524 char *
str = supported_rc_modes_string;
1525 size_t len =
sizeof(supported_rc_modes_string);
1526 int i, first = 1, res;
1528 supported_va_rc_modes = rc_attr.value;
1531 if (supported_va_rc_modes &
rc_mode->va_mode) {
1533 first ?
"" :
", ",
rc_mode->name);
1547 supported_rc_modes_string);
1562 #define TRY_RC_MODE(mode, fail) do { \
1563 rc_mode = &vaapi_encode_rc_modes[mode]; \
1564 if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1566 av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1567 "RC mode (supported modes: %s).\n", rc_mode->name, \
1568 supported_rc_modes_string); \
1569 return AVERROR(EINVAL); \
1571 av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1572 "RC mode.\n", rc_mode->name); \
1575 goto rc_mode_found; \
1579 if (
ctx->explicit_rc_mode)
1582 if (
ctx->explicit_qp)
1612 "RC mode compatible with selected options "
1613 "(supported modes: %s).\n", supported_rc_modes_string);
1630 rc_bits_per_second = avctx->
bit_rate;
1636 rc_target_percentage = 100;
1643 }
else if (
rc_mode->maxrate) {
1647 "bitrate (%"PRId64
") must not be greater than "
1648 "maxrate (%"PRId64
").\n", avctx->
bit_rate,
1653 rc_target_percentage = (avctx->
bit_rate * 100) /
1660 rc_bits_per_second = 2 * avctx->
bit_rate;
1661 rc_target_percentage = 50;
1666 "in %s RC mode.\n",
rc_mode->name);
1668 rc_bits_per_second = avctx->
bit_rate;
1669 rc_target_percentage = 100;
1672 rc_bits_per_second = 0;
1673 rc_target_percentage = 100;
1677 if (
ctx->explicit_qp) {
1678 rc_quality =
ctx->explicit_qp;
1682 rc_quality =
ctx->codec->default_quality;
1684 "using default (%d).\n", rc_quality);
1700 "must have initial buffer size (%d) <= "
1701 "buffer size (%"PRId64
").\n",
1707 hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1710 rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1714 "in %s RC mode.\n",
rc_mode->name);
1717 hrd_buffer_size = 0;
1718 hrd_initial_buffer_fullness = 0;
1722 rc_window_size = 1000;
1726 if (rc_bits_per_second > UINT32_MAX ||
1727 hrd_buffer_size > UINT32_MAX ||
1728 hrd_initial_buffer_fullness > UINT32_MAX) {
1730 "greater are not supported by VAAPI.\n");
1735 ctx->rc_quality = rc_quality;
1737 ctx->va_bit_rate = rc_bits_per_second;
1740 if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1743 ctx->config_attributes[
ctx->nb_config_attributes++] =
1745 .type = VAConfigAttribRateControl,
1746 .value =
ctx->va_rc_mode,
1753 if (
rc_mode->va_mode != VA_RC_CQP) {
1756 "converging in %d frames with %d%% accuracy.\n",
1757 rc_bits_per_second, rc_window_size,
1758 rc_target_percentage);
1759 }
else if (
rc_mode->bitrate) {
1761 "%"PRId64
" bps over %d ms.\n", rc_target_percentage,
1762 rc_bits_per_second, rc_window_size);
1765 ctx->rc_params = (VAEncMiscParameterRateControl) {
1766 .bits_per_second = rc_bits_per_second,
1767 .target_percentage = rc_target_percentage,
1768 .window_size = rc_window_size,
1770 .min_qp = (avctx->
qmin > 0 ? avctx->
qmin : 0),
1771 .basic_unit_size = 0,
1772 #
if VA_CHECK_VERSION(1, 1, 0)
1773 .ICQ_quality_factor =
av_clip(rc_quality, 1, 51),
1774 .max_qp = (avctx->
qmax > 0 ? avctx->
qmax : 0),
1776 #
if VA_CHECK_VERSION(1, 3, 0)
1777 .quality_factor = rc_quality,
1781 VAEncMiscParameterTypeRateControl,
1783 sizeof(
ctx->rc_params));
1788 "initial fullness %"PRId64
" bits.\n",
1789 hrd_buffer_size, hrd_initial_buffer_fullness);
1791 ctx->hrd_params = (VAEncMiscParameterHRD) {
1792 .initial_buffer_fullness = hrd_initial_buffer_fullness,
1793 .buffer_size = hrd_buffer_size,
1796 VAEncMiscParameterTypeHRD,
1798 sizeof(
ctx->hrd_params));
1809 fr_num, fr_den, (
double)fr_num / fr_den);
1811 ctx->fr_params = (VAEncMiscParameterFrameRate) {
1812 .framerate = (
unsigned int)fr_den << 16 | fr_num,
1814 #if VA_CHECK_VERSION(0, 40, 0)
1816 VAEncMiscParameterTypeFrameRate,
1818 sizeof(
ctx->fr_params));
1828 VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1829 uint32_t ref_l0, ref_l1;
1831 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1835 if (vas != VA_STATUS_SUCCESS) {
1837 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1841 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1842 ref_l0 = ref_l1 = 0;
1844 ref_l0 = attr.value & 0xffff;
1845 ref_l1 = attr.value >> 16 & 0xffff;
1852 }
else if (ref_l0 < 1) {
1854 "reference frames.\n");
1857 ref_l1 < 1 || avctx->max_b_frames < 1) {
1859 "(supported references: %d / %d).\n", ref_l0, ref_l1);
1861 ctx->p_per_i = INT_MAX;
1865 "(supported references: %d / %d).\n", ref_l0, ref_l1);
1867 ctx->p_per_i = INT_MAX;
1873 ctx->max_b_depth = 1;
1879 ctx->gop_per_idr =
ctx->idr_interval + 1;
1881 ctx->closed_gop = 1;
1882 ctx->gop_per_idr = 1;
1889 uint32_t slice_structure)
1899 if (avctx->
slices >
ctx->slice_block_rows) {
1901 "configured number of slices (%d < %d); using "
1902 "maximum.\n",
ctx->slice_block_rows, avctx->
slices);
1903 req_slices =
ctx->slice_block_rows;
1905 req_slices = avctx->
slices;
1907 if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1908 slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1909 ctx->nb_slices = req_slices;
1910 ctx->slice_size =
ctx->slice_block_rows /
ctx->nb_slices;
1911 }
else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1913 for (k = 1;; k *= 2) {
1914 if (2 * k * (req_slices - 1) + 1 >=
ctx->slice_block_rows)
1917 ctx->nb_slices = (
ctx->slice_block_rows + k - 1) / k;
1918 ctx->slice_size = k;
1919 #if VA_CHECK_VERSION(1, 0, 0)
1920 }
else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1921 ctx->nb_slices =
ctx->slice_block_rows;
1922 ctx->slice_size = 1;
1926 "slice structure modes (%#x).\n", slice_structure);
1934 uint32_t slice_structure)
1939 if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
1940 (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
1941 ctx->tile_cols == 1))) {
1943 "current tile requirement.\n", slice_structure);
1947 if (
ctx->tile_rows >
ctx->slice_block_rows ||
1948 ctx->tile_cols >
ctx->slice_block_cols) {
1950 "for configured number of tile (%d x %d); ",
1951 ctx->slice_block_rows,
ctx->slice_block_cols,
1952 ctx->tile_rows,
ctx->tile_cols);
1953 ctx->tile_rows =
ctx->tile_rows >
ctx->slice_block_rows ?
1954 ctx->slice_block_rows :
ctx->tile_rows;
1955 ctx->tile_cols =
ctx->tile_cols >
ctx->slice_block_cols ?
1956 ctx->slice_block_cols :
ctx->tile_cols;
1958 ctx->tile_rows,
ctx->tile_cols);
1961 req_tiles =
ctx->tile_rows *
ctx->tile_cols;
1966 if (avctx->
slices != req_tiles)
1968 "mismatches with configured number of tile (%d != %d); "
1969 "using requested tile number for slice.\n",
1970 avctx->
slices, req_tiles);
1972 ctx->nb_slices = req_tiles;
1976 for (
i = 0;
i <
ctx->tile_cols;
i++) {
1977 ctx->col_width[
i] = (
i + 1 ) *
ctx->slice_block_cols /
ctx->tile_cols -
1978 i *
ctx->slice_block_cols /
ctx->tile_cols;
1979 ctx->col_bd[
i + 1] =
ctx->col_bd[
i] +
ctx->col_width[
i];
1982 for (
i = 0;
i <
ctx->tile_rows;
i++) {
1983 ctx->row_height[
i] = (
i + 1 ) *
ctx->slice_block_rows /
ctx->tile_rows -
1984 i *
ctx->slice_block_rows /
ctx->tile_rows;
1985 ctx->row_bd[
i + 1] =
ctx->row_bd[
i] +
ctx->row_height[
i];
1989 ctx->tile_rows,
ctx->tile_cols);
1997 VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
1998 { VAConfigAttribEncSliceStructure },
1999 #if VA_CHECK_VERSION(1, 1, 0)
2000 { VAConfigAttribEncTileSupport },
2004 uint32_t max_slices, slice_structure;
2010 "but this codec does not support controlling slices.\n");
2015 ctx->slice_block_rows = (avctx->
height +
ctx->slice_block_height - 1) /
2016 ctx->slice_block_height;
2017 ctx->slice_block_cols = (avctx->
width +
ctx->slice_block_width - 1) /
2018 ctx->slice_block_width;
2020 if (avctx->
slices <= 1 && !
ctx->tile_rows && !
ctx->tile_cols) {
2022 ctx->slice_size =
ctx->slice_block_rows;
2026 vas = vaGetConfigAttributes(
ctx->hwctx->display,
2030 if (vas != VA_STATUS_SUCCESS) {
2032 "attributes: %d (%s).\n", vas, vaErrorStr(vas));
2035 max_slices = attr[0].value;
2036 slice_structure = attr[1].value;
2037 if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
2038 slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
2040 "pictures as multiple slices.\n.");
2044 if (
ctx->tile_rows &&
ctx->tile_cols) {
2045 #if VA_CHECK_VERSION(1, 1, 0)
2046 uint32_t tile_support = attr[2].value;
2047 if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
2049 "pictures as multiple tiles.\n.");
2054 "not supported with this VAAPI version.\n");
2059 if (
ctx->tile_rows &&
ctx->tile_cols)
2068 "%d (from %d) due to driver constraints on slice "
2069 "structure.\n",
ctx->nb_slices, avctx->
slices);
2071 if (
ctx->nb_slices > max_slices) {
2073 "encoding with %d slices (max %"PRIu32
").\n",
2074 ctx->nb_slices, max_slices);
2087 VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
2089 vas = vaGetConfigAttributes(
ctx->hwctx->display,
2093 if (vas != VA_STATUS_SUCCESS) {
2095 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
2099 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2100 if (
ctx->desired_packed_headers) {
2102 "packed headers (wanted %#x).\n",
2103 ctx->desired_packed_headers);
2106 "packed headers (none wanted).\n");
2108 ctx->va_packed_headers = 0;
2110 if (
ctx->desired_packed_headers & ~attr.value) {
2112 "wanted packed headers (wanted %#x, found %#x).\n",
2113 ctx->desired_packed_headers, attr.value);
2116 "available (wanted %#x, found %#x).\n",
2117 ctx->desired_packed_headers, attr.value);
2119 ctx->va_packed_headers =
ctx->desired_packed_headers & attr.value;
2122 if (
ctx->va_packed_headers) {
2123 ctx->config_attributes[
ctx->nb_config_attributes++] =
2125 .type = VAConfigAttribEncPackedHeaders,
2126 .value =
ctx->va_packed_headers,
2130 if ( (
ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2131 !(
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
2134 "sequence headers, but a global header is requested.\n");
2136 "this may result in a stream which is not usable for some "
2137 "purposes (e.g. not muxable to some containers).\n");
2145 #if VA_CHECK_VERSION(0, 36, 0)
2148 VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
2151 vas = vaGetConfigAttributes(
ctx->hwctx->display,
2155 if (vas != VA_STATUS_SUCCESS) {
2157 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2161 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2164 "supported: will use default quality level.\n");
2167 if (quality > attr.value) {
2169 "valid range is 0-%d, using %d.\n",
2170 attr.value, attr.value);
2171 quality = attr.value;
2174 ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2175 .quality_level = quality,
2178 VAEncMiscParameterTypeQualityLevel,
2179 &
ctx->quality_params,
2180 sizeof(
ctx->quality_params));
2184 "not supported with this VAAPI version.\n");
2192 #if VA_CHECK_VERSION(1, 0, 0)
2195 VAConfigAttrib attr = { VAConfigAttribEncROI };
2197 vas = vaGetConfigAttributes(
ctx->hwctx->display,
2201 if (vas != VA_STATUS_SUCCESS) {
2203 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2207 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2208 ctx->roi_allowed = 0;
2210 VAConfigAttribValEncROI roi = {
2211 .value = attr.value,
2214 ctx->roi_max_regions = roi.bits.num_roi_regions;
2215 ctx->roi_allowed =
ctx->roi_max_regions > 0 &&
2216 (
ctx->va_rc_mode == VA_RC_CQP ||
2217 roi.bits.roi_rc_qp_delta_support);
2228 VABufferID buffer_id;
2230 buffer_id = (VABufferID)(uintptr_t)
data;
2232 vaDestroyBuffer(
ctx->hwctx->display, buffer_id);
2242 VABufferID buffer_id;
2250 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
2251 VAEncCodedBufferType,
2252 3 *
ctx->surface_width *
ctx->surface_height +
2253 (1 << 16), 1, 0, &buffer_id);
2254 if (vas != VA_STATUS_SUCCESS) {
2256 "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2267 vaDestroyBuffer(
ctx->hwctx->display, buffer_id);
2302 if (
ctx->input_frames->sw_format ==
2304 recon_format =
ctx->input_frames->sw_format;
2315 recon_format =
ctx->input_frames->sw_format;
2325 "size %dx%d (constraints: width %d-%d height %d-%d).\n",
2326 ctx->surface_width,
ctx->surface_height,
2337 if (!
ctx->recon_frames_ref) {
2344 ctx->recon_frames->sw_format = recon_format;
2345 ctx->recon_frames->width =
ctx->surface_width;
2346 ctx->recon_frames->height =
ctx->surface_height;
2351 "frame context: %d.\n", err);
2369 ctx->va_config = VA_INVALID_ID;
2370 ctx->va_context = VA_INVALID_ID;
2381 "required to associate the encoding device.\n");
2386 if (!
ctx->input_frames_ref) {
2393 if (!
ctx->device_ref) {
2398 ctx->hwctx =
ctx->device->hwctx;
2430 vas = vaCreateConfig(
ctx->hwctx->display,
2431 ctx->va_profile,
ctx->va_entrypoint,
2432 ctx->config_attributes,
ctx->nb_config_attributes,
2434 if (vas != VA_STATUS_SUCCESS) {
2436 "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2445 recon_hwctx =
ctx->recon_frames->hwctx;
2446 vas = vaCreateContext(
ctx->hwctx->display,
ctx->va_config,
2447 ctx->surface_width,
ctx->surface_height,
2452 if (vas != VA_STATUS_SUCCESS) {
2454 "context: %d (%s).\n", vas, vaErrorStr(vas));
2459 ctx->output_buffer_pool =
2462 if (!
ctx->output_buffer_pool) {
2467 if (
ctx->codec->configure) {
2468 err =
ctx->codec->configure(avctx);
2473 ctx->output_delay =
ctx->b_per_p;
2474 ctx->decode_delay =
ctx->max_b_depth;
2476 if (
ctx->codec->sequence_params_size > 0) {
2477 ctx->codec_sequence_params =
2479 if (!
ctx->codec_sequence_params) {
2484 if (
ctx->codec->picture_params_size > 0) {
2485 ctx->codec_picture_params =
2487 if (!
ctx->codec_picture_params) {
2493 if (
ctx->codec->init_sequence_params) {
2494 err =
ctx->codec->init_sequence_params(avctx);
2497 "failed: %d.\n", err);
2502 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2503 ctx->codec->write_sequence_header &&
2506 size_t bit_len = 8 *
sizeof(
data);
2508 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
2511 "for extradata: %d.\n", err);
2541 for (pic =
ctx->pic_start; pic; pic = next) {
2548 if (
ctx->va_context != VA_INVALID_ID) {
2550 vaDestroyContext(
ctx->hwctx->display,
ctx->va_context);
2551 ctx->va_context = VA_INVALID_ID;
2554 if (
ctx->va_config != VA_INVALID_ID) {
2556 vaDestroyConfig(
ctx->hwctx->display,
ctx->va_config);
2557 ctx->va_config = VA_INVALID_ID;
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Libavcodec external API header.
#define FF_PROFILE_UNKNOWN
common internal and external API header
int ff_get_encode_buffer(AVCodecContext *avctx, AVPacket *avpkt, int64_t size, int flags)
Get a buffer for a packet.
int ff_encode_get_frame(AVCodecContext *avctx, AVFrame *frame)
Called by encoders to get the next frame for encoding.
#define AV_CODEC_FLAG_CLOSED_GOP
#define AV_CODEC_FLAG_QSCALE
Use fixed qscale.
#define AV_CODEC_FLAG_GLOBAL_HEADER
Place global headers in extradata instead of every keyframe.
#define AV_INPUT_BUFFER_PADDING_SIZE
Required number of additionally allocated bytes at the end of the input bitstream for decoding.
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
void av_buffer_unref(AVBufferRef **buf)
Free a given reference and automatically free the buffer if there are no more references to it.
AVBufferRef * av_buffer_create(uint8_t *data, buffer_size_t size, void(*free)(void *opaque, uint8_t *data), void *opaque, int flags)
Create an AVBuffer from an existing array.
AVBufferRef * av_buffer_ref(AVBufferRef *buf)
Create a new reference to an AVBuffer.
#define AV_BUFFER_FLAG_READONLY
Always treat the buffer as read-only, even when it has only one reference.
AVBufferRef * av_buffer_pool_get(AVBufferPool *pool)
Allocate a new AVBuffer, reusing an old buffer from the pool when available.
AVBufferPool * av_buffer_pool_init2(buffer_size_t size, void *opaque, AVBufferRef *(*alloc)(void *opaque, buffer_size_t size), void(*pool_free)(void *opaque))
Allocate and initialize a buffer pool with a more complex allocator.
void av_buffer_pool_uninit(AVBufferPool **ppool)
Mark the pool as being available for freeing.
#define AVERROR_EXTERNAL
Generic error in an external library.
#define AVERROR_EOF
End of file.
void av_frame_move_ref(AVFrame *dst, AVFrame *src)
Move everything contained in src to dst and reset src.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
AVFrameSideData * av_frame_get_side_data(const AVFrame *frame, enum AVFrameSideDataType type)
@ AV_FRAME_DATA_REGIONS_OF_INTEREST
Regions Of Interest, the data is an array of AVRegionOfInterest type, the number of array element is ...
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
#define AV_LOG_WARNING
Something somehow does not look correct.
#define AV_LOG_VERBOSE
Detailed information.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int av_reduce(int *dst_num, int *dst_den, int64_t num, int64_t den, int64_t max)
Reduce a fraction.
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
void * av_realloc_array(void *ptr, size_t nmemb, size_t size)
Allocate, reallocate, or free an array.
void * av_mallocz_array(size_t nmemb, size_t size)
Allocate a memory block for an array with av_mallocz().
@ AV_PICTURE_TYPE_I
Intra.
#define HW_CONFIG_ENCODER_FRAMES(format, device_type_)
void av_hwframe_constraints_free(AVHWFramesConstraints **constraints)
Free an AVHWFrameConstraints structure.
int av_hwframe_ctx_init(AVBufferRef *ref)
Finalize the context before use.
AVHWFramesConstraints * av_hwdevice_get_hwframe_constraints(AVBufferRef *ref, const void *hwconfig)
Get the constraints on HW frames given a device and the HW-specific configuration to be used with tha...
void * av_hwdevice_hwconfig_alloc(AVBufferRef *ref)
Allocate a HW-specific configuration structure for a given HW device.
AVBufferRef * av_hwframe_ctx_alloc(AVBufferRef *device_ref_in)
Allocate an AVHWFramesContext tied to a given device context.
int av_hwframe_get_buffer(AVBufferRef *hwframe_ref, AVFrame *frame, int flags)
Allocate a new frame attached to the given AVHWFramesContext.
@ AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS
The driver does not destroy parameter buffers when they are used by vaRenderPicture().
static int vaapi_encode_wait(AVCodecContext *avctx, VAAPIEncodePicture *pic)
static av_cold int vaapi_encode_create_recon_frames(AVCodecContext *avctx)
#define TRY_RC_MODE(mode, fail)
static void vaapi_encode_add_ref(AVCodecContext *avctx, VAAPIEncodePicture *pic, VAAPIEncodePicture *target, int is_ref, int in_dpb, int prev)
static av_cold int vaapi_encode_init_rate_control(AVCodecContext *avctx)
static int vaapi_encode_make_packed_header(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t bit_len)
const AVCodecHWConfigInternal *const ff_vaapi_encode_hw_configs[]
static int vaapi_encode_send_frame(AVCodecContext *avctx, AVFrame *frame)
static int vaapi_encode_free(AVCodecContext *avctx, VAAPIEncodePicture *pic)
static av_cold int vaapi_encode_init_row_slice_structure(AVCodecContext *avctx, uint32_t slice_structure)
static av_cold int vaapi_encode_profile_entrypoint(AVCodecContext *avctx)
static av_cold void vaapi_encode_add_global_param(AVCodecContext *avctx, int type, void *buffer, size_t size)
static av_cold int vaapi_encode_init_quality(AVCodecContext *avctx)
static void vaapi_encode_remove_refs(AVCodecContext *avctx, VAAPIEncodePicture *pic, int level)
static void vaapi_encode_set_b_pictures(AVCodecContext *avctx, VAAPIEncodePicture *start, VAAPIEncodePicture *end, VAAPIEncodePicture *prev, int current_depth, VAAPIEncodePicture **last)
static int vaapi_encode_make_row_slice(AVCodecContext *avctx, VAAPIEncodePicture *pic)
static av_cold int vaapi_encode_init_tile_slice_structure(AVCodecContext *avctx, uint32_t slice_structure)
static int vaapi_encode_make_misc_param_buffer(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, const void *data, size_t len)
static AVBufferRef * vaapi_encode_alloc_output_buffer(void *opaque, buffer_size_t size)
static av_cold int vaapi_encode_init_roi(AVCodecContext *avctx)
static VAAPIEncodePicture * vaapi_encode_alloc(AVCodecContext *avctx)
int ff_vaapi_encode_receive_packet(AVCodecContext *avctx, AVPacket *pkt)
static void vaapi_encode_free_output_buffer(void *opaque, uint8_t *data)
static int vaapi_encode_pick_next(AVCodecContext *avctx, VAAPIEncodePicture **pic_out)
static int vaapi_encode_issue(AVCodecContext *avctx, VAAPIEncodePicture *pic)
static av_cold int vaapi_encode_init_slice_structure(AVCodecContext *avctx)
static int vaapi_encode_clear_old(AVCodecContext *avctx)
av_cold int ff_vaapi_encode_init(AVCodecContext *avctx)
static const VAAPIEncodeRTFormat vaapi_encode_rt_formats[]
static int vaapi_encode_make_param_buffer(AVCodecContext *avctx, VAAPIEncodePicture *pic, int type, char *data, size_t len)
static int vaapi_encode_check_frame(AVCodecContext *avctx, const AVFrame *frame)
av_cold int ff_vaapi_encode_close(AVCodecContext *avctx)
static const char *const picture_type_name[]
static const VAEntrypoint vaapi_encode_entrypoints_normal[]
static const VAAPIEncodeRCMode vaapi_encode_rc_modes[]
static int vaapi_encode_discard(AVCodecContext *avctx, VAAPIEncodePicture *pic)
static av_cold int vaapi_encode_init_gop_structure(AVCodecContext *avctx)
static int vaapi_encode_make_tile_slice(AVCodecContext *avctx, VAAPIEncodePicture *pic)
static int vaapi_encode_output(AVCodecContext *avctx, VAAPIEncodePicture *pic, AVPacket *pkt)
static av_cold int vaapi_encode_init_packed_headers(AVCodecContext *avctx)
common internal API header
const char * av_get_pix_fmt_name(enum AVPixelFormat pix_fmt)
Return the short name for a pixel format, NULL in case pix_fmt is unknown.
const AVPixFmtDescriptor * av_pix_fmt_desc_get(enum AVPixelFormat pix_fmt)
AVPixelFormat
Pixel format.
static const uint8_t header[24]
#define FF_ARRAY_ELEMS(a)
A reference to a data buffer.
uint8_t * data
The data buffer.
main external API structure.
int width
picture width / height.
int rc_buffer_size
decoder bitstream buffer size
int global_quality
Global quality for codecs which cannot change it per frame.
AVBufferRef * hw_frames_ctx
A reference to the AVHWFramesContext describing the input (for encoding) or output (decoding) frames.
int max_b_frames
maximum number of B-frames between non-B-frames Note: The output will be delayed by max_b_frames+1 re...
int qmin
minimum quantizer
int64_t bit_rate
the average bitrate
int rc_initial_buffer_occupancy
Number of bits which should be loaded into the rc buffer before decoding starts.
int gop_size
the number of pictures in a group of pictures, or 0 for intra_only
int64_t rc_max_rate
maximum bitrate
int qmax
maximum quantizer
AVRational time_base
This is the fundamental unit of time (in seconds) in terms of which frame timestamps are represented.
int flags
AV_CODEC_FLAG_*.
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
int slices
Number of slices.
int flags
Flags modifying the (de)muxer behaviour.
Structure to hold side data for an AVFrame.
This structure describes decoded (raw) audio or video data.
int64_t pts
Presentation timestamp in time_base units (time when frame should be shown to user).
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
enum AVPictureType pict_type
Picture type of the frame.
This struct aggregates all the (hardware/vendor-specific) "high-level" state, i.e.
This struct describes the constraints on hardware frames attached to a given device with a hardware-s...
int max_width
The maximum size of frames in this hw_frames_ctx.
enum AVPixelFormat * valid_sw_formats
A list of possible values for sw_format in the hw_frames_ctx, terminated by AV_PIX_FMT_NONE.
int min_width
The minimum size of frames in this hw_frames_ctx.
This struct describes a set or pool of "hardware" frames (i.e.
This structure stores compressed data.
int flags
A combination of AV_PKT_FLAG values.
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
int64_t dts
Decompression timestamp in AVStream->time_base units; the time at which the packet is decompressed.
Descriptor that unambiguously describes how the bits of a pixel are stored in the up to 4 data planes...
Structure describing a single Region Of Interest.
uint32_t self_size
Must be set to the size of this data structure (that is, sizeof(AVRegionOfInterest)).
AVRational qoffset
Quantisation offset.
int top
Distance in pixels from the top edge of the frame to the top and bottom edges and from the left edge ...
VAAPI-specific data associated with a frame pool.
VASurfaceID * surface_ids
The surfaces IDs of all surfaces in the pool after creation.
VAAPI hardware pipeline configuration details.
VAConfigID config_id
ID of a VAAPI pipeline configuration.
AVBufferRef * output_buffer_ref
void * codec_picture_params
struct VAAPIEncodePicture * refs[MAX_PICTURE_REFERENCES]
VASurfaceID recon_surface
struct VAAPIEncodePicture * dpb[MAX_DPB_SIZE]
struct VAAPIEncodePicture * prev
struct VAAPIEncodePicture * next
VAAPIEncodeSlice * slices
VASurfaceID input_surface
VABufferID * param_buffers
void * codec_slice_params
#define av_malloc_array(a, b)
static int ref[MAX_W *MAX_W]
@ FLAG_CONSTANT_QUALITY_ONLY
@ FLAG_NON_IDR_KEY_PICTURES
@ FLAG_B_PICTURE_REFERENCES