2 * This file is part of Libav.
4 * Libav 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.
9 * Libav 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.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with Libav; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <va/va_enc_h264.h>
22 #include "libavutil/avassert.h"
23 #include "libavutil/internal.h"
24 #include "libavutil/opt.h"
25 #include "libavutil/pixfmt.h"
31 #include "vaapi_encode.h"
32 #include "vaapi_encode_h26x.h"
42 // This structure contains all possibly-useful per-sequence syntax elements
43 // which are not already contained in the various VAAPI structures.
44 typedef struct VAAPIEncodeH264MiscSequenceParams
{
45 unsigned int profile_idc
;
46 char constraint_set0_flag
;
47 char constraint_set1_flag
;
48 char constraint_set2_flag
;
49 char constraint_set3_flag
;
50 char constraint_set4_flag
;
51 char constraint_set5_flag
;
53 char separate_colour_plane_flag
;
54 char qpprime_y_zero_transform_bypass_flag
;
56 char gaps_in_frame_num_allowed_flag
;
57 char delta_pic_order_always_zero_flag
;
58 char bottom_field_pic_order_in_frame_present_flag
;
60 unsigned int num_slice_groups_minus1
;
61 unsigned int slice_group_map_type
;
63 int pic_init_qs_minus26
;
65 char overscan_info_present_flag
;
66 char overscan_appropriate_flag
;
68 char video_signal_type_present_flag
;
69 unsigned int video_format
;
70 char video_full_range_flag
;
71 char colour_description_present_flag
;
72 unsigned int colour_primaries
;
73 unsigned int transfer_characteristics
;
74 unsigned int matrix_coefficients
;
76 char chroma_loc_info_present_flag
;
77 unsigned int chroma_sample_loc_type_top_field
;
78 unsigned int chroma_sample_loc_type_bottom_field
;
80 // Some timing elements are in VAEncSequenceParameterBufferH264.
81 char fixed_frame_rate_flag
;
83 char nal_hrd_parameters_present_flag
;
84 char vcl_hrd_parameters_present_flag
;
85 char low_delay_hrd_flag
;
86 char pic_struct_present_flag
;
87 char bitstream_restriction_flag
;
89 unsigned int cpb_cnt_minus1
;
90 unsigned int bit_rate_scale
;
91 unsigned int cpb_size_scale
;
92 unsigned int bit_rate_value_minus1
[32];
93 unsigned int cpb_size_value_minus1
[32];
95 unsigned int initial_cpb_removal_delay_length_minus1
;
96 unsigned int cpb_removal_delay_length_minus1
;
97 unsigned int dpb_output_delay_length_minus1
;
98 unsigned int time_offset_length
;
100 unsigned int initial_cpb_removal_delay
;
101 unsigned int initial_cpb_removal_delay_offset
;
103 unsigned int pic_struct
;
104 } VAAPIEncodeH264MiscSequenceParams
;
106 // This structure contains all possibly-useful per-slice syntax elements
107 // which are not already contained in the various VAAPI structures.
108 typedef struct VAAPIEncodeH264MiscSliceParams
{
109 unsigned int nal_unit_type
;
110 unsigned int nal_ref_idc
;
112 unsigned int colour_plane_id
;
114 char bottom_field_flag
;
116 unsigned int redundant_pic_cnt
;
118 char sp_for_switch_flag
;
121 char ref_pic_list_modification_flag_l0
;
122 char ref_pic_list_modification_flag_l1
;
124 char no_output_of_prior_pics_flag
;
125 char long_term_reference_flag
;
126 char adaptive_ref_pic_marking_mode_flag
;
127 } VAAPIEncodeH264MiscSliceParams
;
129 typedef struct VAAPIEncodeH264Slice
{
130 VAAPIEncodeH264MiscSliceParams misc_slice_params
;
131 } VAAPIEncodeH264Slice
;
133 typedef struct VAAPIEncodeH264Context
{
134 VAAPIEncodeH264MiscSequenceParams misc_sequence_params
;
144 int64_t idr_pic_count
;
149 // Rate control configuration.
152 VAEncMiscParameterBuffer misc
;
153 VAEncMiscParameterRateControl rc
;
156 VAEncMiscParameterBuffer misc
;
157 VAEncMiscParameterHRD hrd
;
160 #if VA_CHECK_VERSION(0, 36, 0)
161 // Speed-quality tradeoff setting.
163 VAEncMiscParameterBuffer misc
;
164 VAEncMiscParameterBufferQualityLevel quality
;
167 } VAAPIEncodeH264Context
;
169 typedef struct VAAPIEncodeH264Options
{
173 } VAAPIEncodeH264Options
;
176 #define vseq_var(name) vseq->name, name
177 #define vseq_field(name) vseq->seq_fields.bits.name, name
178 #define vvui_field(name) vseq->vui_fields.bits.name, name
179 #define vpic_var(name) vpic->name, name
180 #define vpic_field(name) vpic->pic_fields.bits.name, name
181 #define vslice_var(name) vslice->name, name
182 #define vslice_field(name) vslice->slice_fields.bits.name, name
183 #define mseq_var(name) mseq->name, name
184 #define mslice_var(name) mslice->name, name
186 static void vaapi_encode_h264_write_nal_header(PutBitContext
*pbc
,
187 int nal_unit_type
, int nal_ref_idc
)
189 u(1, 0, forbidden_zero_bit
);
190 u(2, nal_ref_idc
, nal_ref_idc
);
191 u(5, nal_unit_type
, nal_unit_type
);
194 static void vaapi_encode_h264_write_trailing_rbsp(PutBitContext
*pbc
)
196 u(1, 1, rbsp_stop_one_bit
);
197 while (put_bits_count(pbc
) & 7)
198 u(1, 0, rbsp_alignment_zero_bit
);
201 static void vaapi_encode_h264_write_vui(PutBitContext
*pbc
,
202 VAAPIEncodeContext
*ctx
)
204 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
205 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
206 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
209 u(1, vvui_field(aspect_ratio_info_present_flag
));
210 if (vseq
->vui_fields
.bits
.aspect_ratio_info_present_flag
) {
211 u(8, vseq_var(aspect_ratio_idc
));
212 if (vseq
->aspect_ratio_idc
== 255) {
213 u(16, vseq_var(sar_width
));
214 u(16, vseq_var(sar_height
));
218 u(1, mseq_var(overscan_info_present_flag
));
219 if (mseq
->overscan_info_present_flag
)
220 u(1, mseq_var(overscan_appropriate_flag
));
222 u(1, mseq_var(video_signal_type_present_flag
));
223 if (mseq
->video_signal_type_present_flag
) {
224 u(3, mseq_var(video_format
));
225 u(1, mseq_var(video_full_range_flag
));
226 u(1, mseq_var(colour_description_present_flag
));
227 if (mseq
->colour_description_present_flag
) {
228 u(8, mseq_var(colour_primaries
));
229 u(8, mseq_var(transfer_characteristics
));
230 u(8, mseq_var(matrix_coefficients
));
234 u(1, mseq_var(chroma_loc_info_present_flag
));
235 if (mseq
->chroma_loc_info_present_flag
) {
236 ue(mseq_var(chroma_sample_loc_type_top_field
));
237 ue(mseq_var(chroma_sample_loc_type_bottom_field
));
240 u(1, vvui_field(timing_info_present_flag
));
241 if (vseq
->vui_fields
.bits
.timing_info_present_flag
) {
242 u(32, vseq_var(num_units_in_tick
));
243 u(32, vseq_var(time_scale
));
244 u(1, mseq_var(fixed_frame_rate_flag
));
247 u(1, mseq_var(nal_hrd_parameters_present_flag
));
248 if (mseq
->nal_hrd_parameters_present_flag
) {
249 ue(mseq_var(cpb_cnt_minus1
));
250 u(4, mseq_var(bit_rate_scale
));
251 u(4, mseq_var(cpb_size_scale
));
252 for (i
= 0; i
<= mseq
->cpb_cnt_minus1
; i
++) {
253 ue(mseq_var(bit_rate_value_minus1
[i
]));
254 ue(mseq_var(cpb_size_value_minus1
[i
]));
255 u(1, mseq_var(cbr_flag
[i
]));
257 u(5, mseq_var(initial_cpb_removal_delay_length_minus1
));
258 u(5, mseq_var(cpb_removal_delay_length_minus1
));
259 u(5, mseq_var(dpb_output_delay_length_minus1
));
260 u(5, mseq_var(time_offset_length
));
262 u(1, mseq_var(vcl_hrd_parameters_present_flag
));
263 if (mseq
->vcl_hrd_parameters_present_flag
) {
264 av_assert0(0 && "vcl hrd parameters not supported");
267 if (mseq
->nal_hrd_parameters_present_flag
||
268 mseq
->vcl_hrd_parameters_present_flag
)
269 u(1, mseq_var(low_delay_hrd_flag
));
270 u(1, mseq_var(pic_struct_present_flag
));
272 u(1, vvui_field(bitstream_restriction_flag
));
273 if (vseq
->vui_fields
.bits
.bitstream_restriction_flag
) {
274 av_assert0(0 && "bitstream restrictions not supported");
278 static void vaapi_encode_h264_write_sps(PutBitContext
*pbc
,
279 VAAPIEncodeContext
*ctx
)
281 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
282 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
283 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
286 vaapi_encode_h264_write_nal_header(pbc
, NAL_SPS
, 3);
288 u(8, mseq_var(profile_idc
));
289 u(1, mseq_var(constraint_set0_flag
));
290 u(1, mseq_var(constraint_set1_flag
));
291 u(1, mseq_var(constraint_set2_flag
));
292 u(1, mseq_var(constraint_set3_flag
));
293 u(1, mseq_var(constraint_set4_flag
));
294 u(1, mseq_var(constraint_set5_flag
));
295 u(2, 0, reserved_zero_2bits
);
297 u(8, vseq_var(level_idc
));
299 ue(vseq_var(seq_parameter_set_id
));
301 if (mseq
->profile_idc
== 100 || mseq
->profile_idc
== 110 ||
302 mseq
->profile_idc
== 122 || mseq
->profile_idc
== 244 ||
303 mseq
->profile_idc
== 44 || mseq
->profile_idc
== 83 ||
304 mseq
->profile_idc
== 86 || mseq
->profile_idc
== 118 ||
305 mseq
->profile_idc
== 128 || mseq
->profile_idc
== 138) {
306 ue(vseq_field(chroma_format_idc
));
308 if (vseq
->seq_fields
.bits
.chroma_format_idc
== 3)
309 u(1, mseq_var(separate_colour_plane_flag
));
311 ue(vseq_var(bit_depth_luma_minus8
));
312 ue(vseq_var(bit_depth_chroma_minus8
));
314 u(1, mseq_var(qpprime_y_zero_transform_bypass_flag
));
316 u(1, vseq_field(seq_scaling_matrix_present_flag
));
317 if (vseq
->seq_fields
.bits
.seq_scaling_matrix_present_flag
) {
318 av_assert0(0 && "scaling matrices not supported");
322 ue(vseq_field(log2_max_frame_num_minus4
));
323 ue(vseq_field(pic_order_cnt_type
));
325 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 0) {
326 ue(vseq_field(log2_max_pic_order_cnt_lsb_minus4
));
327 } else if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 1) {
328 u(1, mseq_var(delta_pic_order_always_zero_flag
));
329 se(vseq_var(offset_for_non_ref_pic
));
330 se(vseq_var(offset_for_top_to_bottom_field
));
331 ue(vseq_var(num_ref_frames_in_pic_order_cnt_cycle
));
333 for (i
= 0; i
< vseq
->num_ref_frames_in_pic_order_cnt_cycle
; i
++)
334 se(vseq_var(offset_for_ref_frame
[i
]));
337 ue(vseq_var(max_num_ref_frames
));
338 u(1, mseq_var(gaps_in_frame_num_allowed_flag
));
340 ue(vseq
->picture_width_in_mbs
- 1, pic_width_in_mbs_minus1
);
341 ue(vseq
->picture_height_in_mbs
- 1, pic_height_in_mbs_minus1
);
343 u(1, vseq_field(frame_mbs_only_flag
));
344 if (!vseq
->seq_fields
.bits
.frame_mbs_only_flag
)
345 u(1, vseq_field(mb_adaptive_frame_field_flag
));
347 u(1, vseq_field(direct_8x8_inference_flag
));
349 u(1, vseq_var(frame_cropping_flag
));
350 if (vseq
->frame_cropping_flag
) {
351 ue(vseq_var(frame_crop_left_offset
));
352 ue(vseq_var(frame_crop_right_offset
));
353 ue(vseq_var(frame_crop_top_offset
));
354 ue(vseq_var(frame_crop_bottom_offset
));
357 u(1, vseq_var(vui_parameters_present_flag
));
358 if (vseq
->vui_parameters_present_flag
)
359 vaapi_encode_h264_write_vui(pbc
, ctx
);
361 vaapi_encode_h264_write_trailing_rbsp(pbc
);
364 static void vaapi_encode_h264_write_pps(PutBitContext
*pbc
,
365 VAAPIEncodeContext
*ctx
)
367 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
368 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
369 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
371 vaapi_encode_h264_write_nal_header(pbc
, NAL_PPS
, 3);
373 ue(vpic_var(pic_parameter_set_id
));
374 ue(vpic_var(seq_parameter_set_id
));
376 u(1, vpic_field(entropy_coding_mode_flag
));
377 u(1, mseq_var(bottom_field_pic_order_in_frame_present_flag
));
379 ue(mseq_var(num_slice_groups_minus1
));
380 if (mseq
->num_slice_groups_minus1
> 0) {
381 ue(mseq_var(slice_group_map_type
));
382 av_assert0(0 && "slice groups not supported");
385 ue(vpic_var(num_ref_idx_l0_active_minus1
));
386 ue(vpic_var(num_ref_idx_l1_active_minus1
));
388 u(1, vpic_field(weighted_pred_flag
));
389 u(2, vpic_field(weighted_bipred_idc
));
391 se(vpic
->pic_init_qp
- 26, pic_init_qp_minus26
);
392 se(mseq_var(pic_init_qs_minus26
));
393 se(vpic_var(chroma_qp_index_offset
));
395 u(1, vpic_field(deblocking_filter_control_present_flag
));
396 u(1, vpic_field(constrained_intra_pred_flag
));
397 u(1, vpic_field(redundant_pic_cnt_present_flag
));
398 u(1, vpic_field(transform_8x8_mode_flag
));
400 u(1, vpic_field(pic_scaling_matrix_present_flag
));
401 if (vpic
->pic_fields
.bits
.pic_scaling_matrix_present_flag
) {
402 av_assert0(0 && "scaling matrices not supported");
405 se(vpic_var(second_chroma_qp_index_offset
));
407 vaapi_encode_h264_write_trailing_rbsp(pbc
);
410 static void vaapi_encode_h264_write_slice_header2(PutBitContext
*pbc
,
411 VAAPIEncodeContext
*ctx
,
412 VAAPIEncodePicture
*pic
,
413 VAAPIEncodeSlice
*slice
)
415 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
416 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
417 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
418 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
419 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
420 VAAPIEncodeH264Slice
*pslice
= slice
->priv_data
;
421 VAAPIEncodeH264MiscSliceParams
*mslice
= &pslice
->misc_slice_params
;
423 vaapi_encode_h264_write_nal_header(pbc
, mslice
->nal_unit_type
,
424 mslice
->nal_ref_idc
);
426 ue(vslice
->macroblock_address
, first_mb_in_slice
);
427 ue(vslice_var(slice_type
));
428 ue(vpic_var(pic_parameter_set_id
));
430 if (mseq
->separate_colour_plane_flag
) {
431 u(2, mslice_var(colour_plane_id
));
434 u(4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
,
436 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
)) - 1)),
439 if (!vseq
->seq_fields
.bits
.frame_mbs_only_flag
) {
440 u(1, mslice_var(field_pic_flag
));
441 if (mslice
->field_pic_flag
)
442 u(1, mslice_var(bottom_field_flag
));
445 if (vpic
->pic_fields
.bits
.idr_pic_flag
) {
446 ue(vslice_var(idr_pic_id
));
449 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 0) {
450 u(4 + vseq
->seq_fields
.bits
.log2_max_pic_order_cnt_lsb_minus4
,
451 vslice_var(pic_order_cnt_lsb
));
452 if (mseq
->bottom_field_pic_order_in_frame_present_flag
&&
453 !mslice
->field_pic_flag
) {
454 se(vslice_var(delta_pic_order_cnt_bottom
));
458 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 1 &&
459 !vseq
->seq_fields
.bits
.delta_pic_order_always_zero_flag
) {
460 se(vslice_var(delta_pic_order_cnt
[0]));
461 if (mseq
->bottom_field_pic_order_in_frame_present_flag
&&
462 !mslice
->field_pic_flag
) {
463 se(vslice_var(delta_pic_order_cnt
[1]));
467 if (vpic
->pic_fields
.bits
.redundant_pic_cnt_present_flag
) {
468 ue(mslice_var(redundant_pic_cnt
));
471 if (vslice
->slice_type
== SLICE_TYPE_B
) {
472 u(1, vslice_var(direct_spatial_mv_pred_flag
));
475 if (vslice
->slice_type
== SLICE_TYPE_P
||
476 vslice
->slice_type
== SLICE_TYPE_SP
||
477 vslice
->slice_type
== SLICE_TYPE_B
) {
478 u(1, vslice_var(num_ref_idx_active_override_flag
));
479 if (vslice
->num_ref_idx_active_override_flag
) {
480 ue(vslice_var(num_ref_idx_l0_active_minus1
));
481 if (vslice
->slice_type
== SLICE_TYPE_B
)
482 ue(vslice_var(num_ref_idx_l1_active_minus1
));
486 if (mslice
->nal_unit_type
== 20 || mslice
->nal_unit_type
== 21) {
487 av_assert0(0 && "no MVC support");
489 if (vslice
->slice_type
% 5 != 2 && vslice
->slice_type
% 5 != 4) {
490 u(1, mslice_var(ref_pic_list_modification_flag_l0
));
491 if (mslice
->ref_pic_list_modification_flag_l0
) {
492 av_assert0(0 && "ref pic list modification");
495 if (vslice
->slice_type
% 5 == 1) {
496 u(1, mslice_var(ref_pic_list_modification_flag_l1
));
497 if (mslice
->ref_pic_list_modification_flag_l1
) {
498 av_assert0(0 && "ref pic list modification");
503 if ((vpic
->pic_fields
.bits
.weighted_pred_flag
&&
504 (vslice
->slice_type
== SLICE_TYPE_P
||
505 vslice
->slice_type
== SLICE_TYPE_SP
)) ||
506 (vpic
->pic_fields
.bits
.weighted_bipred_idc
== 1 &&
507 vslice
->slice_type
== SLICE_TYPE_B
)) {
508 av_assert0(0 && "prediction weights not supported");
511 av_assert0(mslice
->nal_ref_idc
> 0 ==
512 vpic
->pic_fields
.bits
.reference_pic_flag
);
513 if (mslice
->nal_ref_idc
!= 0) {
514 if (vpic
->pic_fields
.bits
.idr_pic_flag
) {
515 u(1, mslice_var(no_output_of_prior_pics_flag
));
516 u(1, mslice_var(long_term_reference_flag
));
518 u(1, mslice_var(adaptive_ref_pic_marking_mode_flag
));
519 if (mslice
->adaptive_ref_pic_marking_mode_flag
) {
520 av_assert0(0 && "MMCOs not supported");
525 if (vpic
->pic_fields
.bits
.entropy_coding_mode_flag
&&
526 vslice
->slice_type
!= SLICE_TYPE_I
&&
527 vslice
->slice_type
!= SLICE_TYPE_SI
) {
528 ue(vslice_var(cabac_init_idc
));
531 se(vslice_var(slice_qp_delta
));
532 if (vslice
->slice_type
== SLICE_TYPE_SP
||
533 vslice
->slice_type
== SLICE_TYPE_SI
) {
534 if (vslice
->slice_type
== SLICE_TYPE_SP
)
535 u(1, mslice_var(sp_for_switch_flag
));
536 se(mslice_var(slice_qs_delta
));
539 if (vpic
->pic_fields
.bits
.deblocking_filter_control_present_flag
) {
540 ue(vslice_var(disable_deblocking_filter_idc
));
541 if (vslice
->disable_deblocking_filter_idc
!= 1) {
542 se(vslice_var(slice_alpha_c0_offset_div2
));
543 se(vslice_var(slice_beta_offset_div2
));
547 if (mseq
->num_slice_groups_minus1
> 0 &&
548 mseq
->slice_group_map_type
>= 3 && mseq
->slice_group_map_type
<= 5) {
549 av_assert0(0 && "slice groups not supported");
552 // No alignment - this need not be a byte boundary.
555 static void vaapi_encode_h264_write_buffering_period(PutBitContext
*pbc
,
556 VAAPIEncodeContext
*ctx
,
557 VAAPIEncodePicture
*pic
)
559 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
560 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
561 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
564 ue(vpic_var(seq_parameter_set_id
));
566 if (mseq
->nal_hrd_parameters_present_flag
) {
567 for (i
= 0; i
<= mseq
->cpb_cnt_minus1
; i
++) {
568 u(mseq
->initial_cpb_removal_delay_length_minus1
+ 1,
569 mseq_var(initial_cpb_removal_delay
));
570 u(mseq
->initial_cpb_removal_delay_length_minus1
+ 1,
571 mseq_var(initial_cpb_removal_delay_offset
));
574 if (mseq
->vcl_hrd_parameters_present_flag
) {
575 av_assert0(0 && "vcl hrd parameters not supported");
579 static void vaapi_encode_h264_write_pic_timing(PutBitContext
*pbc
,
580 VAAPIEncodeContext
*ctx
,
581 VAAPIEncodePicture
*pic
)
583 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
584 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
585 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
588 if (mseq
->nal_hrd_parameters_present_flag
||
589 mseq
->vcl_hrd_parameters_present_flag
) {
590 u(mseq
->cpb_removal_delay_length_minus1
+ 1,
591 2 * vseq
->num_units_in_tick
* priv
->cpb_delay
,
593 u(mseq
->dpb_output_delay_length_minus1
+ 1,
594 2 * vseq
->num_units_in_tick
* priv
->dpb_delay
,
597 if (mseq
->pic_struct_present_flag
) {
598 u(4, mseq_var(pic_struct
));
599 num_clock_ts
= (mseq
->pic_struct
<= 2 ?
1 :
600 mseq
->pic_struct
<= 4 ?
2 :
601 mseq
->pic_struct
<= 8 ?
3 : 0);
602 for (i
= 0; i
< num_clock_ts
; i
++) {
603 u(1, 0, clock_timestamp_flag
[i
]);
604 // No full timestamp information.
609 static void vaapi_encode_h264_write_identifier(PutBitContext
*pbc
,
610 VAAPIEncodeContext
*ctx
,
611 VAAPIEncodePicture
*pic
)
613 const char *lavc
= LIBAVCODEC_IDENT
;
614 const char *vaapi
= VA_VERSION_S
;
615 const char *driver
= vaQueryVendorString(ctx
->hwctx
->display
);
619 // Random (version 4) ISO 11578 UUID.
621 0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf,
622 0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d,
625 for (i
= 0; i
< 16; i
++)
626 u(8, uuid
[i
], uuid_iso_iec_11578
);
628 snprintf(tmp
, sizeof(tmp
), "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
629 for (i
= 0; i
< sizeof(tmp
) && tmp
[i
]; i
++)
630 u(8, tmp
[i
], user_data_payload_byte
);
633 static void vaapi_encode_h264_write_sei(PutBitContext
*pbc
,
634 VAAPIEncodeContext
*ctx
,
635 VAAPIEncodePicture
*pic
)
637 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
638 PutBitContext payload_bits
;
640 int payload_type
, payload_size
, i
;
641 void (*write_payload
)(PutBitContext
*pbc
,
642 VAAPIEncodeContext
*ctx
,
643 VAAPIEncodePicture
*pic
) = NULL
;
645 vaapi_encode_h264_write_nal_header(pbc
, NAL_SEI
, 0);
647 for (payload_type
= 0; payload_type
< 64; payload_type
++) {
648 switch (payload_type
) {
649 case SEI_TYPE_BUFFERING_PERIOD
:
650 if (!priv
->send_timing_sei
||
651 pic
->type
!= PICTURE_TYPE_IDR
)
653 write_payload
= &vaapi_encode_h264_write_buffering_period
;
655 case SEI_TYPE_PIC_TIMING
:
656 if (!priv
->send_timing_sei
)
658 write_payload
= &vaapi_encode_h264_write_pic_timing
;
660 case SEI_TYPE_USER_DATA_UNREGISTERED
:
661 if (pic
->encode_order
!= 0)
663 write_payload
= &vaapi_encode_h264_write_identifier
;
669 init_put_bits(&payload_bits
, payload
, sizeof(payload
));
670 write_payload(&payload_bits
, ctx
, pic
);
671 if (put_bits_count(&payload_bits
) & 7) {
672 write_u(&payload_bits
, 1, 1, bit_equal_to_one
);
673 while (put_bits_count(&payload_bits
) & 7)
674 write_u(&payload_bits
, 1, 0, bit_equal_to_zero
);
676 payload_size
= put_bits_count(&payload_bits
) / 8;
677 flush_put_bits(&payload_bits
);
679 u(8, payload_type
, last_payload_type_byte
);
680 u(8, payload_size
, last_payload_size_byte
);
681 for (i
= 0; i
< payload_size
; i
++)
682 u(8, payload
[i
] & 0xff, sei_payload
);
685 vaapi_encode_h264_write_trailing_rbsp(pbc
);
688 static int vaapi_encode_h264_write_sequence_header(AVCodecContext
*avctx
,
689 char *data
, size_t *data_len
)
691 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
695 size_t nal_len
, bit_len
, bit_pos
, next_len
;
700 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
701 vaapi_encode_h264_write_sps(&pbc
, ctx
);
702 nal_len
= put_bits_count(&pbc
);
703 flush_put_bits(&pbc
);
705 next_len
= bit_len
- bit_pos
;
706 err
= ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
+ bit_pos
/ 8,
713 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
714 vaapi_encode_h264_write_pps(&pbc
, ctx
);
715 nal_len
= put_bits_count(&pbc
);
716 flush_put_bits(&pbc
);
718 next_len
= bit_len
- bit_pos
;
719 err
= ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
+ bit_pos
/ 8,
730 static int vaapi_encode_h264_write_slice_header(AVCodecContext
*avctx
,
731 VAAPIEncodePicture
*pic
,
732 VAAPIEncodeSlice
*slice
,
733 char *data
, size_t *data_len
)
735 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
740 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
741 vaapi_encode_h264_write_slice_header2(&pbc
, ctx
, pic
, slice
);
742 header_len
= put_bits_count(&pbc
);
743 flush_put_bits(&pbc
);
745 return ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
, data_len
,
749 static int vaapi_encode_h264_write_extra_header(AVCodecContext
*avctx
,
750 VAAPIEncodePicture
*pic
,
751 int index
, int *type
,
752 char *data
, size_t *data_len
)
754 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
759 if (index
== 0 && ctx
->va_rc_mode
== VA_RC_CBR
) {
760 *type
= VAEncPackedHeaderH264_SEI
;
762 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
763 vaapi_encode_h264_write_sei(&pbc
, ctx
, pic
);
764 header_len
= put_bits_count(&pbc
);
765 flush_put_bits(&pbc
);
767 return ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
, data_len
,
775 static int vaapi_encode_h264_init_sequence_params(AVCodecContext
*avctx
)
777 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
778 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
779 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
780 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
781 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
785 vseq
->seq_parameter_set_id
= 0;
787 vseq
->level_idc
= avctx
->level
;
789 vseq
->max_num_ref_frames
= 2;
791 vseq
->picture_width_in_mbs
= priv
->mb_width
;
792 vseq
->picture_height_in_mbs
= priv
->mb_height
;
794 vseq
->seq_fields
.bits
.chroma_format_idc
= 1;
795 vseq
->seq_fields
.bits
.frame_mbs_only_flag
= 1;
796 vseq
->seq_fields
.bits
.direct_8x8_inference_flag
= 1;
797 vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
= 4;
798 vseq
->seq_fields
.bits
.pic_order_cnt_type
= 0;
800 if (ctx
->input_width
!= ctx
->aligned_width
||
801 ctx
->input_height
!= ctx
->aligned_height
) {
802 vseq
->frame_cropping_flag
= 1;
804 vseq
->frame_crop_left_offset
= 0;
805 vseq
->frame_crop_right_offset
=
806 (ctx
->aligned_width
- ctx
->input_width
) / 2;
807 vseq
->frame_crop_top_offset
= 0;
808 vseq
->frame_crop_bottom_offset
=
809 (ctx
->aligned_height
- ctx
->input_height
) / 2;
811 vseq
->frame_cropping_flag
= 0;
814 vseq
->vui_parameters_present_flag
= 1;
815 if (avctx
->sample_aspect_ratio
.num
!= 0) {
816 vseq
->vui_fields
.bits
.aspect_ratio_info_present_flag
= 1;
817 // There is a large enum of these which we could support
818 // individually rather than using the generic X/Y form?
819 if (avctx
->sample_aspect_ratio
.num
==
820 avctx
->sample_aspect_ratio
.den
) {
821 vseq
->aspect_ratio_idc
= 1;
823 vseq
->aspect_ratio_idc
= 255; // Extended SAR.
824 vseq
->sar_width
= avctx
->sample_aspect_ratio
.num
;
825 vseq
->sar_height
= avctx
->sample_aspect_ratio
.den
;
828 if (avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
829 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
830 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
831 mseq
->video_signal_type_present_flag
= 1;
832 mseq
->video_format
= 5; // Unspecified.
833 mseq
->video_full_range_flag
= 0;
834 mseq
->colour_description_present_flag
= 1;
835 // These enums are derived from the standard and hence
836 // we can just use the values directly.
837 mseq
->colour_primaries
= avctx
->color_primaries
;
838 mseq
->transfer_characteristics
= avctx
->color_trc
;
839 mseq
->matrix_coefficients
= avctx
->colorspace
;
842 vseq
->bits_per_second
= avctx
->bit_rate
;
844 vseq
->vui_fields
.bits
.timing_info_present_flag
= 1;
845 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
846 vseq
->num_units_in_tick
= avctx
->framerate
.num
;
847 vseq
->time_scale
= 2 * avctx
->framerate
.den
;
848 mseq
->fixed_frame_rate_flag
= 1;
850 vseq
->num_units_in_tick
= avctx
->time_base
.num
;
851 vseq
->time_scale
= 2 * avctx
->time_base
.den
;
852 mseq
->fixed_frame_rate_flag
= 0;
855 if (ctx
->va_rc_mode
== VA_RC_CBR
) {
856 priv
->send_timing_sei
= 1;
857 mseq
->nal_hrd_parameters_present_flag
= 1;
859 mseq
->cpb_cnt_minus1
= 0;
861 // Try to scale these to a sensible range so that the
862 // golomb encode of the value is not overlong.
863 mseq
->bit_rate_scale
=
864 av_clip(av_log2(avctx
->bit_rate
) - 15, 0, 15);
865 mseq
->bit_rate_value_minus1
[0] =
866 (avctx
->bit_rate
>> mseq
->bit_rate_scale
) - 1;
868 mseq
->cpb_size_scale
=
869 av_clip(av_log2(priv
->hrd_params
.hrd
.buffer_size
) - 15, 0, 15);
870 mseq
->cpb_size_value_minus1
[0] =
871 (priv
->hrd_params
.hrd
.buffer_size
>> mseq
->cpb_size_scale
) - 1;
873 // CBR mode isn't actually available here, despite naming.
874 mseq
->cbr_flag
[0] = 0;
876 mseq
->initial_cpb_removal_delay_length_minus1
= 23;
877 mseq
->cpb_removal_delay_length_minus1
= 23;
878 mseq
->dpb_output_delay_length_minus1
= 7;
879 mseq
->time_offset_length
= 0;
881 // This calculation can easily overflow 32 bits.
882 mseq
->initial_cpb_removal_delay
= 90000 *
883 (uint64_t)priv
->hrd_params
.hrd
.initial_buffer_fullness
/
884 priv
->hrd_params
.hrd
.buffer_size
;
886 mseq
->initial_cpb_removal_delay_offset
= 0;
888 priv
->send_timing_sei
= 0;
889 mseq
->nal_hrd_parameters_present_flag
= 0;
892 vseq
->intra_period
= ctx
->p_per_i
* (ctx
->b_per_p
+ 1);
893 vseq
->intra_idr_period
= vseq
->intra_period
;
894 vseq
->ip_period
= ctx
->b_per_p
+ 1;
898 vpic
->CurrPic
.picture_id
= VA_INVALID_ID
;
899 vpic
->CurrPic
.flags
= VA_PICTURE_H264_INVALID
;
901 for (i
= 0; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
902 vpic
->ReferenceFrames
[i
].picture_id
= VA_INVALID_ID
;
903 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_INVALID
;
906 vpic
->coded_buf
= VA_INVALID_ID
;
908 vpic
->pic_parameter_set_id
= 0;
909 vpic
->seq_parameter_set_id
= 0;
911 vpic
->num_ref_idx_l0_active_minus1
= 0;
912 vpic
->num_ref_idx_l1_active_minus1
= 0;
914 vpic
->pic_fields
.bits
.entropy_coding_mode_flag
=
915 ((avctx
->profile
& 0xff) != 66);
916 vpic
->pic_fields
.bits
.weighted_pred_flag
= 0;
917 vpic
->pic_fields
.bits
.weighted_bipred_idc
= 0;
918 vpic
->pic_fields
.bits
.transform_8x8_mode_flag
=
919 ((avctx
->profile
& 0xff) >= 100);
921 vpic
->pic_init_qp
= priv
->fixed_qp_idr
;
925 mseq
->profile_idc
= avctx
->profile
& 0xff;
927 if (avctx
->profile
& FF_PROFILE_H264_CONSTRAINED
)
928 mseq
->constraint_set1_flag
= 1;
929 if (avctx
->profile
& FF_PROFILE_H264_INTRA
)
930 mseq
->constraint_set3_flag
= 1;
936 static int vaapi_encode_h264_init_picture_params(AVCodecContext
*avctx
,
937 VAAPIEncodePicture
*pic
)
939 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
940 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
941 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
942 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
945 if (pic
->type
== PICTURE_TYPE_IDR
) {
946 av_assert0(pic
->display_order
== pic
->encode_order
);
948 priv
->next_frame_num
= 1;
951 vpic
->frame_num
= priv
->next_frame_num
;
952 if (pic
->type
!= PICTURE_TYPE_B
) {
954 ++priv
->next_frame_num
;
958 priv
->dpb_delay
= pic
->display_order
- pic
->encode_order
+ 1;
960 vpic
->frame_num
= vpic
->frame_num
&
961 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
)) - 1);
963 vpic
->CurrPic
.picture_id
= pic
->recon_surface
;
964 vpic
->CurrPic
.frame_idx
= vpic
->frame_num
;
965 vpic
->CurrPic
.flags
= 0;
966 vpic
->CurrPic
.TopFieldOrderCnt
= pic
->display_order
;
967 vpic
->CurrPic
.BottomFieldOrderCnt
= pic
->display_order
;
969 for (i
= 0; i
< pic
->nb_refs
; i
++) {
970 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
971 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
972 vpic
->ReferenceFrames
[i
].picture_id
= ref
->recon_surface
;
973 vpic
->ReferenceFrames
[i
].frame_idx
= ref
->encode_order
;
974 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_SHORT_TERM_REFERENCE
;
975 vpic
->ReferenceFrames
[i
].TopFieldOrderCnt
= ref
->display_order
;
976 vpic
->ReferenceFrames
[i
].BottomFieldOrderCnt
= ref
->display_order
;
978 for (; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
979 vpic
->ReferenceFrames
[i
].picture_id
= VA_INVALID_ID
;
980 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_INVALID
;
983 vpic
->coded_buf
= pic
->output_buffer
;
985 vpic
->pic_fields
.bits
.idr_pic_flag
= (pic
->type
== PICTURE_TYPE_IDR
);
986 vpic
->pic_fields
.bits
.reference_pic_flag
= (pic
->type
!= PICTURE_TYPE_B
);
993 static int vaapi_encode_h264_init_slice_params(AVCodecContext
*avctx
,
994 VAAPIEncodePicture
*pic
,
995 VAAPIEncodeSlice
*slice
)
997 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
998 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
999 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
1000 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
1001 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
1002 VAAPIEncodeH264Slice
*pslice
;
1003 VAAPIEncodeH264MiscSliceParams
*mslice
;
1006 slice
->priv_data
= av_mallocz(sizeof(*pslice
));
1007 if (!slice
->priv_data
)
1008 return AVERROR(ENOMEM
);
1009 pslice
= slice
->priv_data
;
1010 mslice
= &pslice
->misc_slice_params
;
1012 if (pic
->type
== PICTURE_TYPE_IDR
)
1013 mslice
->nal_unit_type
= NAL_IDR_SLICE
;
1015 mslice
->nal_unit_type
= NAL_SLICE
;
1017 switch (pic
->type
) {
1018 case PICTURE_TYPE_IDR
:
1019 vslice
->slice_type
= SLICE_TYPE_I
;
1020 mslice
->nal_ref_idc
= 3;
1022 case PICTURE_TYPE_I
:
1023 vslice
->slice_type
= SLICE_TYPE_I
;
1024 mslice
->nal_ref_idc
= 2;
1026 case PICTURE_TYPE_P
:
1027 vslice
->slice_type
= SLICE_TYPE_P
;
1028 mslice
->nal_ref_idc
= 1;
1030 case PICTURE_TYPE_B
:
1031 vslice
->slice_type
= SLICE_TYPE_B
;
1032 mslice
->nal_ref_idc
= 0;
1035 av_assert0(0 && "invalid picture type");
1038 // Only one slice per frame.
1039 vslice
->macroblock_address
= 0;
1040 vslice
->num_macroblocks
= priv
->mb_width
* priv
->mb_height
;
1042 vslice
->macroblock_info
= VA_INVALID_ID
;
1044 vslice
->pic_parameter_set_id
= vpic
->pic_parameter_set_id
;
1045 vslice
->idr_pic_id
= priv
->idr_pic_count
++;
1047 vslice
->pic_order_cnt_lsb
= pic
->display_order
&
1048 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_pic_order_cnt_lsb_minus4
)) - 1);
1050 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->RefPicList0
); i
++) {
1051 vslice
->RefPicList0
[i
].picture_id
= VA_INVALID_ID
;
1052 vslice
->RefPicList0
[i
].flags
= VA_PICTURE_H264_INVALID
;
1053 vslice
->RefPicList1
[i
].picture_id
= VA_INVALID_ID
;
1054 vslice
->RefPicList1
[i
].flags
= VA_PICTURE_H264_INVALID
;
1057 av_assert0(pic
->nb_refs
<= 2);
1058 if (pic
->nb_refs
>= 1) {
1059 // Backward reference for P- or B-frame.
1060 av_assert0(pic
->type
== PICTURE_TYPE_P
||
1061 pic
->type
== PICTURE_TYPE_B
);
1063 vslice
->num_ref_idx_l0_active_minus1
= 0;
1064 vslice
->RefPicList0
[0] = vpic
->ReferenceFrames
[0];
1066 if (pic
->nb_refs
>= 2) {
1067 // Forward reference for B-frame.
1068 av_assert0(pic
->type
== PICTURE_TYPE_B
);
1070 vslice
->num_ref_idx_l1_active_minus1
= 0;
1071 vslice
->RefPicList1
[0] = vpic
->ReferenceFrames
[1];
1074 if (pic
->type
== PICTURE_TYPE_B
)
1075 vslice
->slice_qp_delta
= priv
->fixed_qp_b
- vpic
->pic_init_qp
;
1076 else if (pic
->type
== PICTURE_TYPE_P
)
1077 vslice
->slice_qp_delta
= priv
->fixed_qp_p
- vpic
->pic_init_qp
;
1079 vslice
->slice_qp_delta
= priv
->fixed_qp_idr
- vpic
->pic_init_qp
;
1081 vslice
->direct_spatial_mv_pred_flag
= 1;
1086 static av_cold
int vaapi_encode_h264_init_constant_bitrate(AVCodecContext
*avctx
)
1088 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1089 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
1090 int hrd_buffer_size
;
1091 int hrd_initial_buffer_fullness
;
1093 if (avctx
->rc_buffer_size
)
1094 hrd_buffer_size
= avctx
->rc_buffer_size
;
1096 hrd_buffer_size
= avctx
->bit_rate
;
1097 if (avctx
->rc_initial_buffer_occupancy
)
1098 hrd_initial_buffer_fullness
= avctx
->rc_initial_buffer_occupancy
;
1100 hrd_initial_buffer_fullness
= hrd_buffer_size
* 3 / 4;
1102 priv
->rc_params
.misc
.type
= VAEncMiscParameterTypeRateControl
;
1103 priv
->rc_params
.rc
= (VAEncMiscParameterRateControl
) {
1104 .bits_per_second
= avctx
->bit_rate
,
1105 .target_percentage
= 66,
1106 .window_size
= 1000,
1107 .initial_qp
= (avctx
->qmax
>= 0 ? avctx
->qmax
: 40),
1108 .min_qp
= (avctx
->qmin
>= 0 ? avctx
->qmin
: 18),
1109 .basic_unit_size
= 0,
1111 ctx
->global_params
[ctx
->nb_global_params
] =
1112 &priv
->rc_params
.misc
;
1113 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1114 sizeof(priv
->rc_params
);
1116 priv
->hrd_params
.misc
.type
= VAEncMiscParameterTypeHRD
;
1117 priv
->hrd_params
.hrd
= (VAEncMiscParameterHRD
) {
1118 .initial_buffer_fullness
= hrd_initial_buffer_fullness
,
1119 .buffer_size
= hrd_buffer_size
,
1121 ctx
->global_params
[ctx
->nb_global_params
] =
1122 &priv
->hrd_params
.misc
;
1123 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1124 sizeof(priv
->hrd_params
);
1126 // These still need to be set for pic_init_qp/slice_qp_delta.
1127 priv
->fixed_qp_idr
= 26;
1128 priv
->fixed_qp_p
= 26;
1129 priv
->fixed_qp_b
= 26;
1131 av_log(avctx
, AV_LOG_DEBUG
, "Using constant-bitrate = %d bps.\n",
1136 static av_cold
int vaapi_encode_h264_init_fixed_qp(AVCodecContext
*avctx
)
1138 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1139 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
1140 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
1142 priv
->fixed_qp_p
= opt
->qp
;
1143 if (avctx
->i_quant_factor
> 0.0)
1144 priv
->fixed_qp_idr
= (int)((priv
->fixed_qp_p
* avctx
->i_quant_factor
+
1145 avctx
->i_quant_offset
) + 0.5);
1147 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
1148 if (avctx
->b_quant_factor
> 0.0)
1149 priv
->fixed_qp_b
= (int)((priv
->fixed_qp_p
* avctx
->b_quant_factor
+
1150 avctx
->b_quant_offset
) + 0.5);
1152 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
1154 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
1155 "%d / %d / %d for IDR- / P- / B-frames.\n",
1156 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
1160 static av_cold
int vaapi_encode_h264_init_internal(AVCodecContext
*avctx
)
1162 static const VAConfigAttrib default_config_attributes
[] = {
1163 { .type
= VAConfigAttribRTFormat
,
1164 .value
= VA_RT_FORMAT_YUV420
},
1165 { .type
= VAConfigAttribEncPackedHeaders
,
1166 .value
= (VA_ENC_PACKED_HEADER_SEQUENCE
|
1167 VA_ENC_PACKED_HEADER_SLICE
) },
1170 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1171 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
1172 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
1175 switch (avctx
->profile
) {
1176 case FF_PROFILE_H264_CONSTRAINED_BASELINE
:
1177 ctx
->va_profile
= VAProfileH264ConstrainedBaseline
;
1179 case FF_PROFILE_H264_BASELINE
:
1180 ctx
->va_profile
= VAProfileH264Baseline
;
1182 case FF_PROFILE_H264_MAIN
:
1183 ctx
->va_profile
= VAProfileH264Main
;
1185 case FF_PROFILE_H264_EXTENDED
:
1186 av_log(avctx
, AV_LOG_ERROR
, "H.264 extended profile "
1187 "is not supported.\n");
1188 return AVERROR_PATCHWELCOME
;
1189 case FF_PROFILE_UNKNOWN
:
1190 case FF_PROFILE_H264_HIGH
:
1191 ctx
->va_profile
= VAProfileH264High
;
1193 case FF_PROFILE_H264_HIGH_10
:
1194 case FF_PROFILE_H264_HIGH_10_INTRA
:
1195 av_log(avctx
, AV_LOG_ERROR
, "H.264 10-bit profiles "
1196 "are not supported.\n");
1197 return AVERROR_PATCHWELCOME
;
1198 case FF_PROFILE_H264_HIGH_422
:
1199 case FF_PROFILE_H264_HIGH_422_INTRA
:
1200 case FF_PROFILE_H264_HIGH_444
:
1201 case FF_PROFILE_H264_HIGH_444_PREDICTIVE
:
1202 case FF_PROFILE_H264_HIGH_444_INTRA
:
1203 case FF_PROFILE_H264_CAVLC_444
:
1204 av_log(avctx
, AV_LOG_ERROR
, "H.264 non-4:2:0 profiles "
1205 "are not supported.\n");
1206 return AVERROR_PATCHWELCOME
;
1208 av_log(avctx
, AV_LOG_ERROR
, "Unknown H.264 profile %d.\n",
1210 return AVERROR(EINVAL
);
1212 if (opt
->low_power
) {
1213 #if VA_CHECK_VERSION(0, 39, 1)
1214 ctx
->va_entrypoint
= VAEntrypointEncSliceLP
;
1216 av_log(avctx
, AV_LOG_ERROR
, "Low-power encoding is not "
1217 "supported with this VAAPI version.\n");
1218 return AVERROR(EINVAL
);
1221 ctx
->va_entrypoint
= VAEntrypointEncSlice
;
1224 ctx
->input_width
= avctx
->width
;
1225 ctx
->input_height
= avctx
->height
;
1226 ctx
->aligned_width
= FFALIGN(ctx
->input_width
, 16);
1227 ctx
->aligned_height
= FFALIGN(ctx
->input_height
, 16);
1228 priv
->mb_width
= ctx
->aligned_width
/ 16;
1229 priv
->mb_height
= ctx
->aligned_height
/ 16;
1231 for (i
= 0; i
< FF_ARRAY_ELEMS(default_config_attributes
); i
++) {
1232 ctx
->config_attributes
[ctx
->nb_config_attributes
++] =
1233 default_config_attributes
[i
];
1236 if (avctx
->bit_rate
> 0) {
1237 ctx
->va_rc_mode
= VA_RC_CBR
;
1238 err
= vaapi_encode_h264_init_constant_bitrate(avctx
);
1240 ctx
->va_rc_mode
= VA_RC_CQP
;
1241 err
= vaapi_encode_h264_init_fixed_qp(avctx
);
1246 ctx
->config_attributes
[ctx
->nb_config_attributes
++] = (VAConfigAttrib
) {
1247 .type
= VAConfigAttribRateControl
,
1248 .value
= ctx
->va_rc_mode
,
1251 if (opt
->quality
> 0) {
1252 #if VA_CHECK_VERSION(0, 36, 0)
1253 priv
->quality_params
.misc
.type
=
1254 VAEncMiscParameterTypeQualityLevel
;
1255 priv
->quality_params
.quality
.quality_level
= opt
->quality
;
1257 ctx
->global_params
[ctx
->nb_global_params
] =
1258 &priv
->quality_params
.misc
;
1259 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1260 sizeof(priv
->quality_params
);
1262 av_log(avctx
, AV_LOG_WARNING
, "The encode quality option is not "
1263 "supported with this VAAPI version.\n");
1267 ctx
->nb_recon_frames
= 20;
1272 static VAAPIEncodeType vaapi_encode_type_h264
= {
1273 .priv_data_size
= sizeof(VAAPIEncodeH264Context
),
1275 .init
= &vaapi_encode_h264_init_internal
,
1277 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferH264
),
1278 .init_sequence_params
= &vaapi_encode_h264_init_sequence_params
,
1280 .picture_params_size
= sizeof(VAEncPictureParameterBufferH264
),
1281 .init_picture_params
= &vaapi_encode_h264_init_picture_params
,
1283 .slice_params_size
= sizeof(VAEncSliceParameterBufferH264
),
1284 .init_slice_params
= &vaapi_encode_h264_init_slice_params
,
1286 .sequence_header_type
= VAEncPackedHeaderSequence
,
1287 .write_sequence_header
= &vaapi_encode_h264_write_sequence_header
,
1289 .slice_header_type
= VAEncPackedHeaderH264_Slice
,
1290 .write_slice_header
= &vaapi_encode_h264_write_slice_header
,
1292 .write_extra_header
= &vaapi_encode_h264_write_extra_header
,
1295 static av_cold
int vaapi_encode_h264_init(AVCodecContext
*avctx
)
1297 return ff_vaapi_encode_init(avctx
, &vaapi_encode_type_h264
);
1300 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
1301 offsetof(VAAPIEncodeH264Options, x))
1302 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1303 static const AVOption vaapi_encode_h264_options
[] = {
1304 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1305 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 20 }, 0, 52, FLAGS
},
1306 { "quality", "Set encode quality (trades off against speed, higher is faster)",
1307 OFFSET(quality
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 8, FLAGS
},
1308 { "low_power", "Use low-power encoding mode (experimental: only supported "
1309 "on some platforms, does not support all features)",
1310 OFFSET(low_power
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, FLAGS
},
1314 static const AVCodecDefault vaapi_encode_h264_defaults
[] = {
1315 { "profile", "100" },
1320 { "i_qfactor", "1.0" },
1321 { "i_qoffset", "0.0" },
1322 { "b_qfactor", "1.2" },
1323 { "b_qoffset", "0.0" },
1327 static const AVClass vaapi_encode_h264_class
= {
1328 .class_name
= "h264_vaapi",
1329 .item_name
= av_default_item_name
,
1330 .option
= vaapi_encode_h264_options
,
1331 .version
= LIBAVUTIL_VERSION_INT
,
1334 AVCodec ff_h264_vaapi_encoder
= {
1335 .name
= "h264_vaapi",
1336 .long_name
= NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
1337 .type
= AVMEDIA_TYPE_VIDEO
,
1338 .id
= AV_CODEC_ID_H264
,
1339 .priv_data_size
= (sizeof(VAAPIEncodeContext
) +
1340 sizeof(VAAPIEncodeH264Options
)),
1341 .init
= &vaapi_encode_h264_init
,
1342 .encode2
= &ff_vaapi_encode2
,
1343 .close
= &ff_vaapi_encode_close
,
1344 .priv_class
= &vaapi_encode_h264_class
,
1345 .capabilities
= AV_CODEC_CAP_DELAY
,
1346 .defaults
= vaapi_encode_h264_defaults
,
1347 .pix_fmts
= (const enum AVPixelFormat
[]) {