34 int type,
char *
data,
size_t bit_len)
38 VABufferID param_buffer, data_buffer;
40 VAEncPackedHeaderParameterBuffer
params = {
42 .bit_length = bit_len,
43 .has_emulation_bytes = 1,
51 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
52 VAEncPackedHeaderParameterBufferType,
54 if (vas != VA_STATUS_SUCCESS) {
56 "for packed header (type %d): %d (%s).\n",
57 type, vas, vaErrorStr(vas));
62 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
63 VAEncPackedHeaderDataBufferType,
64 (bit_len + 7) / 8, 1,
data, &data_buffer);
65 if (vas != VA_STATUS_SUCCESS) {
67 "for packed header (type %d): %d (%s).\n",
68 type, vas, vaErrorStr(vas));
74 "(%zu bits).\n",
type, param_buffer, data_buffer, bit_len);
92 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
94 if (vas != VA_STATUS_SUCCESS) {
96 "(type %d): %d (%s).\n",
type, vas, vaErrorStr(vas));
115 VAEncMiscParameterBuffer
header = {
118 size_t buffer_size =
sizeof(
header) +
len;
125 VAEncMiscParameterBufferType,
147 if (vas != VA_STATUS_SUCCESS) {
149 "%d (%s).\n", vas, vaErrorStr(vas));
215 if (
ctx->codec->picture_params_size > 0) {
220 ctx->codec->picture_params_size);
229 VAEncSequenceParameterBufferType,
230 ctx->codec_sequence_params,
231 ctx->codec->sequence_params_size);
237 for (
i = 0;
i <
ctx->nb_global_params;
i++) {
239 ctx->global_params_type[
i],
240 ctx->global_params[
i],
241 ctx->global_params_size[
i]);
247 if (
ctx->codec->init_picture_params) {
248 err =
ctx->codec->init_picture_params(avctx, pic);
251 "parameters: %d.\n", err);
255 VAEncPictureParameterBufferType,
257 ctx->codec->picture_params_size);
263 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
264 ctx->codec->write_sequence_header) {
265 bit_len = 8 *
sizeof(
data);
266 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
269 "header: %d.\n", err);
273 ctx->codec->sequence_header_type,
280 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_PICTURE &&
281 ctx->codec->write_picture_header) {
282 bit_len = 8 *
sizeof(
data);
283 err =
ctx->codec->write_picture_header(avctx, pic,
data, &bit_len);
286 "header: %d.\n", err);
290 ctx->codec->picture_header_type,
296 if (
ctx->codec->write_extra_buffer) {
300 err =
ctx->codec->write_extra_buffer(avctx, pic,
i, &
type,
306 "buffer %d: %d.\n",
i, err);
317 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_MISC &&
318 ctx->codec->write_extra_header) {
321 bit_len = 8 *
sizeof(
data);
322 err =
ctx->codec->write_extra_header(avctx, pic,
i, &
type,
328 "header %d: %d.\n",
i, err);
353 rounding =
ctx->slice_block_rows -
ctx->nb_slices *
ctx->slice_size;
361 for (
i = 0;
i < rounding;
i++)
364 for (
i = 0;
i < (rounding + 1) / 2;
i++)
366 for (
i = 0;
i < rounding / 2;
i++)
369 }
else if (rounding < 0) {
394 if (
ctx->codec->slice_params_size > 0) {
402 if (
ctx->codec->init_slice_params) {
403 err =
ctx->codec->init_slice_params(avctx, pic, slice);
406 "parameters: %d.\n", err);
411 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SLICE &&
412 ctx->codec->write_slice_header) {
413 bit_len = 8 *
sizeof(
data);
414 err =
ctx->codec->write_slice_header(avctx, pic, slice,
418 "header: %d.\n", err);
422 ctx->codec->slice_header_type,
428 if (
ctx->codec->init_slice_params) {
430 VAEncSliceParameterBufferType,
432 ctx->codec->slice_params_size);
438 vas = vaBeginPicture(
ctx->hwctx->display,
ctx->va_context,
440 if (vas != VA_STATUS_SUCCESS) {
442 "%d (%s).\n", vas, vaErrorStr(vas));
444 goto fail_with_picture;
447 vas = vaRenderPicture(
ctx->hwctx->display,
ctx->va_context,
449 if (vas != VA_STATUS_SUCCESS) {
451 "%d (%s).\n", vas, vaErrorStr(vas));
453 goto fail_with_picture;
456 vas = vaEndPicture(
ctx->hwctx->display,
ctx->va_context);
457 if (vas != VA_STATUS_SUCCESS) {
459 "%d (%s).\n", vas, vaErrorStr(vas));
463 if (CONFIG_VAAPI_1 ||
ctx->hwctx->driver_quirks &
470 if (CONFIG_VAAPI_1 ||
ctx->hwctx->driver_quirks &
473 vas = vaDestroyBuffer(
ctx->hwctx->display,
475 if (vas != VA_STATUS_SUCCESS) {
477 "param buffer %#x: %d (%s).\n",
489 vaEndPicture(
ctx->hwctx->display,
ctx->va_context);
513 VACodedBufferSegment *buf_list, *
buf;
524 if (vas != VA_STATUS_SUCCESS) {
526 "%d (%s).\n", vas, vaErrorStr(vas));
533 "(status %08x).\n",
buf->size,
buf->status);
548 if (vas != VA_STATUS_SUCCESS) {
550 "%d (%s).\n", vas, vaErrorStr(vas));
577 "%"PRId64
"/%"PRId64
".\n",
596 if (
ctx->codec->picture_priv_data_size > 0) {
646 int is_ref,
int in_dpb,
int prev)
719 if (current_depth ==
ctx->max_b_depth ||
start->next->next ==
end) {
720 for (pic =
start->next; pic; pic = pic->
next) {
741 for (pic =
start->next,
i = 1; 2 * i < len; pic = pic->next,
i++);
758 current_depth + 1, &next);
763 current_depth + 1, last);
772 int i, b_counter, closed_gop_end;
777 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
792 "encode next.\n", pic->
b_depth);
801 closed_gop_end =
ctx->closed_gop ||
802 ctx->idr_counter ==
ctx->gop_per_idr;
803 for (pic =
ctx->pic_start; pic; pic = next) {
813 if (b_counter ==
ctx->b_per_p)
817 if (
ctx->gop_counter + b_counter + closed_gop_end >=
ctx->gop_size)
821 if (next && next->force_idr)
827 if (!pic &&
ctx->end_of_stream) {
836 "need more input for reference pictures.\n");
839 if (
ctx->input_order <=
ctx->decode_delay && !
ctx->end_of_stream) {
841 "need more input for timestamps.\n");
849 ctx->idr_counter = 1;
850 ctx->gop_counter = 1;
852 }
else if (
ctx->gop_counter + b_counter >=
ctx->gop_size) {
853 if (
ctx->idr_counter ==
ctx->gop_per_idr) {
857 ctx->idr_counter = 1;
864 ctx->gop_counter = 1;
867 if (
ctx->gop_counter + b_counter + closed_gop_end ==
ctx->gop_size) {
876 ctx->gop_counter += 1 + b_counter;
889 --
ctx->next_prev->ref_count[0];
895 ctx->next_prev = pic;
897 ++
ctx->next_prev->ref_count[0];
909 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
915 for (pic =
ctx->pic_start; pic; pic = pic->
next) {
922 for (pic =
ctx->pic_start; pic; pic = next) {
929 ctx->pic_start = next;
945 frame->crop_left ||
frame->crop_right) && !
ctx->crop_warned) {
947 "frames ignored due to lack of API support.\n");
948 ctx->crop_warned = 1;
981 if (
ctx->input_order == 0)
987 if (
ctx->input_order == 0)
988 ctx->first_pts = pic->
pts;
989 if (
ctx->input_order ==
ctx->decode_delay)
990 ctx->dts_pts_diff = pic->
pts -
ctx->first_pts;
991 if (
ctx->output_delay > 0)
992 ctx->ts_ring[
ctx->input_order % (3 *
ctx->output_delay)] = pic->
pts;
997 if (
ctx->pic_start) {
998 ctx->pic_end->next = pic;
1001 ctx->pic_start = pic;
1006 ctx->end_of_stream = 1;
1010 if (
ctx->input_order <
ctx->decode_delay)
1011 ctx->dts_pts_diff =
ctx->pic_end->pts -
ctx->first_pts;
1026 if (!
ctx->pic_start) {
1027 if (
ctx->end_of_stream)
1053 if (
ctx->output_delay == 0) {
1062 (3 *
ctx->output_delay)];
1081 ctx->global_params_type[
ctx->nb_global_params] =
type;
1083 ctx->global_params_size[
ctx->nb_global_params] =
size;
1085 ++
ctx->nb_global_params;
1098 {
"YUV400", VA_RT_FORMAT_YUV400, 8, 1, },
1099 {
"YUV420", VA_RT_FORMAT_YUV420, 8, 3, 1, 1 },
1100 {
"YUV422", VA_RT_FORMAT_YUV422, 8, 3, 1, 0 },
1101 {
"YUV444", VA_RT_FORMAT_YUV444, 8, 3, 0, 0 },
1102 {
"YUV411", VA_RT_FORMAT_YUV411, 8, 3, 2, 0 },
1103 #if VA_CHECK_VERSION(0, 38, 1)
1104 {
"YUV420_10", VA_RT_FORMAT_YUV420_10BPP, 10, 3, 1, 1 },
1109 VAEntrypointEncSlice,
1110 VAEntrypointEncPicture,
1111 #if VA_CHECK_VERSION(0, 39, 2)
1112 VAEntrypointEncSliceLP,
1116 #if VA_CHECK_VERSION(0, 39, 2)
1117 static const VAEntrypoint vaapi_encode_entrypoints_low_power[] = {
1118 VAEntrypointEncSliceLP,
1126 VAProfile *va_profiles =
NULL;
1127 VAEntrypoint *va_entrypoints =
NULL;
1129 const VAEntrypoint *usable_entrypoints;
1132 VAConfigAttrib rt_format_attr;
1134 const char *profile_string, *entrypoint_string;
1135 int i, j,
n, depth, err;
1138 if (
ctx->low_power) {
1139 #if VA_CHECK_VERSION(0, 39, 2)
1140 usable_entrypoints = vaapi_encode_entrypoints_low_power;
1143 "supported with this VAAPI version.\n");
1153 ctx->input_frames->sw_format);
1156 depth =
desc->comp[0].depth;
1157 for (
i = 1;
i <
desc->nb_components;
i++) {
1158 if (
desc->comp[
i].depth != depth) {
1167 n = vaMaxNumProfiles(
ctx->hwctx->display);
1173 vas = vaQueryConfigProfiles(
ctx->hwctx->display, va_profiles, &
n);
1174 if (vas != VA_STATUS_SUCCESS) {
1176 vas, vaErrorStr(vas));
1182 for (
i = 0; (
ctx->codec->profiles[
i].av_profile !=
1185 if (depth !=
profile->depth ||
1188 if (
desc->nb_components > 1 &&
1196 #if VA_CHECK_VERSION(1, 0, 0)
1197 profile_string = vaProfileStr(
profile->va_profile);
1199 profile_string =
"(no profile names)";
1202 for (j = 0; j <
n; j++) {
1203 if (va_profiles[j] ==
profile->va_profile)
1208 "is not supported by driver.\n", profile_string,
1216 if (!
ctx->profile) {
1225 profile_string,
ctx->va_profile);
1227 n = vaMaxNumEntrypoints(
ctx->hwctx->display);
1229 if (!va_entrypoints) {
1233 vas = vaQueryConfigEntrypoints(
ctx->hwctx->display,
ctx->va_profile,
1234 va_entrypoints, &
n);
1235 if (vas != VA_STATUS_SUCCESS) {
1237 "profile %s (%d): %d (%s).\n", profile_string,
1238 ctx->va_profile, vas, vaErrorStr(vas));
1243 for (
i = 0;
i <
n;
i++) {
1244 for (j = 0; usable_entrypoints[j]; j++) {
1245 if (va_entrypoints[
i] == usable_entrypoints[j])
1248 if (usable_entrypoints[j])
1253 "for profile %s (%d).\n", profile_string,
ctx->va_profile);
1258 ctx->va_entrypoint = va_entrypoints[
i];
1259 #if VA_CHECK_VERSION(1, 0, 0)
1260 entrypoint_string = vaEntrypointStr(
ctx->va_entrypoint);
1262 entrypoint_string =
"(no entrypoint names)";
1265 entrypoint_string,
ctx->va_entrypoint);
1269 if (rt_format->
depth == depth &&
1277 "found for profile %s (%d) entrypoint %s (%d).\n",
1278 profile_string,
ctx->va_profile,
1279 entrypoint_string,
ctx->va_entrypoint);
1284 rt_format_attr = (VAConfigAttrib) { VAConfigAttribRTFormat };
1285 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1286 ctx->va_profile,
ctx->va_entrypoint,
1287 &rt_format_attr, 1);
1288 if (vas != VA_STATUS_SUCCESS) {
1290 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1295 if (rt_format_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1297 "supported by driver: assuming surface RT format %s "
1298 "is valid.\n", rt_format->
name);
1299 }
else if (!(rt_format_attr.value & rt_format->
value)) {
1301 "by driver for encoding profile %s (%d) entrypoint %s (%d).\n",
1302 rt_format->
name, profile_string,
ctx->va_profile,
1303 entrypoint_string,
ctx->va_entrypoint);
1308 "format %s (%#x).\n", rt_format->
name, rt_format->
value);
1309 ctx->config_attributes[
ctx->nb_config_attributes++] =
1311 .type = VAConfigAttribRTFormat,
1312 .value = rt_format->
value,
1330 #if VA_CHECK_VERSION(1, 1, 0)
1335 #if VA_CHECK_VERSION(1, 3, 0)
1347 uint32_t supported_va_rc_modes;
1349 int64_t rc_bits_per_second;
1350 int rc_target_percentage;
1353 int64_t hrd_buffer_size;
1354 int64_t hrd_initial_buffer_fullness;
1356 VAConfigAttrib rc_attr = { VAConfigAttribRateControl };
1358 char supported_rc_modes_string[64];
1360 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1361 ctx->va_profile,
ctx->va_entrypoint,
1363 if (vas != VA_STATUS_SUCCESS) {
1365 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1368 if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1370 "supported rate control modes: assuming CQP only.\n");
1371 supported_va_rc_modes = VA_RC_CQP;
1372 strcpy(supported_rc_modes_string,
"unknown");
1374 char *str = supported_rc_modes_string;
1375 size_t len =
sizeof(supported_rc_modes_string);
1378 supported_va_rc_modes = rc_attr.value;
1381 if (supported_va_rc_modes &
rc_mode->va_mode) {
1397 supported_rc_modes_string);
1412 #define TRY_RC_MODE(mode, fail) do { \
1413 rc_mode = &vaapi_encode_rc_modes[mode]; \
1414 if (!(rc_mode->va_mode & supported_va_rc_modes)) { \
1416 av_log(avctx, AV_LOG_ERROR, "Driver does not support %s " \
1417 "RC mode (supported modes: %s).\n", rc_mode->name, \
1418 supported_rc_modes_string); \
1419 return AVERROR(EINVAL); \
1421 av_log(avctx, AV_LOG_DEBUG, "Driver does not support %s " \
1422 "RC mode.\n", rc_mode->name); \
1425 goto rc_mode_found; \
1429 if (
ctx->explicit_rc_mode)
1432 if (
ctx->explicit_qp)
1462 "RC mode compatible with selected options "
1463 "(supported modes: %s).\n", supported_rc_modes_string);
1480 rc_bits_per_second = avctx->
bit_rate;
1486 rc_target_percentage = 100;
1493 }
else if (
rc_mode->maxrate) {
1497 "bitrate (%"PRId64
") must not be greater than "
1498 "maxrate (%"PRId64
").\n", avctx->
bit_rate,
1503 rc_target_percentage = (avctx->
bit_rate * 100) /
1510 rc_bits_per_second = 2 * avctx->
bit_rate;
1511 rc_target_percentage = 50;
1516 "in %s RC mode.\n",
rc_mode->name);
1518 rc_bits_per_second = avctx->
bit_rate;
1519 rc_target_percentage = 100;
1522 rc_bits_per_second = 0;
1523 rc_target_percentage = 100;
1527 if (
ctx->explicit_qp) {
1528 rc_quality =
ctx->explicit_qp;
1532 rc_quality =
ctx->codec->default_quality;
1534 "using default (%d).\n", rc_quality);
1550 "must have initial buffer size (%d) <= "
1551 "buffer size (%"PRId64
").\n",
1557 hrd_initial_buffer_fullness = hrd_buffer_size * 3 / 4;
1560 rc_window_size = (hrd_buffer_size * 1000) / rc_bits_per_second;
1564 "in %s RC mode.\n",
rc_mode->name);
1567 hrd_buffer_size = 0;
1568 hrd_initial_buffer_fullness = 0;
1572 rc_window_size = 1000;
1576 if (rc_bits_per_second > UINT32_MAX ||
1577 hrd_buffer_size > UINT32_MAX ||
1578 hrd_initial_buffer_fullness > UINT32_MAX) {
1580 "greater are not supported by VAAPI.\n");
1585 ctx->rc_quality = rc_quality;
1587 ctx->va_bit_rate = rc_bits_per_second;
1590 if (rc_attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1593 ctx->config_attributes[
ctx->nb_config_attributes++] =
1595 .type = VAConfigAttribRateControl,
1596 .value =
ctx->va_rc_mode,
1603 if (
rc_mode->va_mode != VA_RC_CQP) {
1606 "converging in %d frames with %d%% accuracy.\n",
1607 rc_bits_per_second, rc_window_size,
1608 rc_target_percentage);
1609 }
else if (
rc_mode->bitrate) {
1611 "%"PRId64
" bps over %d ms.\n", rc_target_percentage,
1612 rc_bits_per_second, rc_window_size);
1615 ctx->rc_params = (VAEncMiscParameterRateControl) {
1616 .bits_per_second = rc_bits_per_second,
1617 .target_percentage = rc_target_percentage,
1618 .window_size = rc_window_size,
1620 .min_qp = (avctx->
qmin > 0 ? avctx->
qmin : 0),
1621 .basic_unit_size = 0,
1622 #
if VA_CHECK_VERSION(1, 1, 0)
1623 .ICQ_quality_factor = av_clip(rc_quality, 1, 51),
1624 .max_qp = (avctx->
qmax > 0 ? avctx->
qmax : 0),
1626 #
if VA_CHECK_VERSION(1, 3, 0)
1627 .quality_factor = rc_quality,
1631 VAEncMiscParameterTypeRateControl,
1633 sizeof(
ctx->rc_params));
1638 "initial fullness %"PRId64
" bits.\n",
1639 hrd_buffer_size, hrd_initial_buffer_fullness);
1641 ctx->hrd_params = (VAEncMiscParameterHRD) {
1642 .initial_buffer_fullness = hrd_initial_buffer_fullness,
1643 .buffer_size = hrd_buffer_size,
1646 VAEncMiscParameterTypeHRD,
1648 sizeof(
ctx->hrd_params));
1659 fr_num, fr_den, (
double)fr_num / fr_den);
1661 ctx->fr_params = (VAEncMiscParameterFrameRate) {
1662 .framerate = (
unsigned int)fr_den << 16 | fr_num,
1664 #if VA_CHECK_VERSION(0, 40, 0)
1666 VAEncMiscParameterTypeFrameRate,
1668 sizeof(
ctx->fr_params));
1678 VAConfigAttrib attr = { VAConfigAttribEncMaxRefFrames };
1679 uint32_t ref_l0, ref_l1;
1681 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1685 if (vas != VA_STATUS_SUCCESS) {
1687 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1691 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1692 ref_l0 = ref_l1 = 0;
1694 ref_l0 = attr.value & 0xffff;
1695 ref_l1 = attr.value >> 16 & 0xffff;
1702 }
else if (ref_l0 < 1) {
1704 "reference frames.\n");
1707 ref_l1 < 1 || avctx->max_b_frames < 1) {
1709 "(supported references: %d / %d).\n", ref_l0, ref_l1);
1711 ctx->p_per_i = INT_MAX;
1715 "(supported references: %d / %d).\n", ref_l0, ref_l1);
1717 ctx->p_per_i = INT_MAX;
1723 ctx->max_b_depth = 1;
1729 ctx->gop_per_idr =
ctx->idr_interval + 1;
1731 ctx->closed_gop = 1;
1732 ctx->gop_per_idr = 1;
1741 VAConfigAttrib attr[2] = { { VAConfigAttribEncMaxSlices },
1742 { VAConfigAttribEncSliceStructure } };
1744 uint32_t max_slices, slice_structure;
1750 "but this codec does not support controlling slices.\n");
1755 ctx->slice_block_rows = (avctx->
height +
ctx->slice_block_height - 1) /
1756 ctx->slice_block_height;
1757 ctx->slice_block_cols = (avctx->
width +
ctx->slice_block_width - 1) /
1758 ctx->slice_block_width;
1760 if (avctx->
slices <= 1) {
1762 ctx->slice_size =
ctx->slice_block_rows;
1766 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1770 if (vas != VA_STATUS_SUCCESS) {
1772 "attributes: %d (%s).\n", vas, vaErrorStr(vas));
1775 max_slices = attr[0].value;
1776 slice_structure = attr[1].value;
1777 if (max_slices == VA_ATTRIB_NOT_SUPPORTED ||
1778 slice_structure == VA_ATTRIB_NOT_SUPPORTED) {
1780 "pictures as multiple slices.\n.");
1789 if (avctx->
slices >
ctx->slice_block_rows) {
1791 "configured number of slices (%d < %d); using "
1792 "maximum.\n",
ctx->slice_block_rows, avctx->
slices);
1793 req_slices =
ctx->slice_block_rows;
1795 req_slices = avctx->
slices;
1797 if (slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS ||
1798 slice_structure & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS) {
1799 ctx->nb_slices = req_slices;
1800 ctx->slice_size =
ctx->slice_block_rows /
ctx->nb_slices;
1801 }
else if (slice_structure & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS) {
1803 for (k = 1;; k *= 2) {
1804 if (2 * k * (req_slices - 1) + 1 >=
ctx->slice_block_rows)
1807 ctx->nb_slices = (
ctx->slice_block_rows + k - 1) / k;
1808 ctx->slice_size = k;
1809 #if VA_CHECK_VERSION(1, 0, 0)
1810 }
else if (slice_structure & VA_ENC_SLICE_STRUCTURE_EQUAL_ROWS) {
1811 ctx->nb_slices =
ctx->slice_block_rows;
1812 ctx->slice_size = 1;
1816 "slice structure modes (%#x).\n", slice_structure);
1822 "%d (from %d) due to driver constraints on slice "
1823 "structure.\n",
ctx->nb_slices, avctx->
slices);
1825 if (
ctx->nb_slices > max_slices) {
1827 "encoding with %d slices (max %"PRIu32
").\n",
1828 ctx->nb_slices, max_slices);
1833 "(default size %d block rows).\n",
1834 ctx->nb_slices,
ctx->slice_size);
1842 VAConfigAttrib attr = { VAConfigAttribEncPackedHeaders };
1844 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1848 if (vas != VA_STATUS_SUCCESS) {
1850 "attribute: %d (%s).\n", vas, vaErrorStr(vas));
1854 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1855 if (
ctx->desired_packed_headers) {
1857 "packed headers (wanted %#x).\n",
1858 ctx->desired_packed_headers);
1861 "packed headers (none wanted).\n");
1863 ctx->va_packed_headers = 0;
1865 if (
ctx->desired_packed_headers & ~attr.value) {
1867 "wanted packed headers (wanted %#x, found %#x).\n",
1868 ctx->desired_packed_headers, attr.value);
1871 "available (wanted %#x, found %#x).\n",
1872 ctx->desired_packed_headers, attr.value);
1874 ctx->va_packed_headers =
ctx->desired_packed_headers & attr.value;
1877 if (
ctx->va_packed_headers) {
1878 ctx->config_attributes[
ctx->nb_config_attributes++] =
1880 .type = VAConfigAttribEncPackedHeaders,
1881 .value =
ctx->va_packed_headers,
1885 if ( (
ctx->desired_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1886 !(
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE) &&
1889 "sequence headers, but a global header is requested.\n");
1891 "this may result in a stream which is not usable for some "
1892 "purposes (e.g. not muxable to some containers).\n");
1900 #if VA_CHECK_VERSION(0, 36, 0)
1903 VAConfigAttrib attr = { VAConfigAttribEncQualityRange };
1906 vas = vaGetConfigAttributes(
ctx->hwctx->display,
1910 if (vas != VA_STATUS_SUCCESS) {
1912 "config attribute: %d (%s).\n", vas, vaErrorStr(vas));
1916 if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
1919 "supported: will use default quality level.\n");
1924 "valid range is 0-%d, using %d.\n",
1925 attr.value, attr.value);
1929 ctx->quality_params = (VAEncMiscParameterBufferQualityLevel) {
1933 VAEncMiscParameterTypeQualityLevel,
1934 &
ctx->quality_params,
1935 sizeof(
ctx->quality_params));
1939 "not supported with this VAAPI version.\n");
1950 VABufferID buffer_id;
1952 buffer_id = (VABufferID)(uintptr_t)
data;
1954 vaDestroyBuffer(
ctx->hwctx->display, buffer_id);
1964 VABufferID buffer_id;
1972 vas = vaCreateBuffer(
ctx->hwctx->display,
ctx->va_context,
1973 VAEncCodedBufferType,
1974 3 *
ctx->surface_width *
ctx->surface_height +
1975 (1 << 16), 1, 0, &buffer_id);
1976 if (vas != VA_STATUS_SUCCESS) {
1978 "output buffer: %d (%s).\n", vas, vaErrorStr(vas));
1989 vaDestroyBuffer(
ctx->hwctx->display, buffer_id);
2024 if (
ctx->input_frames->sw_format ==
2026 recon_format =
ctx->input_frames->sw_format;
2037 recon_format =
ctx->input_frames->sw_format;
2047 "size %dx%d (constraints: width %d-%d height %d-%d).\n",
2048 ctx->surface_width,
ctx->surface_height,
2059 if (!
ctx->recon_frames_ref) {
2066 ctx->recon_frames->sw_format = recon_format;
2067 ctx->recon_frames->width =
ctx->surface_width;
2068 ctx->recon_frames->height =
ctx->surface_height;
2073 "frame context: %d.\n", err);
2093 "required to associate the encoding device.\n");
2097 ctx->va_config = VA_INVALID_ID;
2098 ctx->va_context = VA_INVALID_ID;
2101 if (!
ctx->input_frames_ref) {
2108 if (!
ctx->device_ref) {
2113 ctx->hwctx =
ctx->device->hwctx;
2141 vas = vaCreateConfig(
ctx->hwctx->display,
2142 ctx->va_profile,
ctx->va_entrypoint,
2143 ctx->config_attributes,
ctx->nb_config_attributes,
2145 if (vas != VA_STATUS_SUCCESS) {
2147 "configuration: %d (%s).\n", vas, vaErrorStr(vas));
2156 recon_hwctx =
ctx->recon_frames->hwctx;
2157 vas = vaCreateContext(
ctx->hwctx->display,
ctx->va_config,
2158 ctx->surface_width,
ctx->surface_height,
2163 if (vas != VA_STATUS_SUCCESS) {
2165 "context: %d (%s).\n", vas, vaErrorStr(vas));
2170 ctx->output_buffer_pool =
2173 if (!
ctx->output_buffer_pool) {
2178 if (
ctx->codec->configure) {
2179 err =
ctx->codec->configure(avctx);
2184 ctx->output_delay =
ctx->b_per_p;
2185 ctx->decode_delay =
ctx->max_b_depth;
2187 if (
ctx->codec->sequence_params_size > 0) {
2188 ctx->codec_sequence_params =
2190 if (!
ctx->codec_sequence_params) {
2195 if (
ctx->codec->picture_params_size > 0) {
2196 ctx->codec_picture_params =
2198 if (!
ctx->codec_picture_params) {
2204 if (
ctx->codec->init_sequence_params) {
2205 err =
ctx->codec->init_sequence_params(avctx);
2208 "failed: %d.\n", err);
2213 if (
ctx->va_packed_headers & VA_ENC_PACKED_HEADER_SEQUENCE &&
2214 ctx->codec->write_sequence_header &&
2217 size_t bit_len = 8 *
sizeof(
data);
2219 err =
ctx->codec->write_sequence_header(avctx,
data, &bit_len);
2222 "for extradata: %d.\n", err);
2248 for (pic =
ctx->pic_start; pic; pic = next) {
2255 if (
ctx->va_context != VA_INVALID_ID) {
2256 vaDestroyContext(
ctx->hwctx->display,
ctx->va_context);
2257 ctx->va_context = VA_INVALID_ID;
2260 if (
ctx->va_config != VA_INVALID_ID) {
2261 vaDestroyConfig(
ctx->hwctx->display,
ctx->va_config);
2262 ctx->va_config = VA_INVALID_ID;