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
;
88 char motion_vectors_over_pic_boundaries_flag
;
89 unsigned int max_bytes_per_pic_denom
;
90 unsigned int max_bits_per_mb_denom
;
91 unsigned int max_num_reorder_frames
;
92 unsigned int max_dec_pic_buffering
;
94 unsigned int cpb_cnt_minus1
;
95 unsigned int bit_rate_scale
;
96 unsigned int cpb_size_scale
;
97 unsigned int bit_rate_value_minus1
[32];
98 unsigned int cpb_size_value_minus1
[32];
100 unsigned int initial_cpb_removal_delay_length_minus1
;
101 unsigned int cpb_removal_delay_length_minus1
;
102 unsigned int dpb_output_delay_length_minus1
;
103 unsigned int time_offset_length
;
105 unsigned int initial_cpb_removal_delay
;
106 unsigned int initial_cpb_removal_delay_offset
;
108 unsigned int pic_struct
;
109 } VAAPIEncodeH264MiscSequenceParams
;
111 // This structure contains all possibly-useful per-slice syntax elements
112 // which are not already contained in the various VAAPI structures.
113 typedef struct VAAPIEncodeH264MiscSliceParams
{
114 unsigned int nal_unit_type
;
115 unsigned int nal_ref_idc
;
117 unsigned int colour_plane_id
;
119 char bottom_field_flag
;
121 unsigned int redundant_pic_cnt
;
123 char sp_for_switch_flag
;
126 char ref_pic_list_modification_flag_l0
;
127 char ref_pic_list_modification_flag_l1
;
129 char no_output_of_prior_pics_flag
;
130 char long_term_reference_flag
;
131 char adaptive_ref_pic_marking_mode_flag
;
132 } VAAPIEncodeH264MiscSliceParams
;
134 typedef struct VAAPIEncodeH264Slice
{
135 VAAPIEncodeH264MiscSliceParams misc_slice_params
;
136 } VAAPIEncodeH264Slice
;
138 typedef struct VAAPIEncodeH264Context
{
139 VAAPIEncodeH264MiscSequenceParams misc_sequence_params
;
149 int64_t last_idr_frame
;
150 int64_t idr_pic_count
;
155 // Rate control configuration.
158 #if VA_CHECK_VERSION(0, 36, 0)
159 // Speed-quality tradeoff setting.
161 VAEncMiscParameterBuffer misc
;
162 VAEncMiscParameterBufferQualityLevel quality
;
165 } VAAPIEncodeH264Context
;
167 typedef struct VAAPIEncodeH264Options
{
171 } VAAPIEncodeH264Options
;
174 #define vseq_var(name) vseq->name, name
175 #define vseq_field(name) vseq->seq_fields.bits.name, name
176 #define vvui_field(name) vseq->vui_fields.bits.name, name
177 #define vpic_var(name) vpic->name, name
178 #define vpic_field(name) vpic->pic_fields.bits.name, name
179 #define vslice_var(name) vslice->name, name
180 #define vslice_field(name) vslice->slice_fields.bits.name, name
181 #define mseq_var(name) mseq->name, name
182 #define mslice_var(name) mslice->name, name
184 static void vaapi_encode_h264_write_nal_header(PutBitContext
*pbc
,
185 int nal_unit_type
, int nal_ref_idc
)
187 u(1, 0, forbidden_zero_bit
);
188 u(2, nal_ref_idc
, nal_ref_idc
);
189 u(5, nal_unit_type
, nal_unit_type
);
192 static void vaapi_encode_h264_write_trailing_rbsp(PutBitContext
*pbc
)
194 u(1, 1, rbsp_stop_one_bit
);
195 while (put_bits_count(pbc
) & 7)
196 u(1, 0, rbsp_alignment_zero_bit
);
199 static void vaapi_encode_h264_write_vui(PutBitContext
*pbc
,
200 VAAPIEncodeContext
*ctx
)
202 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
203 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
204 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
207 u(1, vvui_field(aspect_ratio_info_present_flag
));
208 if (vseq
->vui_fields
.bits
.aspect_ratio_info_present_flag
) {
209 u(8, vseq_var(aspect_ratio_idc
));
210 if (vseq
->aspect_ratio_idc
== 255) {
211 u(16, vseq_var(sar_width
));
212 u(16, vseq_var(sar_height
));
216 u(1, mseq_var(overscan_info_present_flag
));
217 if (mseq
->overscan_info_present_flag
)
218 u(1, mseq_var(overscan_appropriate_flag
));
220 u(1, mseq_var(video_signal_type_present_flag
));
221 if (mseq
->video_signal_type_present_flag
) {
222 u(3, mseq_var(video_format
));
223 u(1, mseq_var(video_full_range_flag
));
224 u(1, mseq_var(colour_description_present_flag
));
225 if (mseq
->colour_description_present_flag
) {
226 u(8, mseq_var(colour_primaries
));
227 u(8, mseq_var(transfer_characteristics
));
228 u(8, mseq_var(matrix_coefficients
));
232 u(1, mseq_var(chroma_loc_info_present_flag
));
233 if (mseq
->chroma_loc_info_present_flag
) {
234 ue(mseq_var(chroma_sample_loc_type_top_field
));
235 ue(mseq_var(chroma_sample_loc_type_bottom_field
));
238 u(1, vvui_field(timing_info_present_flag
));
239 if (vseq
->vui_fields
.bits
.timing_info_present_flag
) {
240 u(32, vseq_var(num_units_in_tick
));
241 u(32, vseq_var(time_scale
));
242 u(1, mseq_var(fixed_frame_rate_flag
));
245 u(1, mseq_var(nal_hrd_parameters_present_flag
));
246 if (mseq
->nal_hrd_parameters_present_flag
) {
247 ue(mseq_var(cpb_cnt_minus1
));
248 u(4, mseq_var(bit_rate_scale
));
249 u(4, mseq_var(cpb_size_scale
));
250 for (i
= 0; i
<= mseq
->cpb_cnt_minus1
; i
++) {
251 ue(mseq_var(bit_rate_value_minus1
[i
]));
252 ue(mseq_var(cpb_size_value_minus1
[i
]));
253 u(1, mseq_var(cbr_flag
[i
]));
255 u(5, mseq_var(initial_cpb_removal_delay_length_minus1
));
256 u(5, mseq_var(cpb_removal_delay_length_minus1
));
257 u(5, mseq_var(dpb_output_delay_length_minus1
));
258 u(5, mseq_var(time_offset_length
));
260 u(1, mseq_var(vcl_hrd_parameters_present_flag
));
261 if (mseq
->vcl_hrd_parameters_present_flag
) {
262 av_assert0(0 && "vcl hrd parameters not supported");
265 if (mseq
->nal_hrd_parameters_present_flag
||
266 mseq
->vcl_hrd_parameters_present_flag
)
267 u(1, mseq_var(low_delay_hrd_flag
));
268 u(1, mseq_var(pic_struct_present_flag
));
270 u(1, vvui_field(bitstream_restriction_flag
));
271 if (vseq
->vui_fields
.bits
.bitstream_restriction_flag
) {
272 u(1, mseq_var(motion_vectors_over_pic_boundaries_flag
));
273 ue(mseq_var(max_bytes_per_pic_denom
));
274 ue(mseq_var(max_bits_per_mb_denom
));
275 ue(vvui_field(log2_max_mv_length_horizontal
));
276 ue(vvui_field(log2_max_mv_length_vertical
));
277 ue(mseq_var(max_num_reorder_frames
));
278 ue(mseq_var(max_dec_pic_buffering
));
282 static void vaapi_encode_h264_write_sps(PutBitContext
*pbc
,
283 VAAPIEncodeContext
*ctx
)
285 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
286 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
287 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
290 vaapi_encode_h264_write_nal_header(pbc
, H264_NAL_SPS
, 3);
292 u(8, mseq_var(profile_idc
));
293 u(1, mseq_var(constraint_set0_flag
));
294 u(1, mseq_var(constraint_set1_flag
));
295 u(1, mseq_var(constraint_set2_flag
));
296 u(1, mseq_var(constraint_set3_flag
));
297 u(1, mseq_var(constraint_set4_flag
));
298 u(1, mseq_var(constraint_set5_flag
));
299 u(2, 0, reserved_zero_2bits
);
301 u(8, vseq_var(level_idc
));
303 ue(vseq_var(seq_parameter_set_id
));
305 if (mseq
->profile_idc
== 100 || mseq
->profile_idc
== 110 ||
306 mseq
->profile_idc
== 122 || mseq
->profile_idc
== 244 ||
307 mseq
->profile_idc
== 44 || mseq
->profile_idc
== 83 ||
308 mseq
->profile_idc
== 86 || mseq
->profile_idc
== 118 ||
309 mseq
->profile_idc
== 128 || mseq
->profile_idc
== 138) {
310 ue(vseq_field(chroma_format_idc
));
312 if (vseq
->seq_fields
.bits
.chroma_format_idc
== 3)
313 u(1, mseq_var(separate_colour_plane_flag
));
315 ue(vseq_var(bit_depth_luma_minus8
));
316 ue(vseq_var(bit_depth_chroma_minus8
));
318 u(1, mseq_var(qpprime_y_zero_transform_bypass_flag
));
320 u(1, vseq_field(seq_scaling_matrix_present_flag
));
321 if (vseq
->seq_fields
.bits
.seq_scaling_matrix_present_flag
) {
322 av_assert0(0 && "scaling matrices not supported");
326 ue(vseq_field(log2_max_frame_num_minus4
));
327 ue(vseq_field(pic_order_cnt_type
));
329 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 0) {
330 ue(vseq_field(log2_max_pic_order_cnt_lsb_minus4
));
331 } else if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 1) {
332 u(1, mseq_var(delta_pic_order_always_zero_flag
));
333 se(vseq_var(offset_for_non_ref_pic
));
334 se(vseq_var(offset_for_top_to_bottom_field
));
335 ue(vseq_var(num_ref_frames_in_pic_order_cnt_cycle
));
337 for (i
= 0; i
< vseq
->num_ref_frames_in_pic_order_cnt_cycle
; i
++)
338 se(vseq_var(offset_for_ref_frame
[i
]));
341 ue(vseq_var(max_num_ref_frames
));
342 u(1, mseq_var(gaps_in_frame_num_allowed_flag
));
344 ue(vseq
->picture_width_in_mbs
- 1, pic_width_in_mbs_minus1
);
345 ue(vseq
->picture_height_in_mbs
- 1, pic_height_in_mbs_minus1
);
347 u(1, vseq_field(frame_mbs_only_flag
));
348 if (!vseq
->seq_fields
.bits
.frame_mbs_only_flag
)
349 u(1, vseq_field(mb_adaptive_frame_field_flag
));
351 u(1, vseq_field(direct_8x8_inference_flag
));
353 u(1, vseq_var(frame_cropping_flag
));
354 if (vseq
->frame_cropping_flag
) {
355 ue(vseq_var(frame_crop_left_offset
));
356 ue(vseq_var(frame_crop_right_offset
));
357 ue(vseq_var(frame_crop_top_offset
));
358 ue(vseq_var(frame_crop_bottom_offset
));
361 u(1, vseq_var(vui_parameters_present_flag
));
362 if (vseq
->vui_parameters_present_flag
)
363 vaapi_encode_h264_write_vui(pbc
, ctx
);
365 vaapi_encode_h264_write_trailing_rbsp(pbc
);
368 static void vaapi_encode_h264_write_pps(PutBitContext
*pbc
,
369 VAAPIEncodeContext
*ctx
)
371 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
372 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
373 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
375 vaapi_encode_h264_write_nal_header(pbc
, H264_NAL_PPS
, 3);
377 ue(vpic_var(pic_parameter_set_id
));
378 ue(vpic_var(seq_parameter_set_id
));
380 u(1, vpic_field(entropy_coding_mode_flag
));
381 u(1, mseq_var(bottom_field_pic_order_in_frame_present_flag
));
383 ue(mseq_var(num_slice_groups_minus1
));
384 if (mseq
->num_slice_groups_minus1
> 0) {
385 ue(mseq_var(slice_group_map_type
));
386 av_assert0(0 && "slice groups not supported");
389 ue(vpic_var(num_ref_idx_l0_active_minus1
));
390 ue(vpic_var(num_ref_idx_l1_active_minus1
));
392 u(1, vpic_field(weighted_pred_flag
));
393 u(2, vpic_field(weighted_bipred_idc
));
395 se(vpic
->pic_init_qp
- 26, pic_init_qp_minus26
);
396 se(mseq_var(pic_init_qs_minus26
));
397 se(vpic_var(chroma_qp_index_offset
));
399 u(1, vpic_field(deblocking_filter_control_present_flag
));
400 u(1, vpic_field(constrained_intra_pred_flag
));
401 u(1, vpic_field(redundant_pic_cnt_present_flag
));
402 u(1, vpic_field(transform_8x8_mode_flag
));
404 u(1, vpic_field(pic_scaling_matrix_present_flag
));
405 if (vpic
->pic_fields
.bits
.pic_scaling_matrix_present_flag
) {
406 av_assert0(0 && "scaling matrices not supported");
409 se(vpic_var(second_chroma_qp_index_offset
));
411 vaapi_encode_h264_write_trailing_rbsp(pbc
);
414 static void vaapi_encode_h264_write_slice_header2(PutBitContext
*pbc
,
415 VAAPIEncodeContext
*ctx
,
416 VAAPIEncodePicture
*pic
,
417 VAAPIEncodeSlice
*slice
)
419 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
420 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
421 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
422 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
423 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
424 VAAPIEncodeH264Slice
*pslice
= slice
->priv_data
;
425 VAAPIEncodeH264MiscSliceParams
*mslice
= &pslice
->misc_slice_params
;
427 vaapi_encode_h264_write_nal_header(pbc
, mslice
->nal_unit_type
,
428 mslice
->nal_ref_idc
);
430 ue(vslice
->macroblock_address
, first_mb_in_slice
);
431 ue(vslice_var(slice_type
));
432 ue(vpic_var(pic_parameter_set_id
));
434 if (mseq
->separate_colour_plane_flag
) {
435 u(2, mslice_var(colour_plane_id
));
438 u(4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
,
440 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
)) - 1)),
443 if (!vseq
->seq_fields
.bits
.frame_mbs_only_flag
) {
444 u(1, mslice_var(field_pic_flag
));
445 if (mslice
->field_pic_flag
)
446 u(1, mslice_var(bottom_field_flag
));
449 if (vpic
->pic_fields
.bits
.idr_pic_flag
) {
450 ue(vslice_var(idr_pic_id
));
453 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 0) {
454 u(4 + vseq
->seq_fields
.bits
.log2_max_pic_order_cnt_lsb_minus4
,
455 vslice_var(pic_order_cnt_lsb
));
456 if (mseq
->bottom_field_pic_order_in_frame_present_flag
&&
457 !mslice
->field_pic_flag
) {
458 se(vslice_var(delta_pic_order_cnt_bottom
));
462 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 1 &&
463 !vseq
->seq_fields
.bits
.delta_pic_order_always_zero_flag
) {
464 se(vslice_var(delta_pic_order_cnt
[0]));
465 if (mseq
->bottom_field_pic_order_in_frame_present_flag
&&
466 !mslice
->field_pic_flag
) {
467 se(vslice_var(delta_pic_order_cnt
[1]));
471 if (vpic
->pic_fields
.bits
.redundant_pic_cnt_present_flag
) {
472 ue(mslice_var(redundant_pic_cnt
));
475 if (vslice
->slice_type
== SLICE_TYPE_B
) {
476 u(1, vslice_var(direct_spatial_mv_pred_flag
));
479 if (vslice
->slice_type
== SLICE_TYPE_P
||
480 vslice
->slice_type
== SLICE_TYPE_SP
||
481 vslice
->slice_type
== SLICE_TYPE_B
) {
482 u(1, vslice_var(num_ref_idx_active_override_flag
));
483 if (vslice
->num_ref_idx_active_override_flag
) {
484 ue(vslice_var(num_ref_idx_l0_active_minus1
));
485 if (vslice
->slice_type
== SLICE_TYPE_B
)
486 ue(vslice_var(num_ref_idx_l1_active_minus1
));
490 if (mslice
->nal_unit_type
== 20 || mslice
->nal_unit_type
== 21) {
491 av_assert0(0 && "no MVC support");
493 if (vslice
->slice_type
% 5 != 2 && vslice
->slice_type
% 5 != 4) {
494 u(1, mslice_var(ref_pic_list_modification_flag_l0
));
495 if (mslice
->ref_pic_list_modification_flag_l0
) {
496 av_assert0(0 && "ref pic list modification");
499 if (vslice
->slice_type
% 5 == 1) {
500 u(1, mslice_var(ref_pic_list_modification_flag_l1
));
501 if (mslice
->ref_pic_list_modification_flag_l1
) {
502 av_assert0(0 && "ref pic list modification");
507 if ((vpic
->pic_fields
.bits
.weighted_pred_flag
&&
508 (vslice
->slice_type
== SLICE_TYPE_P
||
509 vslice
->slice_type
== SLICE_TYPE_SP
)) ||
510 (vpic
->pic_fields
.bits
.weighted_bipred_idc
== 1 &&
511 vslice
->slice_type
== SLICE_TYPE_B
)) {
512 av_assert0(0 && "prediction weights not supported");
515 av_assert0(mslice
->nal_ref_idc
> 0 ==
516 vpic
->pic_fields
.bits
.reference_pic_flag
);
517 if (mslice
->nal_ref_idc
!= 0) {
518 if (vpic
->pic_fields
.bits
.idr_pic_flag
) {
519 u(1, mslice_var(no_output_of_prior_pics_flag
));
520 u(1, mslice_var(long_term_reference_flag
));
522 u(1, mslice_var(adaptive_ref_pic_marking_mode_flag
));
523 if (mslice
->adaptive_ref_pic_marking_mode_flag
) {
524 av_assert0(0 && "MMCOs not supported");
529 if (vpic
->pic_fields
.bits
.entropy_coding_mode_flag
&&
530 vslice
->slice_type
!= SLICE_TYPE_I
&&
531 vslice
->slice_type
!= SLICE_TYPE_SI
) {
532 ue(vslice_var(cabac_init_idc
));
535 se(vslice_var(slice_qp_delta
));
536 if (vslice
->slice_type
== SLICE_TYPE_SP
||
537 vslice
->slice_type
== SLICE_TYPE_SI
) {
538 if (vslice
->slice_type
== SLICE_TYPE_SP
)
539 u(1, mslice_var(sp_for_switch_flag
));
540 se(mslice_var(slice_qs_delta
));
543 if (vpic
->pic_fields
.bits
.deblocking_filter_control_present_flag
) {
544 ue(vslice_var(disable_deblocking_filter_idc
));
545 if (vslice
->disable_deblocking_filter_idc
!= 1) {
546 se(vslice_var(slice_alpha_c0_offset_div2
));
547 se(vslice_var(slice_beta_offset_div2
));
551 if (mseq
->num_slice_groups_minus1
> 0 &&
552 mseq
->slice_group_map_type
>= 3 && mseq
->slice_group_map_type
<= 5) {
553 av_assert0(0 && "slice groups not supported");
556 // No alignment - this need not be a byte boundary.
559 static void vaapi_encode_h264_write_buffering_period(PutBitContext
*pbc
,
560 VAAPIEncodeContext
*ctx
,
561 VAAPIEncodePicture
*pic
)
563 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
564 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
565 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
568 ue(vpic_var(seq_parameter_set_id
));
570 if (mseq
->nal_hrd_parameters_present_flag
) {
571 for (i
= 0; i
<= mseq
->cpb_cnt_minus1
; i
++) {
572 u(mseq
->initial_cpb_removal_delay_length_minus1
+ 1,
573 mseq_var(initial_cpb_removal_delay
));
574 u(mseq
->initial_cpb_removal_delay_length_minus1
+ 1,
575 mseq_var(initial_cpb_removal_delay_offset
));
578 if (mseq
->vcl_hrd_parameters_present_flag
) {
579 av_assert0(0 && "vcl hrd parameters not supported");
583 static void vaapi_encode_h264_write_pic_timing(PutBitContext
*pbc
,
584 VAAPIEncodeContext
*ctx
,
585 VAAPIEncodePicture
*pic
)
587 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
588 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
589 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
592 if (mseq
->nal_hrd_parameters_present_flag
||
593 mseq
->vcl_hrd_parameters_present_flag
) {
594 u(mseq
->cpb_removal_delay_length_minus1
+ 1,
595 2 * vseq
->num_units_in_tick
* priv
->cpb_delay
,
597 u(mseq
->dpb_output_delay_length_minus1
+ 1,
598 2 * vseq
->num_units_in_tick
* priv
->dpb_delay
,
601 if (mseq
->pic_struct_present_flag
) {
602 u(4, mseq_var(pic_struct
));
603 num_clock_ts
= (mseq
->pic_struct
<= 2 ?
1 :
604 mseq
->pic_struct
<= 4 ?
2 :
605 mseq
->pic_struct
<= 8 ?
3 : 0);
606 for (i
= 0; i
< num_clock_ts
; i
++) {
607 u(1, 0, clock_timestamp_flag
[i
]);
608 // No full timestamp information.
613 static void vaapi_encode_h264_write_identifier(PutBitContext
*pbc
,
614 VAAPIEncodeContext
*ctx
,
615 VAAPIEncodePicture
*pic
)
617 const char *lavc
= LIBAVCODEC_IDENT
;
618 const char *vaapi
= VA_VERSION_S
;
619 const char *driver
= vaQueryVendorString(ctx
->hwctx
->display
);
623 // Random (version 4) ISO 11578 UUID.
625 0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf,
626 0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d,
629 for (i
= 0; i
< 16; i
++)
630 u(8, uuid
[i
], uuid_iso_iec_11578
);
632 snprintf(tmp
, sizeof(tmp
), "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
633 for (i
= 0; i
< sizeof(tmp
) && tmp
[i
]; i
++)
634 u(8, tmp
[i
], user_data_payload_byte
);
637 static void vaapi_encode_h264_write_sei(PutBitContext
*pbc
,
638 VAAPIEncodeContext
*ctx
,
639 VAAPIEncodePicture
*pic
)
641 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
642 PutBitContext payload_bits
;
644 int payload_type
, payload_size
, i
;
645 void (*write_payload
)(PutBitContext
*pbc
,
646 VAAPIEncodeContext
*ctx
,
647 VAAPIEncodePicture
*pic
) = NULL
;
649 vaapi_encode_h264_write_nal_header(pbc
, H264_NAL_SEI
, 0);
651 for (payload_type
= 0; payload_type
< 64; payload_type
++) {
652 switch (payload_type
) {
653 case SEI_TYPE_BUFFERING_PERIOD
:
654 if (!priv
->send_timing_sei
||
655 pic
->type
!= PICTURE_TYPE_IDR
)
657 write_payload
= &vaapi_encode_h264_write_buffering_period
;
659 case SEI_TYPE_PIC_TIMING
:
660 if (!priv
->send_timing_sei
)
662 write_payload
= &vaapi_encode_h264_write_pic_timing
;
664 case SEI_TYPE_USER_DATA_UNREGISTERED
:
665 if (pic
->encode_order
!= 0)
667 write_payload
= &vaapi_encode_h264_write_identifier
;
673 init_put_bits(&payload_bits
, payload
, sizeof(payload
));
674 write_payload(&payload_bits
, ctx
, pic
);
675 if (put_bits_count(&payload_bits
) & 7) {
676 write_u(&payload_bits
, 1, 1, bit_equal_to_one
);
677 while (put_bits_count(&payload_bits
) & 7)
678 write_u(&payload_bits
, 1, 0, bit_equal_to_zero
);
680 payload_size
= put_bits_count(&payload_bits
) / 8;
681 flush_put_bits(&payload_bits
);
683 u(8, payload_type
, last_payload_type_byte
);
684 u(8, payload_size
, last_payload_size_byte
);
685 for (i
= 0; i
< payload_size
; i
++)
686 u(8, payload
[i
] & 0xff, sei_payload
);
689 vaapi_encode_h264_write_trailing_rbsp(pbc
);
692 static int vaapi_encode_h264_write_sequence_header(AVCodecContext
*avctx
,
693 char *data
, size_t *data_len
)
695 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
699 size_t nal_len
, bit_len
, bit_pos
, next_len
;
704 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
705 vaapi_encode_h264_write_sps(&pbc
, ctx
);
706 nal_len
= put_bits_count(&pbc
);
707 flush_put_bits(&pbc
);
709 next_len
= bit_len
- bit_pos
;
710 err
= ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
+ bit_pos
/ 8,
717 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
718 vaapi_encode_h264_write_pps(&pbc
, ctx
);
719 nal_len
= put_bits_count(&pbc
);
720 flush_put_bits(&pbc
);
722 next_len
= bit_len
- bit_pos
;
723 err
= ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
+ bit_pos
/ 8,
734 static int vaapi_encode_h264_write_slice_header(AVCodecContext
*avctx
,
735 VAAPIEncodePicture
*pic
,
736 VAAPIEncodeSlice
*slice
,
737 char *data
, size_t *data_len
)
739 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
744 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
745 vaapi_encode_h264_write_slice_header2(&pbc
, ctx
, pic
, slice
);
746 header_len
= put_bits_count(&pbc
);
747 flush_put_bits(&pbc
);
749 return ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
, data_len
,
753 static int vaapi_encode_h264_write_extra_header(AVCodecContext
*avctx
,
754 VAAPIEncodePicture
*pic
,
755 int index
, int *type
,
756 char *data
, size_t *data_len
)
758 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
763 if (index
== 0 && ctx
->va_rc_mode
== VA_RC_CBR
) {
764 *type
= VAEncPackedHeaderH264_SEI
;
766 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
767 vaapi_encode_h264_write_sei(&pbc
, ctx
, pic
);
768 header_len
= put_bits_count(&pbc
);
769 flush_put_bits(&pbc
);
771 return ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
, data_len
,
779 static int vaapi_encode_h264_init_sequence_params(AVCodecContext
*avctx
)
781 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
782 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
783 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
784 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
785 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
789 vseq
->seq_parameter_set_id
= 0;
791 vseq
->level_idc
= avctx
->level
;
793 vseq
->max_num_ref_frames
= 1 + (avctx
->max_b_frames
> 0);
795 vseq
->picture_width_in_mbs
= priv
->mb_width
;
796 vseq
->picture_height_in_mbs
= priv
->mb_height
;
798 vseq
->seq_fields
.bits
.chroma_format_idc
= 1;
799 vseq
->seq_fields
.bits
.frame_mbs_only_flag
= 1;
800 vseq
->seq_fields
.bits
.direct_8x8_inference_flag
= 1;
801 vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
= 4;
802 vseq
->seq_fields
.bits
.pic_order_cnt_type
= 0;
804 if (avctx
->width
!= ctx
->surface_width
||
805 avctx
->height
!= ctx
->surface_height
) {
806 vseq
->frame_cropping_flag
= 1;
808 vseq
->frame_crop_left_offset
= 0;
809 vseq
->frame_crop_right_offset
=
810 (ctx
->surface_width
- avctx
->width
) / 2;
811 vseq
->frame_crop_top_offset
= 0;
812 vseq
->frame_crop_bottom_offset
=
813 (ctx
->surface_height
- avctx
->height
) / 2;
815 vseq
->frame_cropping_flag
= 0;
818 vseq
->vui_parameters_present_flag
= 1;
819 if (avctx
->sample_aspect_ratio
.num
!= 0) {
820 vseq
->vui_fields
.bits
.aspect_ratio_info_present_flag
= 1;
821 // There is a large enum of these which we could support
822 // individually rather than using the generic X/Y form?
823 if (avctx
->sample_aspect_ratio
.num
==
824 avctx
->sample_aspect_ratio
.den
) {
825 vseq
->aspect_ratio_idc
= 1;
827 vseq
->aspect_ratio_idc
= 255; // Extended SAR.
828 vseq
->sar_width
= avctx
->sample_aspect_ratio
.num
;
829 vseq
->sar_height
= avctx
->sample_aspect_ratio
.den
;
832 if (avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
833 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
834 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
835 mseq
->video_signal_type_present_flag
= 1;
836 mseq
->video_format
= 5; // Unspecified.
837 mseq
->video_full_range_flag
= 0;
838 mseq
->colour_description_present_flag
= 1;
839 // These enums are derived from the standard and hence
840 // we can just use the values directly.
841 mseq
->colour_primaries
= avctx
->color_primaries
;
842 mseq
->transfer_characteristics
= avctx
->color_trc
;
843 mseq
->matrix_coefficients
= avctx
->colorspace
;
846 vseq
->vui_fields
.bits
.bitstream_restriction_flag
= 1;
847 mseq
->motion_vectors_over_pic_boundaries_flag
= 1;
848 mseq
->max_bytes_per_pic_denom
= 0;
849 mseq
->max_bits_per_mb_denom
= 0;
850 vseq
->vui_fields
.bits
.log2_max_mv_length_horizontal
= 16;
851 vseq
->vui_fields
.bits
.log2_max_mv_length_vertical
= 16;
853 mseq
->max_num_reorder_frames
= (avctx
->max_b_frames
> 0);
854 mseq
->max_dec_pic_buffering
= vseq
->max_num_ref_frames
;
856 vseq
->bits_per_second
= avctx
->bit_rate
;
858 vseq
->vui_fields
.bits
.timing_info_present_flag
= 1;
859 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
860 vseq
->num_units_in_tick
= avctx
->framerate
.den
;
861 vseq
->time_scale
= 2 * avctx
->framerate
.num
;
862 mseq
->fixed_frame_rate_flag
= 1;
864 vseq
->num_units_in_tick
= avctx
->time_base
.num
;
865 vseq
->time_scale
= 2 * avctx
->time_base
.den
;
866 mseq
->fixed_frame_rate_flag
= 0;
869 if (ctx
->va_rc_mode
== VA_RC_CBR
) {
870 priv
->send_timing_sei
= 1;
871 mseq
->nal_hrd_parameters_present_flag
= 1;
873 mseq
->cpb_cnt_minus1
= 0;
875 // Try to scale these to a sensible range so that the
876 // golomb encode of the value is not overlong.
877 mseq
->bit_rate_scale
=
878 av_clip_uintp2(av_log2(avctx
->bit_rate
) - 15 - 6, 4);
879 mseq
->bit_rate_value_minus1
[0] =
880 (avctx
->bit_rate
>> mseq
->bit_rate_scale
+ 6) - 1;
882 mseq
->cpb_size_scale
=
883 av_clip_uintp2(av_log2(ctx
->hrd_params
.hrd
.buffer_size
) - 15 - 4, 4);
884 mseq
->cpb_size_value_minus1
[0] =
885 (ctx
->hrd_params
.hrd
.buffer_size
>> mseq
->cpb_size_scale
+ 4) - 1;
887 // CBR mode isn't actually available here, despite naming.
888 mseq
->cbr_flag
[0] = 0;
890 mseq
->initial_cpb_removal_delay_length_minus1
= 23;
891 mseq
->cpb_removal_delay_length_minus1
= 23;
892 mseq
->dpb_output_delay_length_minus1
= 7;
893 mseq
->time_offset_length
= 0;
895 // This calculation can easily overflow 32 bits.
896 mseq
->initial_cpb_removal_delay
= 90000 *
897 (uint64_t)ctx
->hrd_params
.hrd
.initial_buffer_fullness
/
898 ctx
->hrd_params
.hrd
.buffer_size
;
900 mseq
->initial_cpb_removal_delay_offset
= 0;
902 priv
->send_timing_sei
= 0;
903 mseq
->nal_hrd_parameters_present_flag
= 0;
906 vseq
->intra_period
= ctx
->p_per_i
* (ctx
->b_per_p
+ 1);
907 vseq
->intra_idr_period
= vseq
->intra_period
;
908 vseq
->ip_period
= ctx
->b_per_p
+ 1;
912 vpic
->CurrPic
.picture_id
= VA_INVALID_ID
;
913 vpic
->CurrPic
.flags
= VA_PICTURE_H264_INVALID
;
915 for (i
= 0; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
916 vpic
->ReferenceFrames
[i
].picture_id
= VA_INVALID_ID
;
917 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_INVALID
;
920 vpic
->coded_buf
= VA_INVALID_ID
;
922 vpic
->pic_parameter_set_id
= 0;
923 vpic
->seq_parameter_set_id
= 0;
925 vpic
->num_ref_idx_l0_active_minus1
= 0;
926 vpic
->num_ref_idx_l1_active_minus1
= 0;
928 vpic
->pic_fields
.bits
.entropy_coding_mode_flag
=
929 ((avctx
->profile
& 0xff) != 66);
930 vpic
->pic_fields
.bits
.weighted_pred_flag
= 0;
931 vpic
->pic_fields
.bits
.weighted_bipred_idc
= 0;
932 vpic
->pic_fields
.bits
.transform_8x8_mode_flag
=
933 ((avctx
->profile
& 0xff) >= 100);
935 vpic
->pic_init_qp
= priv
->fixed_qp_idr
;
939 mseq
->profile_idc
= avctx
->profile
& 0xff;
941 if (avctx
->profile
& FF_PROFILE_H264_CONSTRAINED
)
942 mseq
->constraint_set1_flag
= 1;
943 if (avctx
->profile
& FF_PROFILE_H264_INTRA
)
944 mseq
->constraint_set3_flag
= 1;
950 static int vaapi_encode_h264_init_picture_params(AVCodecContext
*avctx
,
951 VAAPIEncodePicture
*pic
)
953 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
954 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
955 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
956 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
959 if (pic
->type
== PICTURE_TYPE_IDR
) {
960 av_assert0(pic
->display_order
== pic
->encode_order
);
962 priv
->next_frame_num
= 1;
964 priv
->last_idr_frame
= pic
->display_order
;
966 vpic
->frame_num
= priv
->next_frame_num
;
967 if (pic
->type
!= PICTURE_TYPE_B
) {
969 ++priv
->next_frame_num
;
973 priv
->dpb_delay
= pic
->display_order
- pic
->encode_order
+ 1;
975 vpic
->frame_num
= vpic
->frame_num
&
976 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
)) - 1);
978 vpic
->CurrPic
.picture_id
= pic
->recon_surface
;
979 vpic
->CurrPic
.frame_idx
= vpic
->frame_num
;
980 vpic
->CurrPic
.flags
= 0;
981 vpic
->CurrPic
.TopFieldOrderCnt
= pic
->display_order
- priv
->last_idr_frame
;
982 vpic
->CurrPic
.BottomFieldOrderCnt
= pic
->display_order
- priv
->last_idr_frame
;
984 for (i
= 0; i
< pic
->nb_refs
; i
++) {
985 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
986 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
987 vpic
->ReferenceFrames
[i
].picture_id
= ref
->recon_surface
;
988 vpic
->ReferenceFrames
[i
].frame_idx
= ref
->encode_order
;
989 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_SHORT_TERM_REFERENCE
;
990 vpic
->ReferenceFrames
[i
].TopFieldOrderCnt
= ref
->display_order
- priv
->last_idr_frame
;
991 vpic
->ReferenceFrames
[i
].BottomFieldOrderCnt
= ref
->display_order
- priv
->last_idr_frame
;
993 for (; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
994 vpic
->ReferenceFrames
[i
].picture_id
= VA_INVALID_ID
;
995 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_INVALID
;
998 vpic
->coded_buf
= pic
->output_buffer
;
1000 vpic
->pic_fields
.bits
.idr_pic_flag
= (pic
->type
== PICTURE_TYPE_IDR
);
1001 vpic
->pic_fields
.bits
.reference_pic_flag
= (pic
->type
!= PICTURE_TYPE_B
);
1008 static int vaapi_encode_h264_init_slice_params(AVCodecContext
*avctx
,
1009 VAAPIEncodePicture
*pic
,
1010 VAAPIEncodeSlice
*slice
)
1012 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1013 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
1014 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
1015 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
1016 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
1017 VAAPIEncodeH264Slice
*pslice
;
1018 VAAPIEncodeH264MiscSliceParams
*mslice
;
1021 slice
->priv_data
= av_mallocz(sizeof(*pslice
));
1022 if (!slice
->priv_data
)
1023 return AVERROR(ENOMEM
);
1024 pslice
= slice
->priv_data
;
1025 mslice
= &pslice
->misc_slice_params
;
1027 if (pic
->type
== PICTURE_TYPE_IDR
)
1028 mslice
->nal_unit_type
= H264_NAL_IDR_SLICE
;
1030 mslice
->nal_unit_type
= H264_NAL_SLICE
;
1032 switch (pic
->type
) {
1033 case PICTURE_TYPE_IDR
:
1034 vslice
->slice_type
= SLICE_TYPE_I
;
1035 mslice
->nal_ref_idc
= 3;
1037 case PICTURE_TYPE_I
:
1038 vslice
->slice_type
= SLICE_TYPE_I
;
1039 mslice
->nal_ref_idc
= 2;
1041 case PICTURE_TYPE_P
:
1042 vslice
->slice_type
= SLICE_TYPE_P
;
1043 mslice
->nal_ref_idc
= 1;
1045 case PICTURE_TYPE_B
:
1046 vslice
->slice_type
= SLICE_TYPE_B
;
1047 mslice
->nal_ref_idc
= 0;
1050 av_assert0(0 && "invalid picture type");
1053 // Only one slice per frame.
1054 vslice
->macroblock_address
= 0;
1055 vslice
->num_macroblocks
= priv
->mb_width
* priv
->mb_height
;
1057 vslice
->macroblock_info
= VA_INVALID_ID
;
1059 vslice
->pic_parameter_set_id
= vpic
->pic_parameter_set_id
;
1060 vslice
->idr_pic_id
= priv
->idr_pic_count
++;
1062 vslice
->pic_order_cnt_lsb
= (pic
->display_order
- priv
->last_idr_frame
) &
1063 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_pic_order_cnt_lsb_minus4
)) - 1);
1065 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->RefPicList0
); i
++) {
1066 vslice
->RefPicList0
[i
].picture_id
= VA_INVALID_ID
;
1067 vslice
->RefPicList0
[i
].flags
= VA_PICTURE_H264_INVALID
;
1068 vslice
->RefPicList1
[i
].picture_id
= VA_INVALID_ID
;
1069 vslice
->RefPicList1
[i
].flags
= VA_PICTURE_H264_INVALID
;
1072 av_assert0(pic
->nb_refs
<= 2);
1073 if (pic
->nb_refs
>= 1) {
1074 // Backward reference for P- or B-frame.
1075 av_assert0(pic
->type
== PICTURE_TYPE_P
||
1076 pic
->type
== PICTURE_TYPE_B
);
1078 vslice
->num_ref_idx_l0_active_minus1
= 0;
1079 vslice
->RefPicList0
[0] = vpic
->ReferenceFrames
[0];
1081 if (pic
->nb_refs
>= 2) {
1082 // Forward reference for B-frame.
1083 av_assert0(pic
->type
== PICTURE_TYPE_B
);
1085 vslice
->num_ref_idx_l1_active_minus1
= 0;
1086 vslice
->RefPicList1
[0] = vpic
->ReferenceFrames
[1];
1089 if (pic
->type
== PICTURE_TYPE_B
)
1090 vslice
->slice_qp_delta
= priv
->fixed_qp_b
- vpic
->pic_init_qp
;
1091 else if (pic
->type
== PICTURE_TYPE_P
)
1092 vslice
->slice_qp_delta
= priv
->fixed_qp_p
- vpic
->pic_init_qp
;
1094 vslice
->slice_qp_delta
= priv
->fixed_qp_idr
- vpic
->pic_init_qp
;
1096 vslice
->direct_spatial_mv_pred_flag
= 1;
1101 static av_cold
int vaapi_encode_h264_configure(AVCodecContext
*avctx
)
1103 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1104 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
1105 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
1107 priv
->mb_width
= FFALIGN(avctx
->width
, 16) / 16;
1108 priv
->mb_height
= FFALIGN(avctx
->height
, 16) / 16;
1110 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
1111 priv
->fixed_qp_p
= opt
->qp
;
1112 if (avctx
->i_quant_factor
> 0.0)
1113 priv
->fixed_qp_idr
= (int)((priv
->fixed_qp_p
* avctx
->i_quant_factor
+
1114 avctx
->i_quant_offset
) + 0.5);
1116 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
1117 if (avctx
->b_quant_factor
> 0.0)
1118 priv
->fixed_qp_b
= (int)((priv
->fixed_qp_p
* avctx
->b_quant_factor
+
1119 avctx
->b_quant_offset
) + 0.5);
1121 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
1123 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
1124 "%d / %d / %d for IDR- / P- / B-frames.\n",
1125 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
1127 } else if (ctx
->va_rc_mode
== VA_RC_CBR
) {
1128 // These still need to be set for pic_init_qp/slice_qp_delta.
1129 priv
->fixed_qp_idr
= 26;
1130 priv
->fixed_qp_p
= 26;
1131 priv
->fixed_qp_b
= 26;
1133 av_log(avctx
, AV_LOG_DEBUG
, "Using constant-bitrate = %d bps.\n",
1137 av_assert0(0 && "Invalid RC mode.");
1140 if (opt
->quality
> 0) {
1141 #if VA_CHECK_VERSION(0, 36, 0)
1142 priv
->quality_params
.misc
.type
=
1143 VAEncMiscParameterTypeQualityLevel
;
1144 priv
->quality_params
.quality
.quality_level
= opt
->quality
;
1146 ctx
->global_params
[ctx
->nb_global_params
] =
1147 &priv
->quality_params
.misc
;
1148 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1149 sizeof(priv
->quality_params
);
1151 av_log(avctx
, AV_LOG_WARNING
, "The encode quality option is not "
1152 "supported with this VAAPI version.\n");
1159 static const VAAPIEncodeType vaapi_encode_type_h264
= {
1160 .priv_data_size
= sizeof(VAAPIEncodeH264Context
),
1162 .configure
= &vaapi_encode_h264_configure
,
1164 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferH264
),
1165 .init_sequence_params
= &vaapi_encode_h264_init_sequence_params
,
1167 .picture_params_size
= sizeof(VAEncPictureParameterBufferH264
),
1168 .init_picture_params
= &vaapi_encode_h264_init_picture_params
,
1170 .slice_params_size
= sizeof(VAEncSliceParameterBufferH264
),
1171 .init_slice_params
= &vaapi_encode_h264_init_slice_params
,
1173 .sequence_header_type
= VAEncPackedHeaderSequence
,
1174 .write_sequence_header
= &vaapi_encode_h264_write_sequence_header
,
1176 .slice_header_type
= VAEncPackedHeaderH264_Slice
,
1177 .write_slice_header
= &vaapi_encode_h264_write_slice_header
,
1179 .write_extra_header
= &vaapi_encode_h264_write_extra_header
,
1182 static av_cold
int vaapi_encode_h264_init(AVCodecContext
*avctx
)
1184 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1185 VAAPIEncodeH264Options
*opt
=
1186 (VAAPIEncodeH264Options
*)ctx
->codec_options_data
;
1188 ctx
->codec
= &vaapi_encode_type_h264
;
1190 switch (avctx
->profile
) {
1191 case FF_PROFILE_H264_CONSTRAINED_BASELINE
:
1192 ctx
->va_profile
= VAProfileH264ConstrainedBaseline
;
1194 case FF_PROFILE_H264_BASELINE
:
1195 ctx
->va_profile
= VAProfileH264Baseline
;
1197 case FF_PROFILE_H264_MAIN
:
1198 ctx
->va_profile
= VAProfileH264Main
;
1200 case FF_PROFILE_H264_EXTENDED
:
1201 av_log(avctx
, AV_LOG_ERROR
, "H.264 extended profile "
1202 "is not supported.\n");
1203 return AVERROR_PATCHWELCOME
;
1204 case FF_PROFILE_UNKNOWN
:
1205 case FF_PROFILE_H264_HIGH
:
1206 ctx
->va_profile
= VAProfileH264High
;
1208 case FF_PROFILE_H264_HIGH_10
:
1209 case FF_PROFILE_H264_HIGH_10_INTRA
:
1210 av_log(avctx
, AV_LOG_ERROR
, "H.264 10-bit profiles "
1211 "are not supported.\n");
1212 return AVERROR_PATCHWELCOME
;
1213 case FF_PROFILE_H264_HIGH_422
:
1214 case FF_PROFILE_H264_HIGH_422_INTRA
:
1215 case FF_PROFILE_H264_HIGH_444
:
1216 case FF_PROFILE_H264_HIGH_444_PREDICTIVE
:
1217 case FF_PROFILE_H264_HIGH_444_INTRA
:
1218 case FF_PROFILE_H264_CAVLC_444
:
1219 av_log(avctx
, AV_LOG_ERROR
, "H.264 non-4:2:0 profiles "
1220 "are not supported.\n");
1221 return AVERROR_PATCHWELCOME
;
1223 av_log(avctx
, AV_LOG_ERROR
, "Unknown H.264 profile %d.\n",
1225 return AVERROR(EINVAL
);
1227 if (opt
->low_power
) {
1228 #if VA_CHECK_VERSION(0, 39, 2)
1229 ctx
->va_entrypoint
= VAEntrypointEncSliceLP
;
1231 av_log(avctx
, AV_LOG_ERROR
, "Low-power encoding is not "
1232 "supported with this VAAPI version.\n");
1233 return AVERROR(EINVAL
);
1236 ctx
->va_entrypoint
= VAEntrypointEncSlice
;
1239 // Only 8-bit encode is supported.
1240 ctx
->va_rt_format
= VA_RT_FORMAT_YUV420
;
1242 if (avctx
->bit_rate
> 0)
1243 ctx
->va_rc_mode
= VA_RC_CBR
;
1245 ctx
->va_rc_mode
= VA_RC_CQP
;
1247 ctx
->va_packed_headers
=
1248 VA_ENC_PACKED_HEADER_SEQUENCE
| // SPS and PPS.
1249 VA_ENC_PACKED_HEADER_SLICE
| // Slice headers.
1250 VA_ENC_PACKED_HEADER_MISC
; // SEI.
1252 ctx
->surface_width
= FFALIGN(avctx
->width
, 16);
1253 ctx
->surface_height
= FFALIGN(avctx
->height
, 16);
1255 return ff_vaapi_encode_init(avctx
);
1258 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
1259 offsetof(VAAPIEncodeH264Options, x))
1260 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1261 static const AVOption vaapi_encode_h264_options
[] = {
1262 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1263 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 20 }, 0, 52, FLAGS
},
1264 { "quality", "Set encode quality (trades off against speed, higher is faster)",
1265 OFFSET(quality
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 8, FLAGS
},
1266 { "low_power", "Use low-power encoding mode (experimental: only supported "
1267 "on some platforms, does not support all features)",
1268 OFFSET(low_power
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, FLAGS
},
1272 static const AVCodecDefault vaapi_encode_h264_defaults
[] = {
1273 { "profile", "100" },
1278 { "i_qfactor", "1.0" },
1279 { "i_qoffset", "0.0" },
1280 { "b_qfactor", "1.2" },
1281 { "b_qoffset", "0.0" },
1285 static const AVClass vaapi_encode_h264_class
= {
1286 .class_name
= "h264_vaapi",
1287 .item_name
= av_default_item_name
,
1288 .option
= vaapi_encode_h264_options
,
1289 .version
= LIBAVUTIL_VERSION_INT
,
1292 AVCodec ff_h264_vaapi_encoder
= {
1293 .name
= "h264_vaapi",
1294 .long_name
= NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
1295 .type
= AVMEDIA_TYPE_VIDEO
,
1296 .id
= AV_CODEC_ID_H264
,
1297 .priv_data_size
= (sizeof(VAAPIEncodeContext
) +
1298 sizeof(VAAPIEncodeH264Options
)),
1299 .init
= &vaapi_encode_h264_init
,
1300 .encode2
= &ff_vaapi_encode2
,
1301 .close
= &ff_vaapi_encode_close
,
1302 .priv_class
= &vaapi_encode_h264_class
,
1303 .capabilities
= AV_CODEC_CAP_DELAY
,
1304 .defaults
= vaapi_encode_h264_defaults
,
1305 .pix_fmts
= (const enum AVPixelFormat
[]) {