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_h264.h>
23
28
37
38 enum {
42 };
43
44 // Random (version 4) ISO 11578 UUID.
46 0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf,
47 0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d,
48 };
49
53
56
59
63
66
67 // User options.
75
76 // Derived settings.
79
83
85
86 // Writer structures.
89
94
100
105
106
108 char *
data,
size_t *data_len,
110 {
112 int err;
113
115 if (err < 0) {
117 return err;
118 }
119
122 "%zu < %zu.\n", *data_len,
125 }
126
129
130 return 0;
131 }
132
135 void *nal_unit)
136 {
138 int err;
139
142 if (err < 0) {
144 "type = %d.\n",
header->nal_unit_type);
145 return err;
146 }
147
148 return 0;
149 }
150
152 char *
data,
size_t *data_len)
153 {
156 int err;
157
160 if (err < 0)
163 }
164
166 if (err < 0)
168
170 if (err < 0)
172
176 return err;
177 }
178
182 char *
data,
size_t *data_len)
183 {
186 int err;
187
190 if (err < 0)
193 }
194
196 if (err < 0)
198
202 return err;
203 }
204
208 char *
data,
size_t *data_len)
209 {
212 int err;
213
217 if (err < 0)
220 }
221
226 if (err < 0)
228 }
234 if (err < 0)
236 }
240 if (err < 0)
242 }
247 if (err < 0)
249 }
250
252
254 if (err < 0)
256
258
259 *
type = VAEncPackedHeaderRawData;
260 return 0;
261
262 #if !CONFIG_VAAPI_1
264 // Insert a zero-length header using the old SEI type. This is
265 // required to avoid triggering broken behaviour on Intel platforms
266 // in CBR mode where an invalid SEI message is generated by the
267 // driver and inserted into the stream.
268 *data_len = 0;
269 *
type = VAEncPackedHeaderH264_SEI;
271 return 0;
272 #endif
273
274 } else {
276 }
277
280 return err;
281 }
282
284 {
289 VAEncSequenceParameterBufferH264 *vseq =
ctx->codec_sequence_params;
290 VAEncPictureParameterBufferH264 *vpic =
ctx->codec_picture_params;
291
292 memset(
sps, 0,
sizeof(*
sps));
293 memset(
pps, 0,
sizeof(*
pps));
294
295 sps->nal_unit_header.nal_ref_idc = 3;
297
299
302 sps->constraint_set1_flag = 1;
303
305 sps->constraint_set3_flag =
ctx->gop_size == 1;
306
309 sps->constraint_set4_flag = 1;
310 sps->constraint_set5_flag =
ctx->b_per_p == 0;
311 }
312
313 if (
ctx->gop_size == 1)
315 else
317
320 } else {
323
326 else
328
337 if (
level->constraint_set3_flag)
338 sps->constraint_set3_flag = 1;
340 } else {
342 "to any level: using level 6.2.\n");
344 }
345 }
346
347 sps->seq_parameter_set_id = 0;
348 sps->chroma_format_idc = 1;
349
350 sps->log2_max_frame_num_minus4 = 4;
351 sps->pic_order_cnt_type = 0;
352 sps->log2_max_pic_order_cnt_lsb_minus4 = 4;
353
355
357 sps->pic_height_in_map_units_minus1 = priv->
mb_height - 1;
358
359 sps->frame_mbs_only_flag = 1;
360 sps->direct_8x8_inference_flag = 1;
361
364 sps->frame_cropping_flag = 1;
365
366 sps->frame_crop_left_offset = 0;
367 sps->frame_crop_right_offset =
369 sps->frame_crop_top_offset = 0;
370 sps->frame_crop_bottom_offset =
372 } else {
373 sps->frame_cropping_flag = 0;
374 }
375
376 sps->vui_parameters_present_flag = 1;
377
381 { 0, 0 },
382 { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
383 { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
384 { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
385 { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
386 };
391 if (num == sar_idc[
i].num &&
392 den == sar_idc[
i].den) {
393 sps->vui.aspect_ratio_idc =
i;
394 break;
395 }
396 }
398 sps->vui.aspect_ratio_idc = 255;
399 sps->vui.sar_width = num;
400 sps->vui.sar_height = den;
401 }
402 sps->vui.aspect_ratio_info_present_flag = 1;
403 }
404
405 // Unspecified video format, from table E-2.
406 sps->vui.video_format = 5;
407 sps->vui.video_full_range_flag =
415 sps->vui.colour_description_present_flag = 1;
417 sps->vui.colour_description_present_flag)
418 sps->vui.video_signal_type_present_flag = 1;
419
421 sps->vui.chroma_loc_info_present_flag = 1;
422 sps->vui.chroma_sample_loc_type_top_field =
423 sps->vui.chroma_sample_loc_type_bottom_field =
425 }
426
427 sps->vui.timing_info_present_flag = 1;
431 sps->vui.fixed_frame_rate_flag = 1;
432 } else {
435 sps->vui.fixed_frame_rate_flag = 0;
436 }
437
441
442 sps->vui.nal_hrd_parameters_present_flag = 1;
443
445
446 // Try to scale these to a sensible range so that the
447 // golomb encode of the value is not overlong.
452
457
458 // CBR mode as defined for the HRD cannot be achieved without filler
459 // data, so this flag cannot be set even with VAAPI CBR modes.
461
466
468
469 // This calculation can easily overflow 32 bits.
471 (uint64_t)
ctx->hrd_params.initial_buffer_fullness /
472 ctx->hrd_params.buffer_size;
474 } else {
475 sps->vui.nal_hrd_parameters_present_flag = 0;
476 sps->vui.low_delay_hrd_flag = 1 -
sps->vui.fixed_frame_rate_flag;
477 }
478
479 sps->vui.bitstream_restriction_flag = 1;
480 sps->vui.motion_vectors_over_pic_boundaries_flag = 1;
481 sps->vui.log2_max_mv_length_horizontal = 15;
482 sps->vui.log2_max_mv_length_vertical = 15;
483 sps->vui.max_num_reorder_frames =
ctx->max_b_depth;
484 sps->vui.max_dec_frame_buffering =
ctx->max_b_depth + 1;
485
486 pps->nal_unit_header.nal_ref_idc = 3;
488
489 pps->pic_parameter_set_id = 0;
490 pps->seq_parameter_set_id = 0;
491
492 pps->entropy_coding_mode_flag =
496 if (!priv->
coder &&
pps->entropy_coding_mode_flag)
497 pps->entropy_coding_mode_flag = 0;
498
499 pps->num_ref_idx_l0_default_active_minus1 = 0;
500 pps->num_ref_idx_l1_default_active_minus1 = 0;
501
503
507 pps->more_rbsp_data = 0;
508 } else {
509 pps->more_rbsp_data = 1;
510
511 pps->transform_8x8_mode_flag = 1;
512 }
513
514 *vseq = (VAEncSequenceParameterBufferH264) {
515 .seq_parameter_set_id =
sps->seq_parameter_set_id,
516 .level_idc =
sps->level_idc,
517 .intra_period =
ctx->gop_size,
518 .intra_idr_period =
ctx->gop_size,
519 .ip_period =
ctx->b_per_p + 1,
520
521 .bits_per_second =
ctx->va_bit_rate,
522 .max_num_ref_frames =
sps->max_num_ref_frames,
523 .picture_width_in_mbs =
sps->pic_width_in_mbs_minus1 + 1,
524 .picture_height_in_mbs =
sps->pic_height_in_map_units_minus1 + 1,
525
526 .seq_fields.bits = {
527 .chroma_format_idc =
sps->chroma_format_idc,
528 .frame_mbs_only_flag =
sps->frame_mbs_only_flag,
529 .mb_adaptive_frame_field_flag =
sps->mb_adaptive_frame_field_flag,
530 .seq_scaling_matrix_present_flag =
sps->seq_scaling_matrix_present_flag,
531 .direct_8x8_inference_flag =
sps->direct_8x8_inference_flag,
532 .log2_max_frame_num_minus4 =
sps->log2_max_frame_num_minus4,
533 .pic_order_cnt_type =
sps->pic_order_cnt_type,
534 .log2_max_pic_order_cnt_lsb_minus4 =
sps->log2_max_pic_order_cnt_lsb_minus4,
535 .delta_pic_order_always_zero_flag =
sps->delta_pic_order_always_zero_flag,
536 },
537
538 .bit_depth_luma_minus8 =
sps->bit_depth_luma_minus8,
539 .bit_depth_chroma_minus8 =
sps->bit_depth_chroma_minus8,
540
541 .frame_cropping_flag =
sps->frame_cropping_flag,
542 .frame_crop_left_offset =
sps->frame_crop_left_offset,
543 .frame_crop_right_offset =
sps->frame_crop_right_offset,
544 .frame_crop_top_offset =
sps->frame_crop_top_offset,
545 .frame_crop_bottom_offset =
sps->frame_crop_bottom_offset,
546
547 .vui_parameters_present_flag =
sps->vui_parameters_present_flag,
548
549 .vui_fields.bits = {
550 .aspect_ratio_info_present_flag =
sps->vui.aspect_ratio_info_present_flag,
551 .timing_info_present_flag =
sps->vui.timing_info_present_flag,
552 .bitstream_restriction_flag =
sps->vui.bitstream_restriction_flag,
553 .log2_max_mv_length_horizontal =
sps->vui.log2_max_mv_length_horizontal,
554 .log2_max_mv_length_vertical =
sps->vui.log2_max_mv_length_vertical,
555 },
556
557 .aspect_ratio_idc =
sps->vui.aspect_ratio_idc,
558 .sar_width =
sps->vui.sar_width,
559 .sar_height =
sps->vui.sar_height,
560 .num_units_in_tick =
sps->vui.num_units_in_tick,
561 .time_scale =
sps->vui.time_scale,
562 };
563
564 *vpic = (VAEncPictureParameterBufferH264) {
565 .CurrPic = {
566 .picture_id = VA_INVALID_ID,
567 .flags = VA_PICTURE_H264_INVALID,
568 },
569
570 .coded_buf = VA_INVALID_ID,
571
572 .pic_parameter_set_id =
pps->pic_parameter_set_id,
573 .seq_parameter_set_id =
pps->seq_parameter_set_id,
574
575 .pic_init_qp =
pps->pic_init_qp_minus26 + 26,
576 .num_ref_idx_l0_active_minus1 =
pps->num_ref_idx_l0_default_active_minus1,
577 .num_ref_idx_l1_active_minus1 =
pps->num_ref_idx_l1_default_active_minus1,
578
579 .chroma_qp_index_offset =
pps->chroma_qp_index_offset,
580 .second_chroma_qp_index_offset =
pps->second_chroma_qp_index_offset,
581
582 .pic_fields.bits = {
583 .entropy_coding_mode_flag =
pps->entropy_coding_mode_flag,
584 .weighted_pred_flag =
pps->weighted_pred_flag,
585 .weighted_bipred_idc =
pps->weighted_bipred_idc,
586 .constrained_intra_pred_flag =
pps->constrained_intra_pred_flag,
587 .transform_8x8_mode_flag =
pps->transform_8x8_mode_flag,
588 .deblocking_filter_control_present_flag =
589 pps->deblocking_filter_control_present_flag,
590 .redundant_pic_cnt_present_flag =
pps->redundant_pic_cnt_present_flag,
591 .pic_order_present_flag =
592 pps->bottom_field_pic_order_in_frame_present_flag,
593 .pic_scaling_matrix_present_flag =
pps->pic_scaling_matrix_present_flag,
594 },
595 };
596
597 return 0;
598 }
599
602 {
610
613
617
620 } else {
622
624
627
634 } else {
637 }
638 }
642
648 },
650 };
651 } else {
653 }
654
656
659 #if !CONFIG_VAAPI_1
660 if (
ctx->va_rc_mode == VA_RC_CBR)
662 #endif
663
668 };
669
671 }
672
676 .exact_match_flag = 1,
677 .broken_link_flag =
ctx->b_per_p > 0,
678 };
679
681 }
682
683 vpic->CurrPic = (VAPictureH264) {
686 .flags = 0,
689 };
690
694
696 href =
ref->priv_data;
697
698 vpic->ReferenceFrames[
i] = (VAPictureH264) {
699 .picture_id =
ref->recon_surface,
701 .flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE,
704 };
705 }
707 vpic->ReferenceFrames[
i] = (VAPictureH264) {
708 .picture_id = VA_INVALID_ID,
709 .flags = VA_PICTURE_H264_INVALID,
710 };
711 }
712
714
716
719
720 return 0;
721 }
722
727 int *rpl_size)
728 {
732
736
740
742 for (j = n; j > 0; j--) {
746 break;
747 rpl0[j] = rpl0[j - 1];
748 }
749 rpl0[j] = prev->
dpb[
i];
750
752 for (j = n; j > 0; j--) {
758 break;
759 } else {
761 break;
762 }
763 rpl0[j] = rpl0[j - 1];
764 }
765 rpl0[j] = prev->
dpb[
i];
766
767 for (j = n; j > 0; j--) {
773 break;
774 } else {
776 break;
777 }
778 rpl1[j] = rpl1[j - 1];
779 }
780 rpl1[j] = prev->
dpb[
i];
781 }
782
783 ++n;
784 }
785
787 for (
i = 0;
i < n;
i++) {
788 if (rpl0[
i] != rpl1[
i])
789 break;
790 }
793 }
794
799 for (
i = 0;
i < n;
i++) {
802 hn->frame_num,
hn->pic_order_cnt);
803 }
805 }
809 for (
i = 0;
i < n;
i++) {
812 hn->frame_num,
hn->pic_order_cnt);
813 }
815 }
816
817 *rpl_size = n;
818 }
819
823 {
833
837 } else {
840 }
841
844
846
848 ((1 << (4 +
sps->log2_max_frame_num_minus4)) - 1);
851 ((1 << (4 +
sps->log2_max_pic_order_cnt_lsb_minus4)) - 1);
852
854
859 else
861
864 int discard = 0, keep = 0;
865
866 // Discard everything which is in the DPB of the previous frame but
867 // not in the DPB of this one.
870 if (prev->
dpb[
i] == pic->
dpb[j])
871 break;
872 }
874 discard_list[discard] = prev->
dpb[
i];
875 ++discard;
876 } else {
877 ++keep;
878 }
879 }
881
882 if (discard == 0) {
884 } else {
886 for (
i = 0;
i < discard;
i++) {
892 }
894 }
895 }
896
897 // If the intended references are not the first entries of RefPicListN
898 // by default, use ref-pic-list-modification to move them there.
902 int n;
903
905 def_l0, def_l1, &n);
906
908 int need_rplm = 0;
911 if (pic->
refs[
i] != def_l0[
i])
912 need_rplm = 1;
913 }
914
916 if (need_rplm) {
925 } else {
929 }
931 }
933 }
934
935 } else {
936 int need_rplm_l0 = 0, need_rplm_l1 = 0;
937 int n0 = 0, n1 = 0;
943 if (pic->
refs[
i] != def_l0[n0])
944 need_rplm_l0 = 1;
945 ++n0;
946 } else {
947 if (pic->
refs[
i] != def_l1[n1])
948 need_rplm_l1 = 1;
949 ++n1;
950 }
951 }
952
954 if (need_rplm_l0) {
959 continue;
965 } else {
969 }
971 ++j;
972 }
975 }
976
978 if (need_rplm_l1) {
983 continue;
989 } else {
993 }
995 ++j;
996 }
999 }
1000 }
1001 }
1002
1005
1006 vslice->macroblock_info = VA_INVALID_ID;
1007
1011
1013
1015
1017 vslice->RefPicList0[
i].picture_id = VA_INVALID_ID;
1018 vslice->RefPicList0[
i].flags = VA_PICTURE_H264_INVALID;
1019 vslice->RefPicList1[
i].picture_id = VA_INVALID_ID;
1020 vslice->RefPicList1[
i].flags = VA_PICTURE_H264_INVALID;
1021 }
1022
1025 // Backward reference for P- or B-frame.
1028 vslice->RefPicList0[0] = vpic->ReferenceFrames[0];
1029 }
1031 // Forward reference for B-frame.
1033 vslice->RefPicList1[0] = vpic->ReferenceFrames[1];
1034 }
1035
1037
1038 return 0;
1039 }
1040
1042 {
1045 int err;
1046
1048 if (err < 0)
1049 return err;
1050
1053
1054 if (
ctx->va_rc_mode == VA_RC_CQP) {
1060 else
1066 else
1068
1070 "%d / %d / %d for IDR- / P- / B-frames.\n",
1072
1073 } else {
1074 // These still need to be set for pic_init_qp/slice_qp_delta.
1078 }
1079
1080 if (!
ctx->rc_mode->hrd) {
1081 // Timing SEI requires a mode respecting HRD parameters.
1083 }
1084
1087 const char *vaapi = VA_VERSION_S;
1088 const char *driver;
1090
1094
1095 driver = vaQueryVendorString(
ctx->hwctx->display);
1096 if (!driver)
1097 driver = "unknown driver";
1098
1104
1106 "%s / VAAPI %s / %s", lavc, vaapi, driver);
1107
1110 }
1111 }
1112
1113 ctx->roi_quant_range = 51 + 6 * (
ctx->profile->depth - 8);
1114
1115 return 0;
1116 }
1117
1122 8, 3, 1, 1, VAProfileH264ConstrainedBaseline },
1124 };
1125
1128
1133
1134 .default_quality = 20,
1135
1137
1139
1140 .sequence_params_size = sizeof(VAEncSequenceParameterBufferH264),
1142
1143 .picture_params_size = sizeof(VAEncPictureParameterBufferH264),
1145
1146 .slice_params_size = sizeof(VAEncSliceParameterBufferH264),
1148
1149 .sequence_header_type = VAEncPackedHeaderSequence,
1151
1152 .slice_header_type = VAEncPackedHeaderH264_Slice,
1154
1156 };
1157
1159 {
1162
1164
1171
1172 // Reject unsupported profiles.
1176 "supported, using constrained baseline profile instead.\n");
1178 break;
1181 "is not supported.\n");
1186 "are not supported.\n");
1195 "are not supported.\n");
1197 }
1198
1201 "in 8-bit unsigned integer.\n", avctx->
level);
1203 }
1204
1205 ctx->desired_packed_headers =
1206 VA_ENC_PACKED_HEADER_SEQUENCE | // SPS and PPS.
1207 VA_ENC_PACKED_HEADER_SLICE | // Slice headers.
1208 VA_ENC_PACKED_HEADER_MISC; // SEI.
1209
1212
1213 ctx->slice_block_height =
ctx->slice_block_width = 16;
1214
1216 ctx->explicit_qp = priv->
qp;
1217
1219 }
1220
1222 {
1224
1228
1230 }
1231
1232 #define OFFSET(x) offsetof(VAAPIEncodeH264Context, x)
1233 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1237
1238 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1240 { "quality", "Set encode quality (trades off against speed, higher is faster)",
1242 { "coder", "Entropy coder type",
1248
1249 { "aud", "Include AUD",
1251
1252 { "sei", "Set SEI to include",
1255 0, INT_MAX,
FLAGS,
"sei" },
1256 { "identifier", "Include encoder version identifier",
1258 INT_MIN, INT_MAX,
FLAGS,
"sei" },
1259 { "timing", "Include timing parameters (buffering_period and pic_timing)",
1261 INT_MIN, INT_MAX,
FLAGS,
"sei" },
1262 { "recovery_point", "Include recovery points where appropriate",
1264 INT_MIN, INT_MAX,
FLAGS,
"sei" },
1265
1266 { "profile", "Set profile (profile_idc and constraint_set*_flag)",
1269
1270 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1271 { .i64 = value }, 0, 0, FLAGS, "profile"
1275 #undef PROFILE
1276
1277 { "level", "Set level (level_idc)",
1280
1281 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1282 { .i64 = value }, 0, 0, FLAGS, "level"
1284 {
LEVEL(
"1.1", 11) },
1285 {
LEVEL(
"1.2", 12) },
1286 {
LEVEL(
"1.3", 13) },
1288 {
LEVEL(
"2.1", 21) },
1289 {
LEVEL(
"2.2", 22) },
1291 {
LEVEL(
"3.1", 31) },
1292 {
LEVEL(
"3.2", 32) },
1294 {
LEVEL(
"4.1", 41) },
1295 {
LEVEL(
"4.2", 42) },
1297 {
LEVEL(
"5.1", 51) },
1298 {
LEVEL(
"5.2", 52) },
1300 {
LEVEL(
"6.1", 61) },
1301 {
LEVEL(
"6.2", 62) },
1302 #undef LEVEL
1303
1305 };
1306
1308 { "b", "0" },
1309 { "bf", "2" },
1310 { "g", "120" },
1311 { "i_qfactor", "1" },
1312 { "i_qoffset", "0" },
1313 { "b_qfactor", "6/5" },
1314 { "b_qoffset", "0" },
1315 { "qmin", "-1" },
1316 { "qmax", "-1" },
1318 };
1319
1325 };
1326
1328 .
name =
"h264_vaapi",
1344 },
1346 .wrapper_name = "vaapi",
1347 };