39 int type,
char *
data,
size_t bit_len)
43 VABufferID param_buffer, data_buffer;
45 VAEncPackedHeaderParameterBuffer params = {
47 .bit_length = bit_len,
48 .has_emulation_bytes = 1,
56 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
57 VAEncPackedHeaderParameterBufferType,
58 sizeof(params), 1, ¶ms, ¶m_buffer);
59 if (vas != VA_STATUS_SUCCESS) {
61 "for packed header (type %d): %d (%s).\n",
62 type, vas, vaErrorStr(vas));
67 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
68 VAEncPackedHeaderDataBufferType,
69 (bit_len + 7) / 8, 1,
data, &data_buffer);
70 if (vas != VA_STATUS_SUCCESS) {
72 "for packed header (type %d): %d (%s).\n",
73 type, vas, vaErrorStr(vas));
79 "(%zu bits).\n",
type, param_buffer, data_buffer, bit_len);
97 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
99 if (vas != VA_STATUS_SUCCESS) {
101 "(type %d): %d (%s).\n",
type, vas, vaErrorStr(vas));
120 VAEncMiscParameterBuffer
header = {
123 size_t buffer_size =
sizeof(
header) +
len;
130 VAEncMiscParameterBufferType,
152 if (vas != VA_STATUS_SUCCESS) {
154 "%d (%s).\n", vas, vaErrorStr(vas));
221 if (
ctx->codec->picture_params_size > 0) {
226 ctx->codec->picture_params_size);
235 VAEncSequenceParameterBufferType,
236 ctx->codec_sequence_params,
237 ctx->codec->sequence_params_size);
243 for (
i = 0;
i <
ctx->nb_global_params;
i++) {
245 ctx->global_params_type[
i],
246 ctx->global_params[
i],
247 ctx->global_params_size[
i]);
253 if (
ctx->codec->init_picture_params) {
254 err =
ctx->codec->init_picture_params(avctx, pic);
257 "parameters: %d.\n", err);
261 VAEncPictureParameterBufferType,
263 ctx->codec->picture_params_size);
269 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
270 ctx->codec->write_sequence_header) {
271 bit_len = 8 *
sizeof(
data);
272 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
275 "header: %d.\n", err);
279 ctx->codec->sequence_header_type,
286 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE &&
287 ctx->codec->write_picture_header) {
288 bit_len = 8 *
sizeof(
data);
289 err =
ctx->codec->write_picture_header(avctx, pic,
data, &bit_len);
292 "header: %d.\n", err);
296 ctx->codec->picture_header_type,
302 if (
ctx->codec->write_extra_buffer) {
306 err =
ctx->codec->write_extra_buffer(avctx, pic,
i, &
type,
312 "buffer %d: %d.\n",
i, err);
323 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC &&
324 ctx->codec->write_extra_header) {
327 bit_len = 8 *
sizeof(
data);
328 err =
ctx->codec->write_extra_header(avctx, pic,
i, &
type,
334 "header %d: %d.\n",
i, err);
359 rounding =
ctx->slice_block_rows -
ctx->nb_slices *
ctx->slice_size;
367 for (
i = 0;
i < rounding;
i++)
370 for (
i = 0;
i < (rounding + 1) / 2;
i++)
372 for (
i = 0;
i < rounding / 2;
i++)
375 }
else if (rounding < 0) {
400 if (
ctx->codec->slice_params_size > 0) {
408 if (
ctx->codec->init_slice_params) {
409 err =
ctx->codec->init_slice_params(avctx, pic, slice);
412 "parameters: %d.\n", err);
417 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE &&
418 ctx->codec->write_slice_header) {
419 bit_len = 8 *
sizeof(
data);
420 err =
ctx->codec->write_slice_header(avctx, pic, slice,
424 "header: %d.\n", err);
428 ctx->codec->slice_header_type,
434 if (
ctx->codec->init_slice_params) {
436 VAEncSliceParameterBufferType,
438 ctx->codec->slice_params_size);
444 #if VA_CHECK_VERSION(1, 0, 0)
447 if (sd &&
ctx->roi_allowed) {
450 VAEncMiscParameterBufferROI param_roi;
455 av_assert0(roi_size && sd->size % roi_size == 0);
456 nb_roi = sd->size / roi_size;
457 if (nb_roi >
ctx->roi_max_regions) {
458 if (!
ctx->roi_warned) {
460 "supported by driver (%d > %d).\n",
461 nb_roi,
ctx->roi_max_regions);
464 nb_roi =
ctx->roi_max_regions;
473 for (
i = 0;
i < nb_roi;
i++) {
481 pic->
roi[
i] = (VAEncROI) {
488 .roi_value = av_clip_int8(v),
492 param_roi = (VAEncMiscParameterBufferROI) {
494 .max_delta_qp = INT8_MAX,
495 .min_delta_qp = INT8_MIN,
497 .roi_flags.bits.roi_value_is_qp_delta = 1,
501 VAEncMiscParameterTypeROI,
509 vas = vaBeginPicture(
ctx->hwctx->display,
ctx->va_context,
511 if (vas != VA_STATUS_SUCCESS) {
513 "%d (%s).\n", vas, vaErrorStr(vas));
515 goto fail_with_picture;
518 vas = vaRenderPicture(
ctx->hwctx->display,
ctx->va_context,
520 if (vas != VA_STATUS_SUCCESS) {
522 "%d (%s).\n", vas, vaErrorStr(vas));
524 goto fail_with_picture;
527 vas = vaEndPicture(
ctx->hwctx->display,
ctx->va_context);
528 if (vas != VA_STATUS_SUCCESS) {
530 "%d (%s).\n", vas, vaErrorStr(vas));
534 if (CONFIG_VAAPI_1 ||
ctx->hwctx->driver_quirks &
541 if (CONFIG_VAAPI_1 ||
ctx->hwctx->driver_quirks &
544 vas = vaDestroyBuffer(
ctx->hwctx->display,
546 if (vas != VA_STATUS_SUCCESS) {
548 "param buffer %#x: %d (%s).\n",
560 vaEndPicture(
ctx->hwctx->display,
ctx->va_context);
585 VACodedBufferSegment *buf_list, *buf;
598 if (vas != VA_STATUS_SUCCESS) {
600 "%d (%s).\n", vas, vaErrorStr(vas));
605 for (buf = buf_list; buf; buf = buf->next)
606 total_size += buf->size;
614 for (buf = buf_list; buf; buf = buf->next) {
616 "(status %08x).\n", buf->size, buf->status);
618 memcpy(ptr, buf->buf, buf->size);
628 if (vas != VA_STATUS_SUCCESS) {
630 "%d (%s).\n", vas, vaErrorStr(vas));
657 "%"PRId64
"/%"PRId64
".\n",
676 if (
ctx->codec->picture_priv_data_size > 0) {
727 int is_ref,
int in_dpb,
int prev)
800 if (current_depth ==
ctx->max_b_depth || start->
next->
next ==
end) {
801 for (pic = start->
next; pic; pic = pic->
next) {
820 for (pic = start->
next; pic !=
end; pic = pic->
next)
822 for (pic = start->
next,
i = 1; 2 * i < len; pic = pic->next,
i++);
839 current_depth + 1, &next);
844 current_depth + 1, last);
853 int i, b_counter, closed_gop_end;
858 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
873 "encode next.\n", pic->
b_depth);
882 closed_gop_end =
ctx->closed_gop ||
883 ctx->idr_counter ==
ctx->gop_per_idr;
884 for (pic =
ctx->pic_start; pic; pic = next) {
894 if (b_counter ==
ctx->b_per_p)
898 if (
ctx->gop_counter + b_counter + closed_gop_end >=
ctx->gop_size)
902 if (next && next->force_idr)
908 if (!pic &&
ctx->end_of_stream) {
917 "need more input for reference pictures.\n");
920 if (
ctx->input_order <=
ctx->decode_delay && !
ctx->end_of_stream) {
922 "need more input for timestamps.\n");
930 ctx->idr_counter = 1;
931 ctx->gop_counter = 1;
933 }
else if (
ctx->gop_counter + b_counter >=
ctx->gop_size) {
934 if (
ctx->idr_counter ==
ctx->gop_per_idr) {
938 ctx->idr_counter = 1;
945 ctx->gop_counter = 1;
948 if (
ctx->gop_counter + b_counter + closed_gop_end ==
ctx->gop_size) {
957 ctx->gop_counter += 1 + b_counter;
970 --
ctx->next_prev->ref_count[0];
976 ctx->next_prev = pic;
978 ++
ctx->next_prev->ref_count[0];
990 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
996 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
1003 for (pic =
ctx->pic_start; pic; pic = next) {
1010 ctx->pic_start = next;
1025 if ((
frame->crop_top ||
frame->crop_bottom ||
1026 frame->crop_left ||
frame->crop_right) && !
ctx->crop_warned) {
1028 "frames ignored due to lack of API support.\n");
1029 ctx->crop_warned = 1;
1032 if (!
ctx->roi_allowed) {
1036 if (sd && !
ctx->roi_warned) {
1038 "frames ignored due to lack of driver support.\n");
1039 ctx->roi_warned = 1;
1079 if (
ctx->input_order == 0)
1080 ctx->first_pts = pic->
pts;
1081 if (
ctx->input_order ==
ctx->decode_delay)
1082 ctx->dts_pts_diff = pic->
pts -
ctx->first_pts;
1083 if (
ctx->output_delay > 0)
1084 ctx->ts_ring[
ctx->input_order % (3 *
ctx->output_delay)] = pic->
pts;
1089 if (
ctx->pic_start) {
1090 ctx->pic_end->next = pic;
1093 ctx->pic_start = pic;
1098 ctx->end_of_stream = 1;
1102 if (
ctx->input_order <
ctx->decode_delay)
1103 ctx->dts_pts_diff =
ctx->pic_end->pts -
ctx->first_pts;
1119 if (!
ctx->pic_start) {
1120 if (
ctx->end_of_stream)
1146 if (
ctx->output_delay == 0) {
1155 (3 *
ctx->output_delay)];
1174 ctx->global_params_type[
ctx->nb_global_params] =
type;
1176 ctx->global_params_size[
ctx->nb_global_params] =
size;
1178 ++
ctx->nb_global_params;
1191 {
"YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
1192 {
"YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
1193 {
"YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
1194 {
"YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1195 {
"YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
1196 #if VA_CHECK_VERSION(0, 38, 1)
1197 {
"YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
1202 VAEntrypointEncSlice,
1203 VAEntrypointEncPicture,
1204 #if VA_CHECK_VERSION(0, 39, 2)
1205 VAEntrypointEncSliceLP,
1209 #if VA_CHECK_VERSION(0, 39, 2)
1210 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
1211 VAEntrypointEncSliceLP,
1219 VAProfile *va_profiles =
NULL;
1220 VAEntrypoint *va_entrypoints =
NULL;
1222 const VAEntrypoint *usable_entrypoints;
1225 VAConfigAttrib rt_format_attr;
1227 const char *profile_string, *entrypoint_string;
1228 int i, j, n, depth, err;
1231 if (
ctx->low_power) {
1232 #if VA_CHECK_VERSION(0, 39, 2)
1233 usable_entrypoints = vaapi_encode_entrypoints_low_power;
1236 "supported with this VAAPI version.\n");
1246 ctx->input_frames->sw_format);
1249 depth =
desc->comp[0].depth;
1250 for (
i = 1;
i <
desc->nb_components;
i++) {
1251 if (
desc->comp[
i].depth != depth) {
1260 n = vaMaxNumProfiles(
ctx->hwctx->display);
1266 vas = vaQueryConfigProfiles(
ctx->hwctx->display, va_profiles, &n);
1267 if (vas != VA_STATUS_SUCCESS) {
1269 vas, vaErrorStr(vas));
1275 for (
i = 0; (
ctx->codec->profiles[
i].av_profile !=
1278 if (depth !=
profile->depth ||
1281 if (
desc->nb_components > 1 &&
1289 #if VA_CHECK_VERSION(1, 0, 0)
1290 profile_string = vaProfileStr(
profile->va_profile);
1292 profile_string =
"(no profile names)";
1295 for (j = 0; j < n; j++) {
1296 if (va_profiles[j] ==
profile->va_profile)
1301 "is not supported by driver.\n", profile_string,
1309 if (!
ctx->profile) {
1318 profile_string,
ctx->va_profile);
1320 n = vaMaxNumEntrypoints(
ctx->hwctx->display);
1322 if (!va_entrypoints) {
1326 vas = vaQueryConfigEntrypoints(
ctx->hwctx->display,
ctx->va_profile,
1327 va_entrypoints, &n);
1328 if (vas != VA_STATUS_SUCCESS) {
1330 "profile %s (%d): %d (%s).\n", profile_string,
1331 ctx->va_profile, vas, vaErrorStr(vas));
1336 for (
i = 0;
i < n;
i++) {
1337 for (j = 0; usable_entrypoints[j]; j++) {
1338 if (va_entrypoints[
i] == usable_entrypoints[j])
1341 if (usable_entrypoints[j])
1346 "for profile %s (%d).\n", profile_string,
ctx->va_profile);
1351 ctx->va_entrypoint = va_entrypoints[
i];
1352 #if VA_CHECK_VERSION(1, 0, 0)
1353 entrypoint_string = vaEntrypointStr(
ctx->va_entrypoint);
1355 entrypoint_string =
"(no entrypoint names)";
1358 entrypoint_string,
ctx->va_entrypoint);
1362 if (rt_format->
depth == depth &&
1370 "found for profile %s (%d) entrypoint %s (%d).\n",
1371 profile_string,
ctx->va_profile,
1372 entrypoint_string,
ctx->va_entrypoint);
1377 rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1378 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1379 ctx->va_profile,
ctx->va_entrypoint,
1380 &rt_format_attr, 1);
1381 if (vas != VA_STATUS_SUCCESS) {
1383 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1388 if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1390 "supported by driver: assuming surface RT format %s "
1391 "is valid.\n", rt_format->
name);
1392 }
else if (!(rt_format_attr.value & rt_format->
value)) {
1394 "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1395 rt_format->
name, profile_string,
ctx->va_profile,
1396 entrypoint_string,
ctx->va_entrypoint);
1401 "format %s (%#x).\n", rt_format->
name, rt_format->
value);
1402 ctx->config_attributes[
ctx->nb_config_attributes++] =
1404 .type = VAConfigAttribRTFormat,
1405 .value = rt_format->
value,
1423 #if VA_CHECK_VERSION(1, 1, 0)
1428 #if VA_CHECK_VERSION(1, 3, 0)
1440 uint32_t supported_va_rc_modes;
1442 int64_t rc_bits_per_second;
1443 int rc_target_percentage;
1446 int64_t hrd_buffer_size;
1447 int64_t hrd_initial_buffer_fullness;
1449 VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1451 char supported_rc_modes_string[64];
1453 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1454 ctx->va_profile,
ctx->va_entrypoint,
1456 if (vas != VA_STATUS_SUCCESS) {
1458 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1461 if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1463 "supported rate control modes: assuming CQP only.\n");
1464 supported_va_rc_modes = VA_RC_CQP;
1465 strcpy(supported_rc_modes_string,
"unknown");
1467 char *
str = supported_rc_modes_string;
1468 size_t len =
sizeof(supported_rc_modes_string);
1471 supported_va_rc_modes = rc_attr.value;
1474 if (supported_va_rc_modes &
rc_mode->va_mode) {
1490 supported_rc_modes_string);
1505 #define TRY_RC_MODE(mode, fail) do { \
1506 rc_mode = &vaapi_encode_rc_modes[mode]; \
1507 if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1509 av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1510 "RC mode (supported modes: %s).\n", rc_mode->name, \
1511 supported_rc_modes_string); \
1512 return AVERROR(EINVAL); \
1514 av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1515 "RC mode.\n", rc_mode->name); \
1518 goto rc_mode_found; \
1522 if (
ctx->explicit_rc_mode)
1525 if (
ctx->explicit_qp)
1555 "RC mode compatible with selected options "
1556 "(supported modes: %s).\n", supported_rc_modes_string);
1573 rc_bits_per_second = avctx->
bit_rate;
1579 rc_target_percentage = 100;
1586 }
else if (
rc_mode->maxrate) {
1590 "bitrate (%"PRId64
") must not be greater than "
1591 "maxrate (%"PRId64
").\n", avctx->
bit_rate,
1596 rc_target_percentage = (avctx->
bit_rate * 100) /
1603 rc_bits_per_second = 2 * avctx->
bit_rate;
1604 rc_target_percentage = 50;
1609 "in %s RC mode.\n",
rc_mode->name);
1611 rc_bits_per_second = avctx->
bit_rate;
1612 rc_target_percentage = 100;
1615 rc_bits_per_second = 0;
1616 rc_target_percentage = 100;
1620 if (
ctx->explicit_qp) {
1621 rc_quality =
ctx->explicit_qp;
1625 rc_quality =
ctx->codec->default_quality;
1627 "using default (%d).\n", rc_quality);
1643 "must have initial buffer size (%d) <= "
1644 "buffer size (%"PRId64
").\n",
1650 hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1653 rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1657 "in %s RC mode.\n",
rc_mode->name);
1660 hrd_buffer_size = 0;
1661 hrd_initial_buffer_fullness = 0;
1665 rc_window_size = 1000;
1669 if (rc_bits_per_second > UINT32_MAX ||
1670 hrd_buffer_size > UINT32_MAX ||
1671 hrd_initial_buffer_fullness > UINT32_MAX) {
1673 "greater are not supported by VAAPI.\n");
1678 ctx->rc_quality = rc_quality;
1680 ctx->va_bit_rate = rc_bits_per_second;
1683 if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1686 ctx->config_attributes[
ctx->nb_config_attributes++] =
1688 .type = VAConfigAttribRateControl,
1689 .value =
ctx->va_rc_mode,
1696 if (
rc_mode->va_mode != VA_RC_CQP) {
1699 "converging in %d frames with %d%% accuracy.\n",
1700 rc_bits_per_second, rc_window_size,
1701 rc_target_percentage);
1702 }
else if (
rc_mode->bitrate) {
1704 "%"PRId64
" bps over %d ms.\n", rc_target_percentage,
1705 rc_bits_per_second, rc_window_size);
1708 ctx->rc_params = (VAEncMiscParameterRateControl) {
1709 .bits_per_second = rc_bits_per_second,
1710 .target_percentage = rc_target_percentage,
1711 .window_size = rc_window_size,
1713 .min_qp = (avctx->
qmin > 0 ? avctx->
qmin : 0),
1714 .basic_unit_size = 0,
1715 #
if VA_CHECK_VERSION(1, 1, 0)
1716 .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
1717 .max_qp = (avctx->
qmax > 0 ? avctx->
qmax : 0),
1719 #
if VA_CHECK_VERSION(1, 3, 0)
1720 .quality_factor = rc_quality,
1724 VAEncMiscParameterTypeRateControl,
1726 sizeof(
ctx->rc_params));
1731 "initial fullness %"PRId64
" bits.\n",
1732 hrd_buffer_size, hrd_initial_buffer_fullness);
1734 ctx->hrd_params = (VAEncMiscParameterHRD) {
1735 .initial_buffer_fullness = hrd_initial_buffer_fullness,
1736 .buffer_size = hrd_buffer_size,
1739 VAEncMiscParameterTypeHRD,
1741 sizeof(
ctx->hrd_params));
1752 fr_num, fr_den, (
double)fr_num / fr_den);
1754 ctx->fr_params = (VAEncMiscParameterFrameRate) {
1755 .framerate = (
unsigned int)fr_den << 16 | fr_num,
1757 #if VA_CHECK_VERSION(0, 40, 0)
1759 VAEncMiscParameterTypeFrameRate,
1761 sizeof(
ctx->fr_params));
1771 VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1772 uint32_t ref_l0, ref_l1;
1774 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1778 if (vas != VA_STATUS_SUCCESS) {
1780 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1784 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1785 ref_l0 = ref_l1 = 0;
1787 ref_l0 = attr.value & 0xffff;
1788 ref_l1 = attr.value >> 16 & 0xffff;
1795 }
else if (ref_l0 < 1) {
1797 "reference frames.\n");
1800 ref_l1 < 1 || avctx->max_b_frames < 1) {
1802 "(supported references: %d / %d).\n", ref_l0, ref_l1);
1804 ctx->p_per_i = INT_MAX;
1808 "(supported references: %d / %d).\n", ref_l0, ref_l1);
1810 ctx->p_per_i = INT_MAX;
1816 ctx->max_b_depth = 1;
1822 ctx->gop_per_idr =
ctx->idr_interval + 1;
1824 ctx->closed_gop = 1;
1825 ctx->gop_per_idr = 1;
1834 VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices },
1835 { VAConfigAttribEncSliceStructure } };
1837 uint32_t max_slices, slice_structure;
1843 "but this codec does not support controlling slices.\n");
1848 ctx->slice_block_rows = (avctx->
height +
ctx->slice_block_height - 1) /
1849 ctx->slice_block_height;
1850 ctx->slice_block_cols = (avctx->
width +
ctx->slice_block_width - 1) /
1851 ctx->slice_block_width;
1853 if (avctx->
slices <= 1) {
1855 ctx->slice_size =
ctx->slice_block_rows;
1859 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1863 if (vas != VA_STATUS_SUCCESS) {
1865 "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1868 max_slices = attr[0].value;
1869 slice_structure = attr[1].value;
1870 if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
1871 slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
1873 "pictures as multiple slices.\n.");
1882 if (avctx->
slices >
ctx->slice_block_rows) {
1884 "configured number of slices (%d < %d); using "
1885 "maximum.\n",
ctx->slice_block_rows, avctx->
slices);
1886 req_slices =
ctx->slice_block_rows;
1888 req_slices = avctx->
slices;
1890 if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1891 slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1892 ctx->nb_slices = req_slices;
1893 ctx->slice_size =
ctx->slice_block_rows /
ctx->nb_slices;
1894 }
else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1896 for (k = 1;; k *= 2) {
1897 if (2 * k * (req_slices - 1) + 1 >=
ctx->slice_block_rows)
1900 ctx->nb_slices = (
ctx->slice_block_rows + k - 1) / k;
1901 ctx->slice_size = k;
1902 #if VA_CHECK_VERSION(1, 0, 0)
1903 }
else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1904 ctx->nb_slices =
ctx->slice_block_rows;
1905 ctx->slice_size = 1;
1909 "slice structure modes (%#x).\n", slice_structure);
1915 "%d (from %d) due to driver constraints on slice "
1916 "structure.\n",
ctx->nb_slices, avctx->
slices);
1918 if (
ctx->nb_slices > max_slices) {
1920 "encoding with %d slices (max %"PRIu32
").\n",
1921 ctx->nb_slices, max_slices);
1926 "(default size %d block rows).\n",
1927 ctx->nb_slices,
ctx->slice_size);
1935 VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
1937 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1941 if (vas != VA_STATUS_SUCCESS) {
1943 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1947 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1948 if (
ctx->desired_packed_headers) {
1950 "packed headers (wanted %#x).\n",
1951 ctx->desired_packed_headers);
1954 "packed headers (none wanted).\n");
1956 ctx->va_packed_headers = 0;
1958 if (
ctx->desired_packed_headers & ~attr.value) {
1960 "wanted packed headers (wanted %#x, found %#x).\n",
1961 ctx->desired_packed_headers, attr.value);
1964 "available (wanted %#x, found %#x).\n",
1965 ctx->desired_packed_headers, attr.value);
1967 ctx->va_packed_headers =
ctx->desired_packed_headers & attr.value;
1970 if (
ctx->va_packed_headers) {
1971 ctx->config_attributes[
ctx->nb_config_attributes++] =
1973 .type = VAConfigAttribEncPackedHeaders,
1974 .value =
ctx->va_packed_headers,
1978 if ( (
ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1979 !(
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1982 "sequence headers, but a global header is requested.\n");
1984 "this may result in a stream which is not usable for some "
1985 "purposes (e.g. not muxable to some containers).\n");
1993 #if VA_CHECK_VERSION(0, 36, 0)
1996 VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
1999 vas = vaGetConfigAttributes(
ctx->hwctx->display,
2003 if (vas != VA_STATUS_SUCCESS) {
2005 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2009 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2012 "supported: will use default quality level.\n");
2017 "valid range is 0-%d, using %d.\n",
2018 attr.value, attr.value);
2022 ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
2026 VAEncMiscParameterTypeQualityLevel,
2027 &
ctx->quality_params,
2028 sizeof(
ctx->quality_params));
2032 "not supported with this VAAPI version.\n");
2040 #if VA_CHECK_VERSION(1, 0, 0)
2043 VAConfigAttrib attr = { VAConfigAttribEncROI };
2045 vas = vaGetConfigAttributes(
ctx->hwctx->display,
2049 if (vas != VA_STATUS_SUCCESS) {
2051 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
2055 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
2056 ctx->roi_allowed = 0;
2058 VAConfigAttribValEncROI roi = {
2059 .value = attr.value,
2062 ctx->roi_max_regions = roi.bits.num_roi_regions;
2063 ctx->roi_allowed =
ctx->roi_max_regions > 0 &&
2064 (
ctx->va_rc_mode == VA_RC_CQP ||
2065 roi.bits.roi_rc_qp_delta_support);
2076 VABufferID buffer_id;
2078 buffer_id = (VABufferID)(uintptr_t)
data;
2080 vaDestroyBuffer(
ctx->hwctx->display, buffer_id);
2090 VABufferID buffer_id;
2098 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
2099 VAEncCodedBufferType,
2100 3 *
ctx->surface_width *
ctx->surface_height +
2101 (1 << 16), 1, 0, &buffer_id);
2102 if (vas != VA_STATUS_SUCCESS) {
2104 "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
2115 vaDestroyBuffer(
ctx->hwctx->display, buffer_id);
2150 if (
ctx->input_frames->sw_format ==
2152 recon_format =
ctx->input_frames->sw_format;
2163 recon_format =
ctx->input_frames->sw_format;
2173 "size %dx%d (constraints: width %d-%d height %d-%d).\n",
2174 ctx->surface_width,
ctx->surface_height,
2185 if (!
ctx->recon_frames_ref) {
2192 ctx->recon_frames->sw_format = recon_format;
2193 ctx->recon_frames->width =
ctx->surface_width;
2194 ctx->recon_frames->height =
ctx->surface_height;
2199 "frame context: %d.\n", err);
2219 "required to associate the encoding device.\n");
2223 ctx->va_config = VA_INVALID_ID;
2224 ctx->va_context = VA_INVALID_ID;
2227 if (!
ctx->input_frames_ref) {
2234 if (!
ctx->device_ref) {
2239 ctx->hwctx =
ctx->device->hwctx;
2271 vas = vaCreateConfig(
ctx->hwctx->display,
2272 ctx->va_profile,
ctx->va_entrypoint,
2273 ctx->config_attributes,
ctx->nb_config_attributes,
2275 if (vas != VA_STATUS_SUCCESS) {
2277 "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2286 recon_hwctx =
ctx->recon_frames->hwctx;
2287 vas = vaCreateContext(
ctx->hwctx->display,
ctx->va_config,
2288 ctx->surface_width,
ctx->surface_height,
2293 if (vas != VA_STATUS_SUCCESS) {
2295 "context: %d (%s).\n", vas, vaErrorStr(vas));
2300 ctx->output_buffer_pool =
2303 if (!
ctx->output_buffer_pool) {
2308 if (
ctx->codec->configure) {
2309 err =
ctx->codec->configure(avctx);
2314 ctx->output_delay =
ctx->b_per_p;
2315 ctx->decode_delay =
ctx->max_b_depth;
2317 if (
ctx->codec->sequence_params_size > 0) {
2318 ctx->codec_sequence_params =
2320 if (!
ctx->codec_sequence_params) {
2325 if (
ctx->codec->picture_params_size > 0) {
2326 ctx->codec_picture_params =
2328 if (!
ctx->codec_picture_params) {
2334 if (
ctx->codec->init_sequence_params) {
2335 err =
ctx->codec->init_sequence_params(avctx);
2338 "failed: %d.\n", err);
2343 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2344 ctx->codec->write_sequence_header &&
2347 size_t bit_len = 8 *
sizeof(
data);
2349 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
2352 "for extradata: %d.\n", err);
2377 for (pic =
ctx->pic_start; pic; pic = next) {
2384 if (
ctx->va_context != VA_INVALID_ID) {
2385 vaDestroyContext(
ctx->hwctx->display,
ctx->va_context);
2386 ctx->va_context = VA_INVALID_ID;
2389 if (
ctx->va_config != VA_INVALID_ID) {
2390 vaDestroyConfig(
ctx->hwctx->display,
ctx->va_config);
2391 ctx->va_config = VA_INVALID_ID;