43 int type,
char *
data,
size_t bit_len)
47 VABufferID param_buffer, data_buffer;
49 VAEncPackedHeaderParameterBuffer params = {
51 .bit_length = bit_len,
52 .has_emulation_bytes = 1,
60 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
61 VAEncPackedHeaderParameterBufferType,
62 sizeof(params), 1, ¶ms, ¶m_buffer);
63 if (vas != VA_STATUS_SUCCESS) {
65 "for packed header (type %d): %d (%s).\n",
66 type, vas, vaErrorStr(vas));
71 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
72 VAEncPackedHeaderDataBufferType,
73 (bit_len + 7) / 8, 1,
data, &data_buffer);
74 if (vas != VA_STATUS_SUCCESS) {
76 "for packed header (type %d): %d (%s).\n",
77 type, vas, vaErrorStr(vas));
83 "(%zu bits).\n",
type, param_buffer, data_buffer, bit_len);
101 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
103 if (vas != VA_STATUS_SUCCESS) {
105 "(type %d): %d (%s).\n",
type, vas, vaErrorStr(vas));
124 VAEncMiscParameterBuffer
header = {
127 size_t buffer_size =
sizeof(
header) +
len;
134 VAEncMiscParameterBufferType,
140 #if VA_CHECK_VERSION(1, 9, 0)
158 #if VA_CHECK_VERSION(1, 9, 0)
160 vas = vaSyncBuffer(
ctx->hwctx->display,
162 VA_TIMEOUT_INFINITE);
163 if (vas != VA_STATUS_SUCCESS) {
165 "%d (%s).\n", vas, vaErrorStr(vas));
172 if (vas != VA_STATUS_SUCCESS) {
174 "%d (%s).\n", vas, vaErrorStr(vas));
196 rounding =
ctx->slice_block_rows -
ctx->nb_slices *
ctx->slice_size;
204 for (
i = 0;
i < rounding;
i++)
207 for (
i = 0;
i < (rounding + 1) / 2;
i++)
209 for (
i = 0;
i < rounding / 2;
i++)
212 }
else if (rounding < 0) {
248 for (
i = 0;
i <
ctx->tile_cols;
i++) {
249 for (j = 0; j <
ctx->tile_rows; j++) {
255 ctx->row_bd[j] *
ctx->slice_block_cols;
259 "width:%2d height:%2d (%d blocks).\n",
index,
ctx->col_bd[
i],
328 if (
ctx->codec->picture_params_size > 0) {
333 ctx->codec->picture_params_size);
342 VAEncSequenceParameterBufferType,
343 ctx->codec_sequence_params,
344 ctx->codec->sequence_params_size);
350 for (
i = 0;
i <
ctx->nb_global_params;
i++) {
352 ctx->global_params_type[
i],
353 ctx->global_params[
i],
354 ctx->global_params_size[
i]);
360 if (
ctx->codec->init_picture_params) {
361 err =
ctx->codec->init_picture_params(avctx, base_pic);
364 "parameters: %d.\n", err);
368 VAEncPictureParameterBufferType,
370 ctx->codec->picture_params_size);
375 #if VA_CHECK_VERSION(1, 5, 0)
376 if (
ctx->max_frame_size) {
378 VAEncMiscParameterTypeMaxFrameSize,
380 sizeof(
ctx->mfs_params));
387 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
388 ctx->codec->write_sequence_header) {
389 bit_len = 8 *
sizeof(
data);
390 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
393 "header: %d.\n", err);
397 ctx->codec->sequence_header_type,
404 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE &&
405 ctx->codec->write_picture_header) {
406 bit_len = 8 *
sizeof(
data);
407 err =
ctx->codec->write_picture_header(avctx, base_pic,
data, &bit_len);
410 "header: %d.\n", err);
414 ctx->codec->picture_header_type,
420 if (
ctx->codec->write_extra_buffer) {
424 err =
ctx->codec->write_extra_buffer(avctx, base_pic,
i, &
type,
430 "buffer %d: %d.\n",
i, err);
441 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC &&
442 ctx->codec->write_extra_header) {
445 bit_len = 8 *
sizeof(
data);
446 err =
ctx->codec->write_extra_header(avctx, base_pic,
i, &
type,
452 "header %d: %d.\n",
i, err);
472 if (
ctx->tile_rows &&
ctx->tile_cols)
481 if (
ctx->codec->slice_params_size > 0) {
489 if (
ctx->codec->init_slice_params) {
490 err =
ctx->codec->init_slice_params(avctx, base_pic, slice);
493 "parameters: %d.\n", err);
498 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE &&
499 ctx->codec->write_slice_header) {
500 bit_len = 8 *
sizeof(
data);
501 err =
ctx->codec->write_slice_header(avctx, pic, slice,
505 "header: %d.\n", err);
509 ctx->codec->slice_header_type,
515 if (
ctx->codec->init_slice_params) {
517 VAEncSliceParameterBufferType,
519 ctx->codec->slice_params_size);
525 #if VA_CHECK_VERSION(1, 0, 0)
531 VAEncMiscParameterBufferROI param_roi;
536 av_assert0(roi_size && sd->size % roi_size == 0);
537 nb_roi = sd->size / roi_size;
538 if (nb_roi >
ctx->roi_max_regions) {
541 "supported by driver (%d > %d).\n",
542 nb_roi,
ctx->roi_max_regions);
545 nb_roi =
ctx->roi_max_regions;
554 for (
i = 0;
i < nb_roi;
i++) {
562 pic->
roi[
i] = (VAEncROI) {
573 param_roi = (VAEncMiscParameterBufferROI) {
575 .max_delta_qp = INT8_MAX,
576 .min_delta_qp = INT8_MIN,
578 .roi_flags.bits.roi_value_is_qp_delta = 1,
582 VAEncMiscParameterTypeROI,
590 vas = vaBeginPicture(
ctx->hwctx->display,
ctx->va_context,
592 if (vas != VA_STATUS_SUCCESS) {
594 "%d (%s).\n", vas, vaErrorStr(vas));
596 goto fail_with_picture;
599 vas = vaRenderPicture(
ctx->hwctx->display,
ctx->va_context,
601 if (vas != VA_STATUS_SUCCESS) {
603 "%d (%s).\n", vas, vaErrorStr(vas));
605 goto fail_with_picture;
608 vas = vaEndPicture(
ctx->hwctx->display,
ctx->va_context);
609 if (vas != VA_STATUS_SUCCESS) {
611 "%d (%s).\n", vas, vaErrorStr(vas));
615 if (CONFIG_VAAPI_1 ||
ctx->hwctx->driver_quirks &
622 if (CONFIG_VAAPI_1 ||
ctx->hwctx->driver_quirks &
625 vas = vaDestroyBuffer(
ctx->hwctx->display,
627 if (vas != VA_STATUS_SUCCESS) {
629 "param buffer %#x: %d (%s).\n",
639 vaEndPicture(
ctx->hwctx->display,
ctx->va_context);
660 VACodedBufferSegment *buf_list, *buf;
665 vas = vaMapBuffer(
ctx->hwctx->display, buf_id,
667 if (vas != VA_STATUS_SUCCESS) {
669 "%d (%s).\n", vas, vaErrorStr(vas));
674 for (buf = buf_list; buf; buf = buf->next)
677 vas = vaUnmapBuffer(
ctx->hwctx->display, buf_id);
678 if (vas != VA_STATUS_SUCCESS) {
680 "%d (%s).\n", vas, vaErrorStr(vas));
689 VABufferID buf_id, uint8_t **
dst)
692 VACodedBufferSegment *buf_list, *buf;
696 vas = vaMapBuffer(
ctx->hwctx->display, buf_id,
698 if (vas != VA_STATUS_SUCCESS) {
700 "%d (%s).\n", vas, vaErrorStr(vas));
705 for (buf = buf_list; buf; buf = buf->next) {
707 "(status %08x).\n", buf->size, buf->status);
709 memcpy(*
dst, buf->buf, buf->size);
713 vas = vaUnmapBuffer(
ctx->hwctx->display, buf_id);
714 if (vas != VA_STATUS_SUCCESS) {
716 "%d (%s).\n", vas, vaErrorStr(vas));
728 VABufferID output_buffer_prev;
733 if (
ctx->coded_buffer_ref) {
734 output_buffer_prev = *
ctx->coded_buffer_ref;
751 if (
ctx->coded_buffer_ref) {
825 "%"PRId64
"/%"PRId64
".\n",
841 if (
ctx->codec->picture_priv_data_size > 0) {
885 ctx->global_params_type[
ctx->nb_global_params] =
type;
887 ctx->global_params_size[
ctx->nb_global_params] =
size;
889 ++
ctx->nb_global_params;
902 {
"YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
903 {
"YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
904 {
"YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
905 #if VA_CHECK_VERSION(1, 2, 0)
906 {
"YUV420_12", VA_RT_FORMAT_YUV420_12, 12, 3, 1, 1 },
907 {
"YUV422_10", VA_RT_FORMAT_YUV422_10, 10, 3, 1, 0 },
908 {
"YUV422_12", VA_RT_FORMAT_YUV422_12, 12, 3, 1, 0 },
909 {
"YUV444_10", VA_RT_FORMAT_YUV444_10, 10, 3, 0, 0 },
910 {
"YUV444_12", VA_RT_FORMAT_YUV444_12, 12, 3, 0, 0 },
912 {
"YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
913 {
"XYUV", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
914 {
"YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
915 #if VA_CHECK_VERSION(0, 38, 1)
916 {
"YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
921 VAEntrypointEncSlice,
922 VAEntrypointEncPicture,
923 #if VA_CHECK_VERSION(0, 39, 2)
924 VAEntrypointEncSliceLP,
928 #if VA_CHECK_VERSION(0, 39, 2)
929 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
930 VAEntrypointEncSliceLP,
939 VAProfile *va_profiles =
NULL;
940 VAEntrypoint *va_entrypoints =
NULL;
942 const VAEntrypoint *usable_entrypoints;
945 VAConfigAttrib rt_format_attr;
947 const char *profile_string, *entrypoint_string;
948 int i, j, n, depth, err;
951 if (
ctx->low_power) {
952 #if VA_CHECK_VERSION(0, 39, 2)
953 usable_entrypoints = vaapi_encode_entrypoints_low_power;
956 "supported with this VAAPI version.\n");
969 depth =
desc->comp[0].depth;
970 for (
i = 1;
i <
desc->nb_components;
i++) {
971 if (
desc->comp[
i].depth != depth) {
980 n = vaMaxNumProfiles(
ctx->hwctx->display);
986 vas = vaQueryConfigProfiles(
ctx->hwctx->display, va_profiles, &n);
987 if (vas != VA_STATUS_SUCCESS) {
989 vas, vaErrorStr(vas));
995 for (
i = 0; (
ctx->codec->profiles[
i].av_profile !=
1001 if (
desc->nb_components > 1 &&
1009 #if VA_CHECK_VERSION(1, 0, 0)
1010 profile_string = vaProfileStr(
profile->va_profile);
1012 profile_string =
"(no profile names)";
1015 for (j = 0; j < n; j++) {
1016 if (va_profiles[j] ==
profile->va_profile)
1021 "is not supported by driver.\n", profile_string,
1029 if (!
ctx->profile) {
1038 profile_string,
ctx->va_profile);
1040 n = vaMaxNumEntrypoints(
ctx->hwctx->display);
1042 if (!va_entrypoints) {
1046 vas = vaQueryConfigEntrypoints(
ctx->hwctx->display,
ctx->va_profile,
1047 va_entrypoints, &n);
1048 if (vas != VA_STATUS_SUCCESS) {
1050 "profile %s (%d): %d (%s).\n", profile_string,
1051 ctx->va_profile, vas, vaErrorStr(vas));
1056 for (
i = 0;
i < n;
i++) {
1057 for (j = 0; usable_entrypoints[j]; j++) {
1058 if (va_entrypoints[
i] == usable_entrypoints[j])
1061 if (usable_entrypoints[j])
1066 "for profile %s (%d).\n", profile_string,
ctx->va_profile);
1071 ctx->va_entrypoint = va_entrypoints[
i];
1072 #if VA_CHECK_VERSION(1, 0, 0)
1073 entrypoint_string = vaEntrypointStr(
ctx->va_entrypoint);
1075 entrypoint_string =
"(no entrypoint names)";
1078 entrypoint_string,
ctx->va_entrypoint);
1082 if (rt_format->
depth == depth &&
1090 "found for profile %s (%d) entrypoint %s (%d).\n",
1091 profile_string,
ctx->va_profile,
1092 entrypoint_string,
ctx->va_entrypoint);
1097 rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1098 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1099 ctx->va_profile,
ctx->va_entrypoint,
1100 &rt_format_attr, 1);
1101 if (vas != VA_STATUS_SUCCESS) {
1103 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1108 if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1110 "supported by driver: assuming surface RT format %s "
1111 "is valid.\n", rt_format->
name);
1112 }
else if (!(rt_format_attr.value & rt_format->
value)) {
1114 "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1115 rt_format->
name, profile_string,
ctx->va_profile,
1116 entrypoint_string,
ctx->va_entrypoint);
1121 "format %s (%#x).\n", rt_format->
name, rt_format->
value);
1122 ctx->config_attributes[
ctx->nb_config_attributes++] =
1124 .type = VAConfigAttribRTFormat,
1125 .value = rt_format->
value,
1138 #if VA_CHECK_VERSION(1, 21, 0)
1140 VASurfaceAttrib *attr_list =
NULL;
1141 unsigned int attr_count = 0;
1142 VAConfigID va_config;
1146 vas = vaCreateConfig(
ctx->hwctx->display,
1147 ctx->va_profile,
ctx->va_entrypoint,
1148 NULL, 0, &va_config);
1149 if (vas != VA_STATUS_SUCCESS) {
1151 "configuration: %d (%s).\n", vas, vaErrorStr(vas));
1155 vas = vaQuerySurfaceAttributes(
ctx->hwctx->display, va_config,
1157 if (vas != VA_STATUS_SUCCESS) {
1159 "%d (%s).\n", vas, vaErrorStr(vas));
1164 attr_list =
av_malloc(attr_count *
sizeof(*attr_list));
1170 vas = vaQuerySurfaceAttributes(
ctx->hwctx->display, va_config,
1171 attr_list, &attr_count);
1172 if (vas != VA_STATUS_SUCCESS) {
1174 "%d (%s).\n", vas, vaErrorStr(vas));
1179 for (
unsigned int i = 0;
i < attr_count;
i++) {
1180 if (attr_list[
i].
type == VASurfaceAttribAlignmentSize) {
1181 ctx->surface_alignment_width =
1182 1 << (attr_list[
i].value.value.i & 0xf);
1183 ctx->surface_alignment_height =
1184 1 << ((attr_list[
i].value.value.i & 0xf0) >> 4);
1191 vaDestroyConfig(
ctx->hwctx->display, va_config);
1205 #if VA_CHECK_VERSION(1, 1, 0)
1210 #if VA_CHECK_VERSION(1, 3, 0)
1222 uint32_t supported_va_rc_modes;
1225 int rc_target_percentage;
1229 int64_t hrd_initial_buffer_fullness;
1231 VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1233 char supported_rc_modes_string[64];
1235 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1236 ctx->va_profile,
ctx->va_entrypoint,
1238 if (vas != VA_STATUS_SUCCESS) {
1240 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1243 if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1245 "supported rate control modes: assuming CQP only.\n");
1246 supported_va_rc_modes = VA_RC_CQP;
1247 strcpy(supported_rc_modes_string,
"unknown");
1249 char *str = supported_rc_modes_string;
1250 size_t len =
sizeof(supported_rc_modes_string);
1253 supported_va_rc_modes = rc_attr.value;
1255 #if VA_CHECK_VERSION(0, 39, 2)
1256 if (!(supported_va_rc_modes & VA_RC_MB)) {
1263 "or above, which can support BLBRC.\n");
1269 if (supported_va_rc_modes &
rc_mode->va_mode) {
1285 supported_rc_modes_string);
1301 #define TRY_RC_MODE(mode, fail) do { \
1302 rc_mode = &vaapi_encode_rc_modes[mode]; \
1303 if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1305 av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1306 "RC mode (supported modes: %s).\n", rc_mode->name, \
1307 supported_rc_modes_string); \
1308 return AVERROR(EINVAL); \
1310 av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1311 "RC mode.\n", rc_mode->name); \
1314 goto rc_mode_found; \
1318 if (
ctx->explicit_rc_mode)
1321 if (
ctx->explicit_qp)
1354 "RC mode compatible with selected options "
1355 "(supported modes: %s).\n", supported_rc_modes_string);
1372 rc_bits_per_second = avctx->
bit_rate;
1378 rc_target_percentage = 100;
1385 }
else if (
rc_mode->maxrate) {
1389 "bitrate (%"PRId64
") must not be greater than "
1390 "maxrate (%"PRId64
").\n", avctx->
bit_rate,
1395 rc_target_percentage = (avctx->
bit_rate * 100) /
1402 rc_bits_per_second = 2 * avctx->
bit_rate;
1403 rc_target_percentage = 50;
1408 "in %s RC mode.\n",
rc_mode->name);
1410 rc_bits_per_second = avctx->
bit_rate;
1411 rc_target_percentage = 100;
1414 rc_bits_per_second = 0;
1415 rc_target_percentage = 100;
1419 if (
ctx->explicit_qp) {
1420 rc_quality =
ctx->explicit_qp;
1427 rc_quality =
ctx->codec->default_quality;
1429 "using default (%d).\n", rc_quality);
1445 "must have initial buffer size (%d) <= "
1446 "buffer size (%"PRId64
").\n",
1452 hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1455 rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1459 "in %s RC mode.\n",
rc_mode->name);
1462 hrd_buffer_size = 0;
1463 hrd_initial_buffer_fullness = 0;
1467 rc_window_size = 1000;
1471 if (rc_bits_per_second > UINT32_MAX ||
1472 hrd_buffer_size > UINT32_MAX ||
1473 hrd_initial_buffer_fullness > UINT32_MAX) {
1475 "greater are not supported by VAAPI.\n");
1480 ctx->rc_quality = rc_quality;
1482 ctx->va_bit_rate = rc_bits_per_second;
1486 if (
ctx->blbrc &&
ctx->va_rc_mode == VA_RC_CQP)
1490 if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1493 ctx->config_attributes[
ctx->nb_config_attributes++] =
1495 .type = VAConfigAttribRateControl,
1496 #if VA_CHECK_VERSION(0, 39, 2)
1497 .value =
ctx->blbrc ?
ctx->va_rc_mode | VA_RC_MB :
ctx->va_rc_mode,
1499 .value =
ctx->va_rc_mode,
1507 if (
rc_mode->va_mode != VA_RC_CQP) {
1510 "converging in %d frames with %d%% accuracy.\n",
1511 rc_bits_per_second, rc_window_size,
1512 rc_target_percentage);
1513 }
else if (
rc_mode->bitrate) {
1515 "%"PRId64
" bps over %d ms.\n", rc_target_percentage,
1516 rc_bits_per_second, rc_window_size);
1519 ctx->rc_params = (VAEncMiscParameterRateControl) {
1520 .bits_per_second = rc_bits_per_second,
1521 .target_percentage = rc_target_percentage,
1522 .window_size = rc_window_size,
1524 .min_qp = (avctx->
qmin > 0 ? avctx->
qmin : 0),
1525 .basic_unit_size = 0,
1526 #
if VA_CHECK_VERSION(1, 1, 0)
1527 .ICQ_quality_factor =
av_clip(rc_quality, 1, 51),
1528 .max_qp = (avctx->
qmax > 0 ? avctx->
qmax : 0),
1530 #
if VA_CHECK_VERSION(1, 3, 0)
1531 .quality_factor = rc_quality,
1533 #if VA_CHECK_VERSION(0, 39, 2)
1534 .rc_flags.bits.mb_rate_control =
ctx->blbrc ? 1 : 2,
1538 VAEncMiscParameterTypeRateControl,
1540 sizeof(
ctx->rc_params));
1545 "initial fullness %"PRId64
" bits.\n",
1546 hrd_buffer_size, hrd_initial_buffer_fullness);
1548 ctx->hrd_params = (VAEncMiscParameterHRD) {
1549 .initial_buffer_fullness = hrd_initial_buffer_fullness,
1550 .buffer_size = hrd_buffer_size,
1553 VAEncMiscParameterTypeHRD,
1555 sizeof(
ctx->hrd_params));
1566 fr_num, fr_den, (
double)fr_num / fr_den);
1568 ctx->fr_params = (VAEncMiscParameterFrameRate) {
1569 .framerate = (
unsigned int)fr_den << 16 | fr_num,
1571 #if VA_CHECK_VERSION(0, 40, 0)
1573 VAEncMiscParameterTypeFrameRate,
1575 sizeof(
ctx->fr_params));
1583 #if VA_CHECK_VERSION(1, 5, 0)
1585 VAConfigAttrib attr = { VAConfigAttribMaxFrameSize };
1588 if (
ctx->va_rc_mode == VA_RC_CQP) {
1589 ctx->max_frame_size = 0;
1595 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1599 if (vas != VA_STATUS_SUCCESS) {
1600 ctx->max_frame_size = 0;
1602 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1606 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1607 ctx->max_frame_size = 0;
1609 "is not supported.\n");
1612 VAConfigAttribValMaxFrameSize attr_mfs;
1613 attr_mfs.value = attr.value;
1615 if (!attr_mfs.bits.max_frame_size && attr_mfs.bits.multiple_pass) {
1616 ctx->max_frame_size = 0;
1618 "max frame size which has not been implemented in FFmpeg.\n");
1622 ctx->mfs_params = (VAEncMiscParameterBufferMaxFrameSize){
1623 .max_frame_size =
ctx->max_frame_size * 8,
1627 ctx->max_frame_size);
1631 "this VAAPI version.\n");
1643 VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1644 uint32_t ref_l0, ref_l1;
1645 int prediction_pre_only, err;
1647 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1651 if (vas != VA_STATUS_SUCCESS) {
1653 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1657 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1658 ref_l0 = ref_l1 = 0;
1660 ref_l0 = attr.value & 0xffff;
1661 ref_l1 = attr.value >> 16 & 0xffff;
1665 prediction_pre_only = 0;
1667 #if VA_CHECK_VERSION(1, 9, 0)
1670 attr = (VAConfigAttrib) { VAConfigAttribPredictionDirection };
1671 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1675 if (vas != VA_STATUS_SUCCESS) {
1677 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1679 }
else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1681 "prediction constraints.\n");
1683 if (((ref_l0 > 0 || ref_l1 > 0) && !(attr.value & VA_PREDICTION_DIRECTION_PREVIOUS)) ||
1684 ((ref_l1 == 0) && (attr.value & (VA_PREDICTION_DIRECTION_FUTURE | VA_PREDICTION_DIRECTION_BI_NOT_EMPTY)))) {
1686 "direction attribute.\n");
1690 if (!(attr.value & VA_PREDICTION_DIRECTION_FUTURE)) {
1691 if (ref_l0 > 0 && ref_l1 > 0) {
1692 prediction_pre_only = 1;
1694 "lists for B-frames.\n");
1698 if (attr.value & VA_PREDICTION_DIRECTION_BI_NOT_EMPTY) {
1699 if (ref_l0 > 0 && ref_l1 > 0) {
1702 "replacing them with B-frames.\n");
1710 ctx->codec->
flags, prediction_pre_only);
1718 uint32_t slice_structure)
1728 if (avctx->
slices >
ctx->slice_block_rows) {
1730 "configured number of slices (%d < %d); using "
1731 "maximum.\n",
ctx->slice_block_rows, avctx->
slices);
1732 req_slices =
ctx->slice_block_rows;
1734 req_slices = avctx->
slices;
1736 if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1737 slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1738 ctx->nb_slices = req_slices;
1739 ctx->slice_size =
ctx->slice_block_rows /
ctx->nb_slices;
1740 }
else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1742 for (k = 1;; k *= 2) {
1743 if (2 * k * (req_slices - 1) + 1 >=
ctx->slice_block_rows)
1746 ctx->nb_slices = (
ctx->slice_block_rows + k - 1) / k;
1747 ctx->slice_size = k;
1748 #if VA_CHECK_VERSION(1, 0, 0)
1749 }
else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1750 ctx->nb_slices =
ctx->slice_block_rows;
1751 ctx->slice_size = 1;
1755 "slice structure modes (%#x).\n", slice_structure);
1763 uint32_t slice_structure)
1768 if (!(slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS ||
1769 (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS &&
1770 ctx->tile_cols == 1))) {
1772 "current tile requirement.\n", slice_structure);
1776 if (
ctx->tile_rows >
ctx->slice_block_rows ||
1777 ctx->tile_cols >
ctx->slice_block_cols) {
1779 "for configured number of tile (%d x %d); ",
1780 ctx->slice_block_rows,
ctx->slice_block_cols,
1781 ctx->tile_rows,
ctx->tile_cols);
1782 ctx->tile_rows =
ctx->tile_rows >
ctx->slice_block_rows ?
1783 ctx->slice_block_rows :
ctx->tile_rows;
1784 ctx->tile_cols =
ctx->tile_cols >
ctx->slice_block_cols ?
1785 ctx->slice_block_cols :
ctx->tile_cols;
1787 ctx->tile_rows,
ctx->tile_cols);
1790 req_tiles =
ctx->tile_rows *
ctx->tile_cols;
1795 if (avctx->
slices != req_tiles)
1797 "mismatches with configured number of tile (%d != %d); "
1798 "using requested tile number for slice.\n",
1799 avctx->
slices, req_tiles);
1801 ctx->nb_slices = req_tiles;
1805 for (
i = 0;
i <
ctx->tile_cols;
i++) {
1806 ctx->col_width[
i] = (
i + 1 ) *
ctx->slice_block_cols /
ctx->tile_cols -
1807 i *
ctx->slice_block_cols /
ctx->tile_cols;
1808 ctx->col_bd[
i + 1] =
ctx->col_bd[
i] +
ctx->col_width[
i];
1811 for (
i = 0;
i <
ctx->tile_rows;
i++) {
1812 ctx->row_height[
i] = (
i + 1 ) *
ctx->slice_block_rows /
ctx->tile_rows -
1813 i *
ctx->slice_block_rows /
ctx->tile_rows;
1814 ctx->row_bd[
i + 1] =
ctx->row_bd[
i] +
ctx->row_height[
i];
1818 ctx->tile_rows,
ctx->tile_cols);
1827 VAConfigAttrib attr[3] = { { VAConfigAttribEncMaxSlices },
1828 { VAConfigAttribEncSliceStructure },
1829 #if VA_CHECK_VERSION(1, 1, 0)
1830 { VAConfigAttribEncTileSupport },
1834 uint32_t max_slices, slice_structure;
1840 "but this codec does not support controlling slices.\n");
1852 if (avctx->
slices <= 1 && !
ctx->tile_rows && !
ctx->tile_cols) {
1854 ctx->slice_size =
ctx->slice_block_rows;
1858 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1862 if (vas != VA_STATUS_SUCCESS) {
1864 "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1867 max_slices = attr[0].value;
1868 slice_structure = attr[1].value;
1869 if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
1870 slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
1872 "pictures as multiple slices.\n.");
1876 if (
ctx->tile_rows &&
ctx->tile_cols) {
1877 #if VA_CHECK_VERSION(1, 1, 0)
1878 uint32_t tile_support = attr[2].value;
1879 if (tile_support == VA_ATTRIB_NOT_SUPPORTED) {
1881 "pictures as multiple tiles.\n.");
1886 "not supported with this VAAPI version.\n");
1891 if (
ctx->tile_rows &&
ctx->tile_cols)
1900 "%d (from %d) due to driver constraints on slice "
1901 "structure.\n",
ctx->nb_slices, avctx->
slices);
1903 if (
ctx->nb_slices > max_slices) {
1905 "encoding with %d slices (max %"PRIu32
").\n",
1906 ctx->nb_slices, max_slices);
1919 VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
1921 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1925 if (vas != VA_STATUS_SUCCESS) {
1927 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1931 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1932 if (
ctx->desired_packed_headers) {
1934 "packed headers (wanted %#x).\n",
1935 ctx->desired_packed_headers);
1938 "packed headers (none wanted).\n");
1940 ctx->va_packed_headers = 0;
1942 if (
ctx->desired_packed_headers & ~attr.value) {
1944 "wanted packed headers (wanted %#x, found %#x).\n",
1945 ctx->desired_packed_headers, attr.value);
1948 "available (wanted %#x, found %#x).\n",
1949 ctx->desired_packed_headers, attr.value);
1951 ctx->va_packed_headers =
ctx->desired_packed_headers & attr.value;
1954 if (
ctx->va_packed_headers) {
1955 ctx->config_attributes[
ctx->nb_config_attributes++] =
1957 .type = VAConfigAttribEncPackedHeaders,
1958 .value =
ctx->va_packed_headers,
1962 if ( (
ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1963 !(
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1966 "sequence headers, but a global header is requested.\n");
1968 "this may result in a stream which is not usable for some "
1969 "purposes (e.g. not muxable to some containers).\n");
1977 #if VA_CHECK_VERSION(0, 36, 0)
1980 VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
1983 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1987 if (vas != VA_STATUS_SUCCESS) {
1989 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1993 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1996 "supported: will use default quality level.\n");
2001 "valid range is 0-%d, using %d.\n",
2002 attr.value, attr.value);
2006 ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2010 VAEncMiscParameterTypeQualityLevel,
2011 &
ctx->quality_params,
2012 sizeof(
ctx->quality_params));
2016 "not supported with this VAAPI version.\n");
2024 #if VA_CHECK_VERSION(1, 0, 0)
2028 VAConfigAttrib attr = { VAConfigAttribEncROI };
2030 vas = vaGetConfigAttributes(
ctx->hwctx->display,
2034 if (vas != VA_STATUS_SUCCESS) {
2036 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2040 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2043 VAConfigAttribValEncROI roi = {
2044 .value = attr.value,
2047 ctx->roi_max_regions = roi.bits.num_roi_regions;
2049 (
ctx->va_rc_mode == VA_RC_CQP ||
2050 roi.bits.roi_rc_qp_delta_support);
2061 VABufferID *buffer_id_ref = obj;
2062 VABufferID buffer_id = *buffer_id_ref;
2064 vaDestroyBuffer(
ctx->hwctx->display, buffer_id);
2074 VABufferID *buffer_id = obj;
2081 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
2082 VAEncCodedBufferType,
2084 (1 << 16), 1, 0, buffer_id);
2085 if (vas != VA_STATUS_SUCCESS) {
2087 "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2130 "frame context: %d.\n", err);
2169 ctx->va_config = VA_INVALID_ID;
2170 ctx->va_context = VA_INVALID_ID;
2184 if (
ctx->codec->get_encoder_caps) {
2185 err =
ctx->codec->get_encoder_caps(avctx);
2224 if (
ctx->max_frame_size) {
2230 vas = vaCreateConfig(
ctx->hwctx->display,
2231 ctx->va_profile,
ctx->va_entrypoint,
2232 ctx->config_attributes,
ctx->nb_config_attributes,
2234 if (vas != VA_STATUS_SUCCESS) {
2236 "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2246 vas = vaCreateContext(
ctx->hwctx->display,
ctx->va_config,
2252 if (vas != VA_STATUS_SUCCESS) {
2254 "context: %d (%s).\n", vas, vaErrorStr(vas));
2259 ctx->output_buffer_pool =
2263 if (!
ctx->output_buffer_pool) {
2268 if (
ctx->codec->configure) {
2269 err =
ctx->codec->configure(avctx);
2277 if (
ctx->codec->sequence_params_size > 0) {
2278 ctx->codec_sequence_params =
2280 if (!
ctx->codec_sequence_params) {
2285 if (
ctx->codec->picture_params_size > 0) {
2286 ctx->codec_picture_params =
2288 if (!
ctx->codec_picture_params) {
2294 if (
ctx->codec->init_sequence_params) {
2295 err =
ctx->codec->init_sequence_params(avctx);
2298 "failed: %d.\n", err);
2303 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2304 ctx->codec->write_sequence_header &&
2307 size_t bit_len = 8 *
sizeof(
data);
2309 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
2312 "for extradata: %d.\n", err);
2326 #if VA_CHECK_VERSION(1, 9, 0)
2328 vas = vaSyncBuffer(
ctx->hwctx->display, VA_INVALID_ID, 0);
2329 if (vas != VA_STATUS_ERROR_UNIMPLEMENTED) {
2353 if (!base_ctx->
frame)
2356 for (pic = base_ctx->
pic_start; pic; pic = next) {
2363 if (
ctx->va_context != VA_INVALID_ID) {
2365 vaDestroyContext(
ctx->hwctx->display,
ctx->va_context);
2366 ctx->va_context = VA_INVALID_ID;
2369 if (
ctx->va_config != VA_INVALID_ID) {
2371 vaDestroyConfig(
ctx->hwctx->display,
ctx->va_config);
2372 ctx->va_config = VA_INVALID_ID;