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 #if VA_CHECK_VERSION(0, 36, 0)
153 // Speed-quality tradeoff setting.
155 VAEncMiscParameterBuffer misc
;
156 VAEncMiscParameterBufferQualityLevel quality
;
159 } VAAPIEncodeH264Context
;
161 typedef struct VAAPIEncodeH264Options
{
165 } VAAPIEncodeH264Options
;
168 #define vseq_var(name) vseq->name, name
169 #define vseq_field(name) vseq->seq_fields.bits.name, name
170 #define vvui_field(name) vseq->vui_fields.bits.name, name
171 #define vpic_var(name) vpic->name, name
172 #define vpic_field(name) vpic->pic_fields.bits.name, name
173 #define vslice_var(name) vslice->name, name
174 #define vslice_field(name) vslice->slice_fields.bits.name, name
175 #define mseq_var(name) mseq->name, name
176 #define mslice_var(name) mslice->name, name
178 static void vaapi_encode_h264_write_nal_header(PutBitContext
*pbc
,
179 int nal_unit_type
, int nal_ref_idc
)
181 u(1, 0, forbidden_zero_bit
);
182 u(2, nal_ref_idc
, nal_ref_idc
);
183 u(5, nal_unit_type
, nal_unit_type
);
186 static void vaapi_encode_h264_write_trailing_rbsp(PutBitContext
*pbc
)
188 u(1, 1, rbsp_stop_one_bit
);
189 while (put_bits_count(pbc
) & 7)
190 u(1, 0, rbsp_alignment_zero_bit
);
193 static void vaapi_encode_h264_write_vui(PutBitContext
*pbc
,
194 VAAPIEncodeContext
*ctx
)
196 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
197 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
198 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
201 u(1, vvui_field(aspect_ratio_info_present_flag
));
202 if (vseq
->vui_fields
.bits
.aspect_ratio_info_present_flag
) {
203 u(8, vseq_var(aspect_ratio_idc
));
204 if (vseq
->aspect_ratio_idc
== 255) {
205 u(16, vseq_var(sar_width
));
206 u(16, vseq_var(sar_height
));
210 u(1, mseq_var(overscan_info_present_flag
));
211 if (mseq
->overscan_info_present_flag
)
212 u(1, mseq_var(overscan_appropriate_flag
));
214 u(1, mseq_var(video_signal_type_present_flag
));
215 if (mseq
->video_signal_type_present_flag
) {
216 u(3, mseq_var(video_format
));
217 u(1, mseq_var(video_full_range_flag
));
218 u(1, mseq_var(colour_description_present_flag
));
219 if (mseq
->colour_description_present_flag
) {
220 u(8, mseq_var(colour_primaries
));
221 u(8, mseq_var(transfer_characteristics
));
222 u(8, mseq_var(matrix_coefficients
));
226 u(1, mseq_var(chroma_loc_info_present_flag
));
227 if (mseq
->chroma_loc_info_present_flag
) {
228 ue(mseq_var(chroma_sample_loc_type_top_field
));
229 ue(mseq_var(chroma_sample_loc_type_bottom_field
));
232 u(1, vvui_field(timing_info_present_flag
));
233 if (vseq
->vui_fields
.bits
.timing_info_present_flag
) {
234 u(32, vseq_var(num_units_in_tick
));
235 u(32, vseq_var(time_scale
));
236 u(1, mseq_var(fixed_frame_rate_flag
));
239 u(1, mseq_var(nal_hrd_parameters_present_flag
));
240 if (mseq
->nal_hrd_parameters_present_flag
) {
241 ue(mseq_var(cpb_cnt_minus1
));
242 u(4, mseq_var(bit_rate_scale
));
243 u(4, mseq_var(cpb_size_scale
));
244 for (i
= 0; i
<= mseq
->cpb_cnt_minus1
; i
++) {
245 ue(mseq_var(bit_rate_value_minus1
[i
]));
246 ue(mseq_var(cpb_size_value_minus1
[i
]));
247 u(1, mseq_var(cbr_flag
[i
]));
249 u(5, mseq_var(initial_cpb_removal_delay_length_minus1
));
250 u(5, mseq_var(cpb_removal_delay_length_minus1
));
251 u(5, mseq_var(dpb_output_delay_length_minus1
));
252 u(5, mseq_var(time_offset_length
));
254 u(1, mseq_var(vcl_hrd_parameters_present_flag
));
255 if (mseq
->vcl_hrd_parameters_present_flag
) {
256 av_assert0(0 && "vcl hrd parameters not supported");
259 if (mseq
->nal_hrd_parameters_present_flag
||
260 mseq
->vcl_hrd_parameters_present_flag
)
261 u(1, mseq_var(low_delay_hrd_flag
));
262 u(1, mseq_var(pic_struct_present_flag
));
264 u(1, vvui_field(bitstream_restriction_flag
));
265 if (vseq
->vui_fields
.bits
.bitstream_restriction_flag
) {
266 av_assert0(0 && "bitstream restrictions not supported");
270 static void vaapi_encode_h264_write_sps(PutBitContext
*pbc
,
271 VAAPIEncodeContext
*ctx
)
273 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
274 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
275 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
278 vaapi_encode_h264_write_nal_header(pbc
, H264_NAL_SPS
, 3);
280 u(8, mseq_var(profile_idc
));
281 u(1, mseq_var(constraint_set0_flag
));
282 u(1, mseq_var(constraint_set1_flag
));
283 u(1, mseq_var(constraint_set2_flag
));
284 u(1, mseq_var(constraint_set3_flag
));
285 u(1, mseq_var(constraint_set4_flag
));
286 u(1, mseq_var(constraint_set5_flag
));
287 u(2, 0, reserved_zero_2bits
);
289 u(8, vseq_var(level_idc
));
291 ue(vseq_var(seq_parameter_set_id
));
293 if (mseq
->profile_idc
== 100 || mseq
->profile_idc
== 110 ||
294 mseq
->profile_idc
== 122 || mseq
->profile_idc
== 244 ||
295 mseq
->profile_idc
== 44 || mseq
->profile_idc
== 83 ||
296 mseq
->profile_idc
== 86 || mseq
->profile_idc
== 118 ||
297 mseq
->profile_idc
== 128 || mseq
->profile_idc
== 138) {
298 ue(vseq_field(chroma_format_idc
));
300 if (vseq
->seq_fields
.bits
.chroma_format_idc
== 3)
301 u(1, mseq_var(separate_colour_plane_flag
));
303 ue(vseq_var(bit_depth_luma_minus8
));
304 ue(vseq_var(bit_depth_chroma_minus8
));
306 u(1, mseq_var(qpprime_y_zero_transform_bypass_flag
));
308 u(1, vseq_field(seq_scaling_matrix_present_flag
));
309 if (vseq
->seq_fields
.bits
.seq_scaling_matrix_present_flag
) {
310 av_assert0(0 && "scaling matrices not supported");
314 ue(vseq_field(log2_max_frame_num_minus4
));
315 ue(vseq_field(pic_order_cnt_type
));
317 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 0) {
318 ue(vseq_field(log2_max_pic_order_cnt_lsb_minus4
));
319 } else if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 1) {
320 u(1, mseq_var(delta_pic_order_always_zero_flag
));
321 se(vseq_var(offset_for_non_ref_pic
));
322 se(vseq_var(offset_for_top_to_bottom_field
));
323 ue(vseq_var(num_ref_frames_in_pic_order_cnt_cycle
));
325 for (i
= 0; i
< vseq
->num_ref_frames_in_pic_order_cnt_cycle
; i
++)
326 se(vseq_var(offset_for_ref_frame
[i
]));
329 ue(vseq_var(max_num_ref_frames
));
330 u(1, mseq_var(gaps_in_frame_num_allowed_flag
));
332 ue(vseq
->picture_width_in_mbs
- 1, pic_width_in_mbs_minus1
);
333 ue(vseq
->picture_height_in_mbs
- 1, pic_height_in_mbs_minus1
);
335 u(1, vseq_field(frame_mbs_only_flag
));
336 if (!vseq
->seq_fields
.bits
.frame_mbs_only_flag
)
337 u(1, vseq_field(mb_adaptive_frame_field_flag
));
339 u(1, vseq_field(direct_8x8_inference_flag
));
341 u(1, vseq_var(frame_cropping_flag
));
342 if (vseq
->frame_cropping_flag
) {
343 ue(vseq_var(frame_crop_left_offset
));
344 ue(vseq_var(frame_crop_right_offset
));
345 ue(vseq_var(frame_crop_top_offset
));
346 ue(vseq_var(frame_crop_bottom_offset
));
349 u(1, vseq_var(vui_parameters_present_flag
));
350 if (vseq
->vui_parameters_present_flag
)
351 vaapi_encode_h264_write_vui(pbc
, ctx
);
353 vaapi_encode_h264_write_trailing_rbsp(pbc
);
356 static void vaapi_encode_h264_write_pps(PutBitContext
*pbc
,
357 VAAPIEncodeContext
*ctx
)
359 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
360 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
361 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
363 vaapi_encode_h264_write_nal_header(pbc
, H264_NAL_PPS
, 3);
365 ue(vpic_var(pic_parameter_set_id
));
366 ue(vpic_var(seq_parameter_set_id
));
368 u(1, vpic_field(entropy_coding_mode_flag
));
369 u(1, mseq_var(bottom_field_pic_order_in_frame_present_flag
));
371 ue(mseq_var(num_slice_groups_minus1
));
372 if (mseq
->num_slice_groups_minus1
> 0) {
373 ue(mseq_var(slice_group_map_type
));
374 av_assert0(0 && "slice groups not supported");
377 ue(vpic_var(num_ref_idx_l0_active_minus1
));
378 ue(vpic_var(num_ref_idx_l1_active_minus1
));
380 u(1, vpic_field(weighted_pred_flag
));
381 u(2, vpic_field(weighted_bipred_idc
));
383 se(vpic
->pic_init_qp
- 26, pic_init_qp_minus26
);
384 se(mseq_var(pic_init_qs_minus26
));
385 se(vpic_var(chroma_qp_index_offset
));
387 u(1, vpic_field(deblocking_filter_control_present_flag
));
388 u(1, vpic_field(constrained_intra_pred_flag
));
389 u(1, vpic_field(redundant_pic_cnt_present_flag
));
390 u(1, vpic_field(transform_8x8_mode_flag
));
392 u(1, vpic_field(pic_scaling_matrix_present_flag
));
393 if (vpic
->pic_fields
.bits
.pic_scaling_matrix_present_flag
) {
394 av_assert0(0 && "scaling matrices not supported");
397 se(vpic_var(second_chroma_qp_index_offset
));
399 vaapi_encode_h264_write_trailing_rbsp(pbc
);
402 static void vaapi_encode_h264_write_slice_header2(PutBitContext
*pbc
,
403 VAAPIEncodeContext
*ctx
,
404 VAAPIEncodePicture
*pic
,
405 VAAPIEncodeSlice
*slice
)
407 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
408 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
409 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
410 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
411 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
412 VAAPIEncodeH264Slice
*pslice
= slice
->priv_data
;
413 VAAPIEncodeH264MiscSliceParams
*mslice
= &pslice
->misc_slice_params
;
415 vaapi_encode_h264_write_nal_header(pbc
, mslice
->nal_unit_type
,
416 mslice
->nal_ref_idc
);
418 ue(vslice
->macroblock_address
, first_mb_in_slice
);
419 ue(vslice_var(slice_type
));
420 ue(vpic_var(pic_parameter_set_id
));
422 if (mseq
->separate_colour_plane_flag
) {
423 u(2, mslice_var(colour_plane_id
));
426 u(4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
,
428 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
)) - 1)),
431 if (!vseq
->seq_fields
.bits
.frame_mbs_only_flag
) {
432 u(1, mslice_var(field_pic_flag
));
433 if (mslice
->field_pic_flag
)
434 u(1, mslice_var(bottom_field_flag
));
437 if (vpic
->pic_fields
.bits
.idr_pic_flag
) {
438 ue(vslice_var(idr_pic_id
));
441 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 0) {
442 u(4 + vseq
->seq_fields
.bits
.log2_max_pic_order_cnt_lsb_minus4
,
443 vslice_var(pic_order_cnt_lsb
));
444 if (mseq
->bottom_field_pic_order_in_frame_present_flag
&&
445 !mslice
->field_pic_flag
) {
446 se(vslice_var(delta_pic_order_cnt_bottom
));
450 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 1 &&
451 !vseq
->seq_fields
.bits
.delta_pic_order_always_zero_flag
) {
452 se(vslice_var(delta_pic_order_cnt
[0]));
453 if (mseq
->bottom_field_pic_order_in_frame_present_flag
&&
454 !mslice
->field_pic_flag
) {
455 se(vslice_var(delta_pic_order_cnt
[1]));
459 if (vpic
->pic_fields
.bits
.redundant_pic_cnt_present_flag
) {
460 ue(mslice_var(redundant_pic_cnt
));
463 if (vslice
->slice_type
== SLICE_TYPE_B
) {
464 u(1, vslice_var(direct_spatial_mv_pred_flag
));
467 if (vslice
->slice_type
== SLICE_TYPE_P
||
468 vslice
->slice_type
== SLICE_TYPE_SP
||
469 vslice
->slice_type
== SLICE_TYPE_B
) {
470 u(1, vslice_var(num_ref_idx_active_override_flag
));
471 if (vslice
->num_ref_idx_active_override_flag
) {
472 ue(vslice_var(num_ref_idx_l0_active_minus1
));
473 if (vslice
->slice_type
== SLICE_TYPE_B
)
474 ue(vslice_var(num_ref_idx_l1_active_minus1
));
478 if (mslice
->nal_unit_type
== 20 || mslice
->nal_unit_type
== 21) {
479 av_assert0(0 && "no MVC support");
481 if (vslice
->slice_type
% 5 != 2 && vslice
->slice_type
% 5 != 4) {
482 u(1, mslice_var(ref_pic_list_modification_flag_l0
));
483 if (mslice
->ref_pic_list_modification_flag_l0
) {
484 av_assert0(0 && "ref pic list modification");
487 if (vslice
->slice_type
% 5 == 1) {
488 u(1, mslice_var(ref_pic_list_modification_flag_l1
));
489 if (mslice
->ref_pic_list_modification_flag_l1
) {
490 av_assert0(0 && "ref pic list modification");
495 if ((vpic
->pic_fields
.bits
.weighted_pred_flag
&&
496 (vslice
->slice_type
== SLICE_TYPE_P
||
497 vslice
->slice_type
== SLICE_TYPE_SP
)) ||
498 (vpic
->pic_fields
.bits
.weighted_bipred_idc
== 1 &&
499 vslice
->slice_type
== SLICE_TYPE_B
)) {
500 av_assert0(0 && "prediction weights not supported");
503 av_assert0(mslice
->nal_ref_idc
> 0 ==
504 vpic
->pic_fields
.bits
.reference_pic_flag
);
505 if (mslice
->nal_ref_idc
!= 0) {
506 if (vpic
->pic_fields
.bits
.idr_pic_flag
) {
507 u(1, mslice_var(no_output_of_prior_pics_flag
));
508 u(1, mslice_var(long_term_reference_flag
));
510 u(1, mslice_var(adaptive_ref_pic_marking_mode_flag
));
511 if (mslice
->adaptive_ref_pic_marking_mode_flag
) {
512 av_assert0(0 && "MMCOs not supported");
517 if (vpic
->pic_fields
.bits
.entropy_coding_mode_flag
&&
518 vslice
->slice_type
!= SLICE_TYPE_I
&&
519 vslice
->slice_type
!= SLICE_TYPE_SI
) {
520 ue(vslice_var(cabac_init_idc
));
523 se(vslice_var(slice_qp_delta
));
524 if (vslice
->slice_type
== SLICE_TYPE_SP
||
525 vslice
->slice_type
== SLICE_TYPE_SI
) {
526 if (vslice
->slice_type
== SLICE_TYPE_SP
)
527 u(1, mslice_var(sp_for_switch_flag
));
528 se(mslice_var(slice_qs_delta
));
531 if (vpic
->pic_fields
.bits
.deblocking_filter_control_present_flag
) {
532 ue(vslice_var(disable_deblocking_filter_idc
));
533 if (vslice
->disable_deblocking_filter_idc
!= 1) {
534 se(vslice_var(slice_alpha_c0_offset_div2
));
535 se(vslice_var(slice_beta_offset_div2
));
539 if (mseq
->num_slice_groups_minus1
> 0 &&
540 mseq
->slice_group_map_type
>= 3 && mseq
->slice_group_map_type
<= 5) {
541 av_assert0(0 && "slice groups not supported");
544 // No alignment - this need not be a byte boundary.
547 static void vaapi_encode_h264_write_buffering_period(PutBitContext
*pbc
,
548 VAAPIEncodeContext
*ctx
,
549 VAAPIEncodePicture
*pic
)
551 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
552 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
553 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
556 ue(vpic_var(seq_parameter_set_id
));
558 if (mseq
->nal_hrd_parameters_present_flag
) {
559 for (i
= 0; i
<= mseq
->cpb_cnt_minus1
; i
++) {
560 u(mseq
->initial_cpb_removal_delay_length_minus1
+ 1,
561 mseq_var(initial_cpb_removal_delay
));
562 u(mseq
->initial_cpb_removal_delay_length_minus1
+ 1,
563 mseq_var(initial_cpb_removal_delay_offset
));
566 if (mseq
->vcl_hrd_parameters_present_flag
) {
567 av_assert0(0 && "vcl hrd parameters not supported");
571 static void vaapi_encode_h264_write_pic_timing(PutBitContext
*pbc
,
572 VAAPIEncodeContext
*ctx
,
573 VAAPIEncodePicture
*pic
)
575 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
576 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
577 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
580 if (mseq
->nal_hrd_parameters_present_flag
||
581 mseq
->vcl_hrd_parameters_present_flag
) {
582 u(mseq
->cpb_removal_delay_length_minus1
+ 1,
583 2 * vseq
->num_units_in_tick
* priv
->cpb_delay
,
585 u(mseq
->dpb_output_delay_length_minus1
+ 1,
586 2 * vseq
->num_units_in_tick
* priv
->dpb_delay
,
589 if (mseq
->pic_struct_present_flag
) {
590 u(4, mseq_var(pic_struct
));
591 num_clock_ts
= (mseq
->pic_struct
<= 2 ?
1 :
592 mseq
->pic_struct
<= 4 ?
2 :
593 mseq
->pic_struct
<= 8 ?
3 : 0);
594 for (i
= 0; i
< num_clock_ts
; i
++) {
595 u(1, 0, clock_timestamp_flag
[i
]);
596 // No full timestamp information.
601 static void vaapi_encode_h264_write_identifier(PutBitContext
*pbc
,
602 VAAPIEncodeContext
*ctx
,
603 VAAPIEncodePicture
*pic
)
605 const char *lavc
= LIBAVCODEC_IDENT
;
606 const char *vaapi
= VA_VERSION_S
;
607 const char *driver
= vaQueryVendorString(ctx
->hwctx
->display
);
611 // Random (version 4) ISO 11578 UUID.
613 0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf,
614 0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d,
617 for (i
= 0; i
< 16; i
++)
618 u(8, uuid
[i
], uuid_iso_iec_11578
);
620 snprintf(tmp
, sizeof(tmp
), "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
621 for (i
= 0; i
< sizeof(tmp
) && tmp
[i
]; i
++)
622 u(8, tmp
[i
], user_data_payload_byte
);
625 static void vaapi_encode_h264_write_sei(PutBitContext
*pbc
,
626 VAAPIEncodeContext
*ctx
,
627 VAAPIEncodePicture
*pic
)
629 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
630 PutBitContext payload_bits
;
632 int payload_type
, payload_size
, i
;
633 void (*write_payload
)(PutBitContext
*pbc
,
634 VAAPIEncodeContext
*ctx
,
635 VAAPIEncodePicture
*pic
) = NULL
;
637 vaapi_encode_h264_write_nal_header(pbc
, H264_NAL_SEI
, 0);
639 for (payload_type
= 0; payload_type
< 64; payload_type
++) {
640 switch (payload_type
) {
641 case SEI_TYPE_BUFFERING_PERIOD
:
642 if (!priv
->send_timing_sei
||
643 pic
->type
!= PICTURE_TYPE_IDR
)
645 write_payload
= &vaapi_encode_h264_write_buffering_period
;
647 case SEI_TYPE_PIC_TIMING
:
648 if (!priv
->send_timing_sei
)
650 write_payload
= &vaapi_encode_h264_write_pic_timing
;
652 case SEI_TYPE_USER_DATA_UNREGISTERED
:
653 if (pic
->encode_order
!= 0)
655 write_payload
= &vaapi_encode_h264_write_identifier
;
661 init_put_bits(&payload_bits
, payload
, sizeof(payload
));
662 write_payload(&payload_bits
, ctx
, pic
);
663 if (put_bits_count(&payload_bits
) & 7) {
664 write_u(&payload_bits
, 1, 1, bit_equal_to_one
);
665 while (put_bits_count(&payload_bits
) & 7)
666 write_u(&payload_bits
, 1, 0, bit_equal_to_zero
);
668 payload_size
= put_bits_count(&payload_bits
) / 8;
669 flush_put_bits(&payload_bits
);
671 u(8, payload_type
, last_payload_type_byte
);
672 u(8, payload_size
, last_payload_size_byte
);
673 for (i
= 0; i
< payload_size
; i
++)
674 u(8, payload
[i
] & 0xff, sei_payload
);
677 vaapi_encode_h264_write_trailing_rbsp(pbc
);
680 static int vaapi_encode_h264_write_sequence_header(AVCodecContext
*avctx
,
681 char *data
, size_t *data_len
)
683 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
687 size_t nal_len
, bit_len
, bit_pos
, next_len
;
692 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
693 vaapi_encode_h264_write_sps(&pbc
, ctx
);
694 nal_len
= put_bits_count(&pbc
);
695 flush_put_bits(&pbc
);
697 next_len
= bit_len
- bit_pos
;
698 err
= ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
+ bit_pos
/ 8,
705 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
706 vaapi_encode_h264_write_pps(&pbc
, ctx
);
707 nal_len
= put_bits_count(&pbc
);
708 flush_put_bits(&pbc
);
710 next_len
= bit_len
- bit_pos
;
711 err
= ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
+ bit_pos
/ 8,
722 static int vaapi_encode_h264_write_slice_header(AVCodecContext
*avctx
,
723 VAAPIEncodePicture
*pic
,
724 VAAPIEncodeSlice
*slice
,
725 char *data
, size_t *data_len
)
727 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
732 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
733 vaapi_encode_h264_write_slice_header2(&pbc
, ctx
, pic
, slice
);
734 header_len
= put_bits_count(&pbc
);
735 flush_put_bits(&pbc
);
737 return ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
, data_len
,
741 static int vaapi_encode_h264_write_extra_header(AVCodecContext
*avctx
,
742 VAAPIEncodePicture
*pic
,
743 int index
, int *type
,
744 char *data
, size_t *data_len
)
746 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
751 if (index
== 0 && ctx
->va_rc_mode
== VA_RC_CBR
) {
752 *type
= VAEncPackedHeaderH264_SEI
;
754 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
755 vaapi_encode_h264_write_sei(&pbc
, ctx
, pic
);
756 header_len
= put_bits_count(&pbc
);
757 flush_put_bits(&pbc
);
759 return ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
, data_len
,
767 static int vaapi_encode_h264_init_sequence_params(AVCodecContext
*avctx
)
769 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
770 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
771 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
772 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
773 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
777 vseq
->seq_parameter_set_id
= 0;
779 vseq
->level_idc
= avctx
->level
;
781 vseq
->max_num_ref_frames
= 2;
783 vseq
->picture_width_in_mbs
= priv
->mb_width
;
784 vseq
->picture_height_in_mbs
= priv
->mb_height
;
786 vseq
->seq_fields
.bits
.chroma_format_idc
= 1;
787 vseq
->seq_fields
.bits
.frame_mbs_only_flag
= 1;
788 vseq
->seq_fields
.bits
.direct_8x8_inference_flag
= 1;
789 vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
= 4;
790 vseq
->seq_fields
.bits
.pic_order_cnt_type
= 0;
792 if (avctx
->width
!= ctx
->surface_width
||
793 avctx
->height
!= ctx
->surface_height
) {
794 vseq
->frame_cropping_flag
= 1;
796 vseq
->frame_crop_left_offset
= 0;
797 vseq
->frame_crop_right_offset
=
798 (ctx
->surface_width
- avctx
->width
) / 2;
799 vseq
->frame_crop_top_offset
= 0;
800 vseq
->frame_crop_bottom_offset
=
801 (ctx
->surface_height
- avctx
->height
) / 2;
803 vseq
->frame_cropping_flag
= 0;
806 vseq
->vui_parameters_present_flag
= 1;
807 if (avctx
->sample_aspect_ratio
.num
!= 0) {
808 vseq
->vui_fields
.bits
.aspect_ratio_info_present_flag
= 1;
809 // There is a large enum of these which we could support
810 // individually rather than using the generic X/Y form?
811 if (avctx
->sample_aspect_ratio
.num
==
812 avctx
->sample_aspect_ratio
.den
) {
813 vseq
->aspect_ratio_idc
= 1;
815 vseq
->aspect_ratio_idc
= 255; // Extended SAR.
816 vseq
->sar_width
= avctx
->sample_aspect_ratio
.num
;
817 vseq
->sar_height
= avctx
->sample_aspect_ratio
.den
;
820 if (avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
821 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
822 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
823 mseq
->video_signal_type_present_flag
= 1;
824 mseq
->video_format
= 5; // Unspecified.
825 mseq
->video_full_range_flag
= 0;
826 mseq
->colour_description_present_flag
= 1;
827 // These enums are derived from the standard and hence
828 // we can just use the values directly.
829 mseq
->colour_primaries
= avctx
->color_primaries
;
830 mseq
->transfer_characteristics
= avctx
->color_trc
;
831 mseq
->matrix_coefficients
= avctx
->colorspace
;
834 vseq
->bits_per_second
= avctx
->bit_rate
;
836 vseq
->vui_fields
.bits
.timing_info_present_flag
= 1;
837 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
838 vseq
->num_units_in_tick
= avctx
->framerate
.num
;
839 vseq
->time_scale
= 2 * avctx
->framerate
.den
;
840 mseq
->fixed_frame_rate_flag
= 1;
842 vseq
->num_units_in_tick
= avctx
->time_base
.num
;
843 vseq
->time_scale
= 2 * avctx
->time_base
.den
;
844 mseq
->fixed_frame_rate_flag
= 0;
847 if (ctx
->va_rc_mode
== VA_RC_CBR
) {
848 priv
->send_timing_sei
= 1;
849 mseq
->nal_hrd_parameters_present_flag
= 1;
851 mseq
->cpb_cnt_minus1
= 0;
853 // Try to scale these to a sensible range so that the
854 // golomb encode of the value is not overlong.
855 mseq
->bit_rate_scale
=
856 av_clip_uintp2(av_log2(avctx
->bit_rate
) - 15 - 6, 4);
857 mseq
->bit_rate_value_minus1
[0] =
858 (avctx
->bit_rate
>> mseq
->bit_rate_scale
+ 6) - 1;
860 mseq
->cpb_size_scale
=
861 av_clip_uintp2(av_log2(ctx
->hrd_params
.hrd
.buffer_size
) - 15 - 4, 4);
862 mseq
->cpb_size_value_minus1
[0] =
863 (ctx
->hrd_params
.hrd
.buffer_size
>> mseq
->cpb_size_scale
+ 4) - 1;
865 // CBR mode isn't actually available here, despite naming.
866 mseq
->cbr_flag
[0] = 0;
868 mseq
->initial_cpb_removal_delay_length_minus1
= 23;
869 mseq
->cpb_removal_delay_length_minus1
= 23;
870 mseq
->dpb_output_delay_length_minus1
= 7;
871 mseq
->time_offset_length
= 0;
873 // This calculation can easily overflow 32 bits.
874 mseq
->initial_cpb_removal_delay
= 90000 *
875 (uint64_t)ctx
->hrd_params
.hrd
.initial_buffer_fullness
/
876 ctx
->hrd_params
.hrd
.buffer_size
;
878 mseq
->initial_cpb_removal_delay_offset
= 0;
880 priv
->send_timing_sei
= 0;
881 mseq
->nal_hrd_parameters_present_flag
= 0;
884 vseq
->intra_period
= ctx
->p_per_i
* (ctx
->b_per_p
+ 1);
885 vseq
->intra_idr_period
= vseq
->intra_period
;
886 vseq
->ip_period
= ctx
->b_per_p
+ 1;
890 vpic
->CurrPic
.picture_id
= VA_INVALID_ID
;
891 vpic
->CurrPic
.flags
= VA_PICTURE_H264_INVALID
;
893 for (i
= 0; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
894 vpic
->ReferenceFrames
[i
].picture_id
= VA_INVALID_ID
;
895 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_INVALID
;
898 vpic
->coded_buf
= VA_INVALID_ID
;
900 vpic
->pic_parameter_set_id
= 0;
901 vpic
->seq_parameter_set_id
= 0;
903 vpic
->num_ref_idx_l0_active_minus1
= 0;
904 vpic
->num_ref_idx_l1_active_minus1
= 0;
906 vpic
->pic_fields
.bits
.entropy_coding_mode_flag
=
907 ((avctx
->profile
& 0xff) != 66);
908 vpic
->pic_fields
.bits
.weighted_pred_flag
= 0;
909 vpic
->pic_fields
.bits
.weighted_bipred_idc
= 0;
910 vpic
->pic_fields
.bits
.transform_8x8_mode_flag
=
911 ((avctx
->profile
& 0xff) >= 100);
913 vpic
->pic_init_qp
= priv
->fixed_qp_idr
;
917 mseq
->profile_idc
= avctx
->profile
& 0xff;
919 if (avctx
->profile
& FF_PROFILE_H264_CONSTRAINED
)
920 mseq
->constraint_set1_flag
= 1;
921 if (avctx
->profile
& FF_PROFILE_H264_INTRA
)
922 mseq
->constraint_set3_flag
= 1;
928 static int vaapi_encode_h264_init_picture_params(AVCodecContext
*avctx
,
929 VAAPIEncodePicture
*pic
)
931 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
932 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
933 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
934 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
937 if (pic
->type
== PICTURE_TYPE_IDR
) {
938 av_assert0(pic
->display_order
== pic
->encode_order
);
940 priv
->next_frame_num
= 1;
943 vpic
->frame_num
= priv
->next_frame_num
;
944 if (pic
->type
!= PICTURE_TYPE_B
) {
946 ++priv
->next_frame_num
;
950 priv
->dpb_delay
= pic
->display_order
- pic
->encode_order
+ 1;
952 vpic
->frame_num
= vpic
->frame_num
&
953 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
)) - 1);
955 vpic
->CurrPic
.picture_id
= pic
->recon_surface
;
956 vpic
->CurrPic
.frame_idx
= vpic
->frame_num
;
957 vpic
->CurrPic
.flags
= 0;
958 vpic
->CurrPic
.TopFieldOrderCnt
= pic
->display_order
;
959 vpic
->CurrPic
.BottomFieldOrderCnt
= pic
->display_order
;
961 for (i
= 0; i
< pic
->nb_refs
; i
++) {
962 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
963 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
964 vpic
->ReferenceFrames
[i
].picture_id
= ref
->recon_surface
;
965 vpic
->ReferenceFrames
[i
].frame_idx
= ref
->encode_order
;
966 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_SHORT_TERM_REFERENCE
;
967 vpic
->ReferenceFrames
[i
].TopFieldOrderCnt
= ref
->display_order
;
968 vpic
->ReferenceFrames
[i
].BottomFieldOrderCnt
= ref
->display_order
;
970 for (; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
971 vpic
->ReferenceFrames
[i
].picture_id
= VA_INVALID_ID
;
972 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_INVALID
;
975 vpic
->coded_buf
= pic
->output_buffer
;
977 vpic
->pic_fields
.bits
.idr_pic_flag
= (pic
->type
== PICTURE_TYPE_IDR
);
978 vpic
->pic_fields
.bits
.reference_pic_flag
= (pic
->type
!= PICTURE_TYPE_B
);
985 static int vaapi_encode_h264_init_slice_params(AVCodecContext
*avctx
,
986 VAAPIEncodePicture
*pic
,
987 VAAPIEncodeSlice
*slice
)
989 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
990 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
991 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
992 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
993 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
994 VAAPIEncodeH264Slice
*pslice
;
995 VAAPIEncodeH264MiscSliceParams
*mslice
;
998 slice
->priv_data
= av_mallocz(sizeof(*pslice
));
999 if (!slice
->priv_data
)
1000 return AVERROR(ENOMEM
);
1001 pslice
= slice
->priv_data
;
1002 mslice
= &pslice
->misc_slice_params
;
1004 if (pic
->type
== PICTURE_TYPE_IDR
)
1005 mslice
->nal_unit_type
= H264_NAL_IDR_SLICE
;
1007 mslice
->nal_unit_type
= H264_NAL_SLICE
;
1009 switch (pic
->type
) {
1010 case PICTURE_TYPE_IDR
:
1011 vslice
->slice_type
= SLICE_TYPE_I
;
1012 mslice
->nal_ref_idc
= 3;
1014 case PICTURE_TYPE_I
:
1015 vslice
->slice_type
= SLICE_TYPE_I
;
1016 mslice
->nal_ref_idc
= 2;
1018 case PICTURE_TYPE_P
:
1019 vslice
->slice_type
= SLICE_TYPE_P
;
1020 mslice
->nal_ref_idc
= 1;
1022 case PICTURE_TYPE_B
:
1023 vslice
->slice_type
= SLICE_TYPE_B
;
1024 mslice
->nal_ref_idc
= 0;
1027 av_assert0(0 && "invalid picture type");
1030 // Only one slice per frame.
1031 vslice
->macroblock_address
= 0;
1032 vslice
->num_macroblocks
= priv
->mb_width
* priv
->mb_height
;
1034 vslice
->macroblock_info
= VA_INVALID_ID
;
1036 vslice
->pic_parameter_set_id
= vpic
->pic_parameter_set_id
;
1037 vslice
->idr_pic_id
= priv
->idr_pic_count
++;
1039 vslice
->pic_order_cnt_lsb
= pic
->display_order
&
1040 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_pic_order_cnt_lsb_minus4
)) - 1);
1042 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->RefPicList0
); i
++) {
1043 vslice
->RefPicList0
[i
].picture_id
= VA_INVALID_ID
;
1044 vslice
->RefPicList0
[i
].flags
= VA_PICTURE_H264_INVALID
;
1045 vslice
->RefPicList1
[i
].picture_id
= VA_INVALID_ID
;
1046 vslice
->RefPicList1
[i
].flags
= VA_PICTURE_H264_INVALID
;
1049 av_assert0(pic
->nb_refs
<= 2);
1050 if (pic
->nb_refs
>= 1) {
1051 // Backward reference for P- or B-frame.
1052 av_assert0(pic
->type
== PICTURE_TYPE_P
||
1053 pic
->type
== PICTURE_TYPE_B
);
1055 vslice
->num_ref_idx_l0_active_minus1
= 0;
1056 vslice
->RefPicList0
[0] = vpic
->ReferenceFrames
[0];
1058 if (pic
->nb_refs
>= 2) {
1059 // Forward reference for B-frame.
1060 av_assert0(pic
->type
== PICTURE_TYPE_B
);
1062 vslice
->num_ref_idx_l1_active_minus1
= 0;
1063 vslice
->RefPicList1
[0] = vpic
->ReferenceFrames
[1];
1066 if (pic
->type
== PICTURE_TYPE_B
)
1067 vslice
->slice_qp_delta
= priv
->fixed_qp_b
- vpic
->pic_init_qp
;
1068 else if (pic
->type
== PICTURE_TYPE_P
)
1069 vslice
->slice_qp_delta
= priv
->fixed_qp_p
- vpic
->pic_init_qp
;
1071 vslice
->slice_qp_delta
= priv
->fixed_qp_idr
- vpic
->pic_init_qp
;
1073 vslice
->direct_spatial_mv_pred_flag
= 1;
1078 static av_cold
int vaapi_encode_h264_configure(AVCodecContext
*avctx
)
1080 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1081 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
1082 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
1084 priv
->mb_width
= FFALIGN(avctx
->width
, 16) / 16;
1085 priv
->mb_height
= FFALIGN(avctx
->height
, 16) / 16;
1087 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
1088 priv
->fixed_qp_p
= opt
->qp
;
1089 if (avctx
->i_quant_factor
> 0.0)
1090 priv
->fixed_qp_idr
= (int)((priv
->fixed_qp_p
* avctx
->i_quant_factor
+
1091 avctx
->i_quant_offset
) + 0.5);
1093 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
1094 if (avctx
->b_quant_factor
> 0.0)
1095 priv
->fixed_qp_b
= (int)((priv
->fixed_qp_p
* avctx
->b_quant_factor
+
1096 avctx
->b_quant_offset
) + 0.5);
1098 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
1100 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
1101 "%d / %d / %d for IDR- / P- / B-frames.\n",
1102 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
1104 } else if (ctx
->va_rc_mode
== VA_RC_CBR
) {
1105 // These still need to be set for pic_init_qp/slice_qp_delta.
1106 priv
->fixed_qp_idr
= 26;
1107 priv
->fixed_qp_p
= 26;
1108 priv
->fixed_qp_b
= 26;
1110 av_log(avctx
, AV_LOG_DEBUG
, "Using constant-bitrate = %d bps.\n",
1114 av_assert0(0 && "Invalid RC mode.");
1117 if (opt
->quality
> 0) {
1118 #if VA_CHECK_VERSION(0, 36, 0)
1119 priv
->quality_params
.misc
.type
=
1120 VAEncMiscParameterTypeQualityLevel
;
1121 priv
->quality_params
.quality
.quality_level
= opt
->quality
;
1123 ctx
->global_params
[ctx
->nb_global_params
] =
1124 &priv
->quality_params
.misc
;
1125 ctx
->global_params_size
[ctx
->nb_global_params
++] =
1126 sizeof(priv
->quality_params
);
1128 av_log(avctx
, AV_LOG_WARNING
, "The encode quality option is not "
1129 "supported with this VAAPI version.\n");
1136 static const VAAPIEncodeType vaapi_encode_type_h264
= {
1137 .priv_data_size
= sizeof(VAAPIEncodeH264Context
),
1139 .configure
= &vaapi_encode_h264_configure
,
1141 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferH264
),
1142 .init_sequence_params
= &vaapi_encode_h264_init_sequence_params
,
1144 .picture_params_size
= sizeof(VAEncPictureParameterBufferH264
),
1145 .init_picture_params
= &vaapi_encode_h264_init_picture_params
,
1147 .slice_params_size
= sizeof(VAEncSliceParameterBufferH264
),
1148 .init_slice_params
= &vaapi_encode_h264_init_slice_params
,
1150 .sequence_header_type
= VAEncPackedHeaderSequence
,
1151 .write_sequence_header
= &vaapi_encode_h264_write_sequence_header
,
1153 .slice_header_type
= VAEncPackedHeaderH264_Slice
,
1154 .write_slice_header
= &vaapi_encode_h264_write_slice_header
,
1156 .write_extra_header
= &vaapi_encode_h264_write_extra_header
,
1159 static av_cold
int vaapi_encode_h264_init(AVCodecContext
*avctx
)
1161 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1162 VAAPIEncodeH264Options
*opt
=
1163 (VAAPIEncodeH264Options
*)ctx
->codec_options_data
;
1165 ctx
->codec
= &vaapi_encode_type_h264
;
1167 switch (avctx
->profile
) {
1168 case FF_PROFILE_H264_CONSTRAINED_BASELINE
:
1169 ctx
->va_profile
= VAProfileH264ConstrainedBaseline
;
1171 case FF_PROFILE_H264_BASELINE
:
1172 ctx
->va_profile
= VAProfileH264Baseline
;
1174 case FF_PROFILE_H264_MAIN
:
1175 ctx
->va_profile
= VAProfileH264Main
;
1177 case FF_PROFILE_H264_EXTENDED
:
1178 av_log(avctx
, AV_LOG_ERROR
, "H.264 extended profile "
1179 "is not supported.\n");
1180 return AVERROR_PATCHWELCOME
;
1181 case FF_PROFILE_UNKNOWN
:
1182 case FF_PROFILE_H264_HIGH
:
1183 ctx
->va_profile
= VAProfileH264High
;
1185 case FF_PROFILE_H264_HIGH_10
:
1186 case FF_PROFILE_H264_HIGH_10_INTRA
:
1187 av_log(avctx
, AV_LOG_ERROR
, "H.264 10-bit profiles "
1188 "are not supported.\n");
1189 return AVERROR_PATCHWELCOME
;
1190 case FF_PROFILE_H264_HIGH_422
:
1191 case FF_PROFILE_H264_HIGH_422_INTRA
:
1192 case FF_PROFILE_H264_HIGH_444
:
1193 case FF_PROFILE_H264_HIGH_444_PREDICTIVE
:
1194 case FF_PROFILE_H264_HIGH_444_INTRA
:
1195 case FF_PROFILE_H264_CAVLC_444
:
1196 av_log(avctx
, AV_LOG_ERROR
, "H.264 non-4:2:0 profiles "
1197 "are not supported.\n");
1198 return AVERROR_PATCHWELCOME
;
1200 av_log(avctx
, AV_LOG_ERROR
, "Unknown H.264 profile %d.\n",
1202 return AVERROR(EINVAL
);
1204 if (opt
->low_power
) {
1205 #if VA_CHECK_VERSION(0, 39, 2)
1206 ctx
->va_entrypoint
= VAEntrypointEncSliceLP
;
1208 av_log(avctx
, AV_LOG_ERROR
, "Low-power encoding is not "
1209 "supported with this VAAPI version.\n");
1210 return AVERROR(EINVAL
);
1213 ctx
->va_entrypoint
= VAEntrypointEncSlice
;
1216 // Only 8-bit encode is supported.
1217 ctx
->va_rt_format
= VA_RT_FORMAT_YUV420
;
1219 if (avctx
->bit_rate
> 0)
1220 ctx
->va_rc_mode
= VA_RC_CBR
;
1222 ctx
->va_rc_mode
= VA_RC_CQP
;
1224 ctx
->va_packed_headers
=
1225 VA_ENC_PACKED_HEADER_SEQUENCE
| // SPS and PPS.
1226 VA_ENC_PACKED_HEADER_SLICE
| // Slice headers.
1227 VA_ENC_PACKED_HEADER_MISC
; // SEI.
1229 ctx
->surface_width
= FFALIGN(avctx
->width
, 16);
1230 ctx
->surface_height
= FFALIGN(avctx
->height
, 16);
1232 return ff_vaapi_encode_init(avctx
);
1235 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
1236 offsetof(VAAPIEncodeH264Options, x))
1237 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1238 static const AVOption vaapi_encode_h264_options
[] = {
1239 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1240 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 20 }, 0, 52, FLAGS
},
1241 { "quality", "Set encode quality (trades off against speed, higher is faster)",
1242 OFFSET(quality
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 8, FLAGS
},
1243 { "low_power", "Use low-power encoding mode (experimental: only supported "
1244 "on some platforms, does not support all features)",
1245 OFFSET(low_power
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, FLAGS
},
1249 static const AVCodecDefault vaapi_encode_h264_defaults
[] = {
1250 { "profile", "100" },
1255 { "i_qfactor", "1.0" },
1256 { "i_qoffset", "0.0" },
1257 { "b_qfactor", "1.2" },
1258 { "b_qoffset", "0.0" },
1262 static const AVClass vaapi_encode_h264_class
= {
1263 .class_name
= "h264_vaapi",
1264 .item_name
= av_default_item_name
,
1265 .option
= vaapi_encode_h264_options
,
1266 .version
= LIBAVUTIL_VERSION_INT
,
1269 AVCodec ff_h264_vaapi_encoder
= {
1270 .name
= "h264_vaapi",
1271 .long_name
= NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
1272 .type
= AVMEDIA_TYPE_VIDEO
,
1273 .id
= AV_CODEC_ID_H264
,
1274 .priv_data_size
= (sizeof(VAAPIEncodeContext
) +
1275 sizeof(VAAPIEncodeH264Options
)),
1276 .init
= &vaapi_encode_h264_init
,
1277 .encode2
= &ff_vaapi_encode2
,
1278 .close
= &ff_vaapi_encode_close
,
1279 .priv_class
= &vaapi_encode_h264_class
,
1280 .capabilities
= AV_CODEC_CAP_DELAY
,
1281 .defaults
= vaapi_encode_h264_defaults
,
1282 .pix_fmts
= (const enum AVPixelFormat
[]) {