1 /*
2 * This file is part of FFmpeg.
3 *
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18
19 #include <string.h>
20
21 #include <va/va.h>
22 #include <va/va_enc_hevc.h>
23
30
40
42
43 enum {
47 };
48
51
53
58
61
62 // Encoder features.
64 // Block size info.
68
69 // User options.
75
76 // Derived settings.
79
80 // Writer structures.
85
90
96
97
99 char *
data,
size_t *data_len,
101 {
103 int err;
104
105 err = ff_cbs_write_fragment_data(priv->
cbc, au);
106 if (err < 0) {
108 return err;
109 }
110
113 "%zu < %zu.\n", *data_len,
116 }
117
120
121 return 0;
122 }
123
126 void *nal_unit)
127 {
129 int err;
130
131 err = ff_cbs_insert_unit_content(au, -1,
133 if (err < 0) {
135 "type = %d.\n",
header->nal_unit_type);
136 return err;
137 }
138
139 return 0;
140 }
141
143 char *
data,
size_t *data_len)
144 {
147 int err;
148
151 if (err < 0)
154 }
155
157 if (err < 0)
159
161 if (err < 0)
163
165 if (err < 0)
167
170 ff_cbs_fragment_reset(au);
171 return err;
172 }
173
177 char *
data,
size_t *data_len)
178 {
181 int err;
182
185 if (err < 0)
188 }
189
191 if (err < 0)
193
196 ff_cbs_fragment_reset(au);
197 return err;
198 }
199
203 char *
data,
size_t *data_len)
204 {
207 int err;
208
212 if (err < 0)
215 }
216
221 if (err < 0)
223 }
224
229 if (err < 0)
231 }
236 if (err < 0)
238 }
239
241
243 if (err < 0)
245
246 ff_cbs_fragment_reset(au);
247
248 *
type = VAEncPackedHeaderRawData;
249 return 0;
250 } else {
252 }
253
255 ff_cbs_fragment_reset(au);
256 return err;
257 }
258
260 {
267 VAEncSequenceParameterBufferHEVC *vseq =
ctx->codec_sequence_params;
268 VAEncPictureParameterBufferHEVC *vpic =
ctx->codec_picture_params;
270
271 // priv->unit_opts.tier already set
272 // priv->unit_opts.fixed_qp_idr already set
283
286 if (err < 0)
287 return err;
288
289 #if VA_CHECK_VERSION(1, 13, 0)
290 // update sps setting according to queried result
292 VAConfigAttribValEncHEVCFeatures features = { .value = priv->
va_features };
293
294 // Enable feature if get queried result is VA_FEATURE_SUPPORTED | VA_FEATURE_REQUIRED
295 sps->amp_enabled_flag =
296 !!features.bits.amp;
297 sps->sample_adaptive_offset_enabled_flag =
298 !!features.bits.sao;
299 sps->sps_temporal_mvp_enabled_flag =
300 !!features.bits.temporal_mvp;
301 sps->pcm_enabled_flag =
302 !!features.bits.pcm;
303 }
304
306 VAConfigAttribValEncHEVCBlockSizes bs = { .value = priv->
va_bs };
307 sps->log2_min_luma_coding_block_size_minus3 =
309 sps->log2_diff_max_min_luma_coding_block_size =
311
312 sps->log2_min_luma_transform_block_size_minus2 =
313 bs.bits.log2_min_luma_transform_block_size_minus2;
314 sps->log2_diff_max_min_luma_transform_block_size =
315 bs.bits.log2_max_luma_transform_block_size_minus2 -
316 bs.bits.log2_min_luma_transform_block_size_minus2;
317
318 sps->max_transform_hierarchy_depth_inter =
319 bs.bits.max_max_transform_hierarchy_depth_inter;
320 sps->max_transform_hierarchy_depth_intra =
321 bs.bits.max_max_transform_hierarchy_depth_intra;
322 }
323
324 // update pps setting according to queried result
326 VAConfigAttribValEncHEVCFeatures features = { .value = priv->
va_features };
327 if (
ctx->va_rc_mode != VA_RC_CQP)
328 pps->cu_qp_delta_enabled_flag =
329 !!features.bits.cu_qp_delta;
330
331 pps->transform_skip_enabled_flag =
332 !!features.bits.transform_skip;
333 // set diff_cu_qp_delta_depth as its max value if cu_qp_delta enabled. Otherwise
334 // 0 will make cu_qp_delta invalid.
335 if (
pps->cu_qp_delta_enabled_flag)
336 pps->diff_cu_qp_delta_depth =
sps->log2_diff_max_min_luma_coding_block_size;
337 }
338 #endif
339
340 // Fill VAAPI parameter buffers.
341
342 *vseq = (VAEncSequenceParameterBufferHEVC) {
343 .general_profile_idc =
vps->profile_tier_level.general_profile_idc,
344 .general_level_idc =
vps->profile_tier_level.general_level_idc,
345 .general_tier_flag =
vps->profile_tier_level.general_tier_flag,
346
348 .intra_idr_period = base_ctx->
gop_size,
349 .ip_period = base_ctx->
b_per_p + 1,
350 .bits_per_second =
ctx->va_bit_rate,
351
352 .pic_width_in_luma_samples =
sps->pic_width_in_luma_samples,
353 .pic_height_in_luma_samples =
sps->pic_height_in_luma_samples,
354
355 .seq_fields.bits = {
356 .chroma_format_idc =
sps->chroma_format_idc,
357 .separate_colour_plane_flag =
sps->separate_colour_plane_flag,
358 .bit_depth_luma_minus8 =
sps->bit_depth_luma_minus8,
359 .bit_depth_chroma_minus8 =
sps->bit_depth_chroma_minus8,
360 .scaling_list_enabled_flag =
sps->scaling_list_enabled_flag,
361 .strong_intra_smoothing_enabled_flag =
362 sps->strong_intra_smoothing_enabled_flag,
363 .amp_enabled_flag =
sps->amp_enabled_flag,
364 .sample_adaptive_offset_enabled_flag =
365 sps->sample_adaptive_offset_enabled_flag,
366 .pcm_enabled_flag =
sps->pcm_enabled_flag,
367 .pcm_loop_filter_disabled_flag =
sps->pcm_loop_filter_disabled_flag,
368 .sps_temporal_mvp_enabled_flag =
sps->sps_temporal_mvp_enabled_flag,
369 },
370
371 .log2_min_luma_coding_block_size_minus3 =
372 sps->log2_min_luma_coding_block_size_minus3,
373 .log2_diff_max_min_luma_coding_block_size =
374 sps->log2_diff_max_min_luma_coding_block_size,
375 .log2_min_transform_block_size_minus2 =
376 sps->log2_min_luma_transform_block_size_minus2,
377 .log2_diff_max_min_transform_block_size =
378 sps->log2_diff_max_min_luma_transform_block_size,
379 .max_transform_hierarchy_depth_inter =
380 sps->max_transform_hierarchy_depth_inter,
381 .max_transform_hierarchy_depth_intra =
382 sps->max_transform_hierarchy_depth_intra,
383
384 .pcm_sample_bit_depth_luma_minus1 =
385 sps->pcm_sample_bit_depth_luma_minus1,
386 .pcm_sample_bit_depth_chroma_minus1 =
387 sps->pcm_sample_bit_depth_chroma_minus1,
388 .log2_min_pcm_luma_coding_block_size_minus3 =
389 sps->log2_min_pcm_luma_coding_block_size_minus3,
390 .log2_max_pcm_luma_coding_block_size_minus3 =
391 sps->log2_min_pcm_luma_coding_block_size_minus3 +
392 sps->log2_diff_max_min_pcm_luma_coding_block_size,
393
394 .vui_parameters_present_flag = 0,
395 };
396
397 *vpic = (VAEncPictureParameterBufferHEVC) {
398 .decoded_curr_pic = {
399 .picture_id = VA_INVALID_ID,
400 .flags = VA_PICTURE_HEVC_INVALID,
401 },
402
403 .coded_buf = VA_INVALID_ID,
404
405 .collocated_ref_pic_index =
sps->sps_temporal_mvp_enabled_flag ?
406 0 : 0xff,
407 .last_picture = 0,
408
409 .pic_init_qp =
pps->init_qp_minus26 + 26,
410 .diff_cu_qp_delta_depth =
pps->diff_cu_qp_delta_depth,
411 .pps_cb_qp_offset =
pps->pps_cb_qp_offset,
412 .pps_cr_qp_offset =
pps->pps_cr_qp_offset,
413
414 .num_tile_columns_minus1 =
pps->num_tile_columns_minus1,
415 .num_tile_rows_minus1 =
pps->num_tile_rows_minus1,
416
417 .log2_parallel_merge_level_minus2 =
pps->log2_parallel_merge_level_minus2,
418 .ctu_max_bitsize_allowed = 0,
419
420 .num_ref_idx_l0_default_active_minus1 =
421 pps->num_ref_idx_l0_default_active_minus1,
422 .num_ref_idx_l1_default_active_minus1 =
423 pps->num_ref_idx_l1_default_active_minus1,
424
425 .slice_pic_parameter_set_id =
pps->pps_pic_parameter_set_id,
426
427 .pic_fields.bits = {
428 .sign_data_hiding_enabled_flag =
pps->sign_data_hiding_enabled_flag,
429 .constrained_intra_pred_flag =
pps->constrained_intra_pred_flag,
430 .transform_skip_enabled_flag =
pps->transform_skip_enabled_flag,
431 .cu_qp_delta_enabled_flag =
pps->cu_qp_delta_enabled_flag,
432 .weighted_pred_flag =
pps->weighted_pred_flag,
433 .weighted_bipred_flag =
pps->weighted_bipred_flag,
434 .transquant_bypass_enabled_flag =
pps->transquant_bypass_enabled_flag,
435 .tiles_enabled_flag =
pps->tiles_enabled_flag,
436 .entropy_coding_sync_enabled_flag =
pps->entropy_coding_sync_enabled_flag,
437 .loop_filter_across_tiles_enabled_flag =
438 pps->loop_filter_across_tiles_enabled_flag,
439 .pps_loop_filter_across_slices_enabled_flag =
440 pps->pps_loop_filter_across_slices_enabled_flag,
441 .scaling_list_data_present_flag = (
sps->sps_scaling_list_data_present_flag |
442 pps->pps_scaling_list_data_present_flag),
443 .screen_content_flag = 0,
444 .enable_gpu_weighted_prediction = 0,
445 .no_output_of_prior_pics_flag = 0,
446 },
447 };
448
449 if (
pps->tiles_enabled_flag) {
450 for (
i = 0;
i <= vpic->num_tile_rows_minus1;
i++)
451 vpic->row_height_minus1[
i] =
pps->row_height_minus1[
i];
452 for (
i = 0;
i <= vpic->num_tile_columns_minus1;
i++)
453 vpic->column_width_minus1[
i] =
pps->column_width_minus1[
i];
454 }
455
456 return 0;
457 }
458
461 {
470
473
475
479 } else {
482
492 } else {
495 for (irap_ref = pic; irap_ref; irap_ref = irap_ref->
refs[1][0]) {
497 break;
498 }
502 } else {
505 }
508 }
509 }
511
517 .nuh_layer_id = 0,
518 .nuh_temporal_id_plus1 = 1,
519 },
521 };
522 } else {
524 }
525
527
528 // Only look for the metadata on I/IDR frame on the output. We
529 // may force an IDR frame on the output where the metadata gets
530 // changed on the input frame.
536
537 if (sd) {
540
541 // SEI is needed when both the primaries and luminance are set
545 const int mapping[3] = {1, 2, 0};
546 const int chroma_den = 50000;
547 const int luma_den = 10000;
548
549 for (
i = 0;
i < 3;
i++) {
550 const int j = mapping[
i];
554 chroma_den);
558 chroma_den);
559 }
560
563 chroma_den);
566 chroma_den);
567
573
575 }
576 }
577 }
578
584
585 if (sd) {
590
592 clli->max_pic_average_light_level =
FFMIN(clm->
MaxFALL, 65535);
593
595 }
596 }
597
599 int err;
600 size_t sei_a53cc_len;
603 if (err < 0)
604 return err;
609
611 }
612 }
613
614 vpic->decoded_curr_pic = (VAPictureHEVC) {
617 .flags = 0,
618 };
619
624
626 href =
ref->codec_priv;
627
628 vpic->reference_frames[j++] = (VAPictureHEVC) {
632 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE : 0) |
634 VA_PICTURE_HEVC_RPS_ST_CURR_AFTER : 0),
635 };
636 }
637 }
638
640 vpic->reference_frames[j] = (VAPictureHEVC) {
641 .picture_id = VA_INVALID_ID,
642 .flags = VA_PICTURE_HEVC_INVALID,
643 };
644 }
645
647
649
650 vpic->pic_fields.bits.reference_pic_flag = pic->
is_reference;
653 vpic->pic_fields.bits.idr_pic_flag = 1;
654 vpic->pic_fields.bits.coding_type = 1;
655 break;
657 vpic->pic_fields.bits.idr_pic_flag = 0;
658 vpic->pic_fields.bits.coding_type = 1;
659 break;
661 vpic->pic_fields.bits.idr_pic_flag = 0;
662 vpic->pic_fields.bits.coding_type = 2;
663 break;
665 vpic->pic_fields.bits.idr_pic_flag = 0;
666 vpic->pic_fields.bits.coding_type = 3;
667 break;
668 default:
670 }
671
672 return 0;
673 }
674
678 {
689
692 .nuh_layer_id = 0,
693 .nuh_temporal_id_plus1 = 1,
694 };
695
697
700
702
705
707 (1 << (
sps->log2_max_pic_order_cnt_lsb_minus4 + 4)) - 1;
708
714 int i, j, poc, rps_pics;
715
717
719 memset(rps, 0, sizeof(*rps));
720
721 rps_pics = 0;
723 for (j = 0; j < pic->
nb_refs[
i]; j++) {
726 rps_used[rps_pics] = 1;
727 ++rps_pics;
728 }
729 }
730
732 if (pic->
dpb[
i] == pic)
733 continue;
734
735 for (j = 0; j < pic->
nb_refs[0]; j++) {
737 break;
738 }
739 if (j < pic->nb_refs[0])
740 continue;
741
742 for (j = 0; j < pic->
nb_refs[1]; j++) {
744 break;
745 }
746 if (j < pic->nb_refs[1])
747 continue;
748
751 rps_used[rps_pics] = 0;
752 ++rps_pics;
753 }
754
755 for (
i = 1;
i < rps_pics;
i++) {
756 for (j =
i; j > 0; j--) {
757 if (rps_poc[j] > rps_poc[j - 1])
758 break;
760 FFSWAP(
int, rps_poc[j], rps_poc[j - 1]);
761 FFSWAP(
int, rps_used[j], rps_used[j - 1]);
762 }
763 }
764
767 for (
i = 0;
i < rps_pics;
i++) {
769 rps_poc[
i], rps_used[
i]);
770 }
772
773 for (
i = 0;
i < rps_pics;
i++) {
776 break;
777 }
778
781 for (j =
i - 1; j >= 0; j--) {
784 poc = rps_poc[j];
785 }
786
789 for (j =
i; j < rps_pics; j++) {
792 poc = rps_poc[j];
793 }
794
797
798 // when this flag is not present, it is inerred to 1.
801 sps->sps_temporal_mvp_enabled_flag;
806 }
807
811 }
812
814 sps->sample_adaptive_offset_enabled_flag;
815
820 else
822
823
824 *vslice = (VAEncSliceParameterBufferHEVC) {
827
830
833
836
838
842
845
846 .slice_fields.bits = {
847 .last_slice_of_pic_flag = slice->
index == vaapi_pic->
nb_slices - 1,
850 .slice_temporal_mvp_enabled_flag =
854 .num_ref_idx_active_override_flag =
858 .slice_deblocking_filter_disabled_flag =
860 .slice_loop_filter_across_slices_enabled_flag =
863 },
864 };
865
867 vslice->ref_pic_list0[
i].picture_id = VA_INVALID_ID;
868 vslice->ref_pic_list0[
i].flags = VA_PICTURE_HEVC_INVALID;
869 vslice->ref_pic_list1[
i].picture_id = VA_INVALID_ID;
870 vslice->ref_pic_list1[
i].flags = VA_PICTURE_HEVC_INVALID;
871 }
872
874 // Backward reference for P- or B-frame.
877 vslice->ref_pic_list0[0] = vpic->reference_frames[0];
879 // Reference for GPB B-frame, L0 == L1
880 vslice->ref_pic_list1[0] = vpic->reference_frames[0];
881 }
883 // Forward reference for B-frame.
885 vslice->ref_pic_list1[0] = vpic->reference_frames[1];
886 }
887
891 vslice->ref_pic_list1[
i].picture_id = vslice->ref_pic_list0[
i].picture_id;
892 vslice->ref_pic_list1[
i].flags = vslice->ref_pic_list0[
i].flags;
893 }
894 }
895
896 return 0;
897 }
898
900 {
903
904 #if VA_CHECK_VERSION(1, 13, 0)
905 {
907 VAConfigAttribValEncHEVCBlockSizes block_size;
908 VAConfigAttrib attr;
909 VAStatus vas;
910
911 attr.type = VAConfigAttribEncHEVCFeatures;
912 vas = vaGetConfigAttributes(
ctx->hwctx->display,
ctx->va_profile,
913 ctx->va_entrypoint, &attr, 1);
914 if (vas != VA_STATUS_SUCCESS) {
916 "features, using guessed defaults.\n");
918 } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
920 "encoder features, using guessed defaults.\n");
921 } else {
923 }
924
925 attr.type = VAConfigAttribEncHEVCBlockSizes;
926 vas = vaGetConfigAttributes(
ctx->hwctx->display,
ctx->va_profile,
927 ctx->va_entrypoint, &attr, 1);
928 if (vas != VA_STATUS_SUCCESS) {
930 "block size, using guessed defaults.\n");
932 } else if (attr.value == VA_ATTRIB_NOT_SUPPORTED) {
934 "encoder block size, using guessed defaults.\n");
935 } else {
936 priv->
va_bs = block_size.value = attr.value;
937
939 1 << block_size.bits.log2_max_coding_tree_block_size_minus3 + 3;
941 1 << block_size.bits.log2_min_luma_coding_block_size_minus3 + 3;
942 }
943 }
944 #endif
945
949 }
953
958
960
961 return 0;
962 }
963
965 {
968 int err;
969
971 if (err < 0)
972 return err;
973
974 if (
ctx->va_rc_mode == VA_RC_CQP) {
975 // Note that VAAPI only supports positive QP values - the range is
976 // therefore always bounded below by 1, even in 10-bit mode where
977 // it should go down to -12.
978
984 else
990 else
992
994 "%d / %d / %d for IDR- / P- / B-frames.\n",
996
997 } else {
998 // These still need to be set for init_qp/slice_qp_delta.
1002 }
1003
1004 ctx->roi_quant_range = 51 + 6 * (
ctx->profile->depth - 8);
1005
1006 return 0;
1007 }
1008
1012 #if VA_CHECK_VERSION(0, 37, 0)
1015 #endif
1016 #if VA_CHECK_VERSION(1, 2, 0)
1024 #endif
1026 };
1027
1030
1035
1036 .default_quality = 25,
1037
1040
1042
1043 .sequence_params_size = sizeof(VAEncSequenceParameterBufferHEVC),
1045
1046 .picture_params_size = sizeof(VAEncPictureParameterBufferHEVC),
1048
1049 .slice_params_size = sizeof(VAEncSliceParameterBufferHEVC),
1051
1052 .sequence_header_type = VAEncPackedHeaderSequence,
1054
1055 .slice_header_type = VAEncPackedHeaderHEVC_Slice,
1057
1059 };
1060
1062 {
1065
1067
1072
1075 "in 8-bit unsigned integer.\n", avctx->
level);
1077 }
1078
1079 ctx->desired_packed_headers =
1080 VA_ENC_PACKED_HEADER_SEQUENCE | // VPS, SPS and PPS.
1081 VA_ENC_PACKED_HEADER_SLICE | // Slice headers.
1082 VA_ENC_PACKED_HEADER_MISC; // SEI
1083
1085 ctx->explicit_qp = priv->
qp;
1086
1088 }
1089
1091 {
1093
1095 ff_cbs_close(&priv->
cbc);
1097
1099 }
1100
1101 #define OFFSET(x) offsetof(VAAPIEncodeH265Context, x)
1102 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1107
1108 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1110
1111 { "aud", "Include AUD",
1113
1114 { "profile", "Set profile (general_profile_idc)",
1117
1118 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1119 { .i64 = value }, 0, 0, FLAGS, .unit = "profile"
1123 #undef PROFILE
1124
1125 { "tier", "Set tier (general_tier_flag)",
1127 { .i64 = 0 }, 0, 1,
FLAGS, .unit =
"tier" },
1129 { .i64 = 0 }, 0, 0,
FLAGS, .unit =
"tier" },
1131 { .i64 = 1 }, 0, 0,
FLAGS, .unit =
"tier" },
1132
1133 { "level", "Set level (general_level_idc)",
1136
1137 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1138 { .i64 = value }, 0, 0, FLAGS, .unit = "level"
1141 {
LEVEL(
"2.1", 63) },
1143 {
LEVEL(
"3.1", 93) },
1144 {
LEVEL(
"4", 120) },
1145 {
LEVEL(
"4.1", 123) },
1146 {
LEVEL(
"5", 150) },
1147 {
LEVEL(
"5.1", 153) },
1148 {
LEVEL(
"5.2", 156) },
1149 {
LEVEL(
"6", 180) },
1150 {
LEVEL(
"6.1", 183) },
1151 {
LEVEL(
"6.2", 186) },
1152 #undef LEVEL
1153
1154 { "sei", "Set SEI to include",
1157 0, INT_MAX,
FLAGS, .unit =
"sei" },
1158 { "hdr",
1159 "Include HDR metadata for mastering display colour volume "
1160 "and content light level information",
1163 INT_MIN, INT_MAX,
FLAGS, .unit =
"sei" },
1164 { "a53_cc",
1165 "Include A/53 caption data",
1168 INT_MIN, INT_MAX,
FLAGS, .unit =
"sei" },
1169
1170 { "tiles", "Tile columns x rows",
1173
1175 };
1176
1178 { "b", "0" },
1179 { "bf", "2" },
1180 { "g", "120" },
1181 { "i_qfactor", "1" },
1182 { "i_qoffset", "0" },
1183 { "b_qfactor", "6/5" },
1184 { "b_qoffset", "0" },
1185 { "qmin", "-1" },
1186 { "qmax", "-1" },
1187 { "refs", "0" },
1189 };
1190
1196 };
1197
1199 .
p.
name =
"hevc_vaapi",
1216 .p.wrapper_name = "vaapi",
1217 };