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"
30 #include "vaapi_encode.h"
31 #include "vaapi_encode_h26x.h"
41 // This structure contains all possibly-useful per-sequence syntax elements
42 // which are not already contained in the various VAAPI structures.
43 typedef struct VAAPIEncodeH264MiscSequenceParams
{
44 unsigned int profile_idc
;
45 char constraint_set0_flag
;
46 char constraint_set1_flag
;
47 char constraint_set2_flag
;
48 char constraint_set3_flag
;
49 char constraint_set4_flag
;
50 char constraint_set5_flag
;
52 char separate_colour_plane_flag
;
53 char qpprime_y_zero_transform_bypass_flag
;
55 char gaps_in_frame_num_allowed_flag
;
56 char delta_pic_order_always_zero_flag
;
57 char bottom_field_pic_order_in_frame_present_flag
;
59 unsigned int num_slice_groups_minus1
;
60 unsigned int slice_group_map_type
;
62 int pic_init_qs_minus26
;
64 char vui_parameters_present_flag
;
65 } VAAPIEncodeH264MiscSequenceParams
;
67 // This structure contains all possibly-useful per-slice syntax elements
68 // which are not already contained in the various VAAPI structures.
69 typedef struct VAAPIEncodeH264MiscSliceParams
{
70 unsigned int nal_unit_type
;
71 unsigned int nal_ref_idc
;
73 unsigned int colour_plane_id
;
75 char bottom_field_flag
;
77 unsigned int redundant_pic_cnt
;
79 char sp_for_switch_flag
;
82 char ref_pic_list_modification_flag_l0
;
83 char ref_pic_list_modification_flag_l1
;
85 char no_output_of_prior_pics_flag
;
86 char long_term_reference_flag
;
87 char adaptive_ref_pic_marking_mode_flag
;
88 } VAAPIEncodeH264MiscSliceParams
;
90 typedef struct VAAPIEncodeH264Slice
{
91 VAAPIEncodeH264MiscSliceParams misc_slice_params
;
92 } VAAPIEncodeH264Slice
;
94 typedef struct VAAPIEncodeH264Context
{
95 VAAPIEncodeH264MiscSequenceParams misc_sequence_params
;
105 int64_t idr_pic_count
;
107 // Rate control configuration.
109 VAEncMiscParameterBuffer misc
;
110 VAEncMiscParameterRateControl rc
;
113 VAEncMiscParameterBuffer misc
;
114 VAEncMiscParameterHRD hrd
;
117 #if VA_CHECK_VERSION(0, 36, 0)
118 // Speed-quality tradeoff setting.
120 VAEncMiscParameterBuffer misc
;
121 VAEncMiscParameterBufferQualityLevel quality
;
124 } VAAPIEncodeH264Context
;
126 typedef struct VAAPIEncodeH264Options
{
129 } VAAPIEncodeH264Options
;
132 #define vseq_var(name) vseq->name, name
133 #define vseq_field(name) vseq->seq_fields.bits.name, name
134 #define vpic_var(name) vpic->name, name
135 #define vpic_field(name) vpic->pic_fields.bits.name, name
136 #define vslice_var(name) vslice->name, name
137 #define vslice_field(name) vslice->slice_fields.bits.name, name
138 #define mseq_var(name) mseq->name, name
139 #define mslice_var(name) mslice->name, name
141 static void vaapi_encode_h264_write_nal_header(PutBitContext
*pbc
,
142 int nal_unit_type
, int nal_ref_idc
)
144 u(1, 0, forbidden_zero_bit
);
145 u(2, nal_ref_idc
, nal_ref_idc
);
146 u(5, nal_unit_type
, nal_unit_type
);
149 static void vaapi_encode_h264_write_trailing_rbsp(PutBitContext
*pbc
)
151 u(1, 1, rbsp_stop_one_bit
);
152 while (put_bits_count(pbc
) & 7)
153 u(1, 0, rbsp_alignment_zero_bit
);
156 static void vaapi_encode_h264_write_sps(PutBitContext
*pbc
,
157 VAAPIEncodeContext
*ctx
)
159 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
160 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
161 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
164 vaapi_encode_h264_write_nal_header(pbc
, NAL_SPS
, 3);
166 u(8, mseq_var(profile_idc
));
167 u(1, mseq_var(constraint_set0_flag
));
168 u(1, mseq_var(constraint_set1_flag
));
169 u(1, mseq_var(constraint_set2_flag
));
170 u(1, mseq_var(constraint_set3_flag
));
171 u(1, mseq_var(constraint_set4_flag
));
172 u(1, mseq_var(constraint_set5_flag
));
173 u(2, 0, reserved_zero_2bits
);
175 u(8, vseq_var(level_idc
));
177 ue(vseq_var(seq_parameter_set_id
));
179 if (mseq
->profile_idc
== 100 || mseq
->profile_idc
== 110 ||
180 mseq
->profile_idc
== 122 || mseq
->profile_idc
== 244 ||
181 mseq
->profile_idc
== 44 || mseq
->profile_idc
== 83 ||
182 mseq
->profile_idc
== 86 || mseq
->profile_idc
== 118 ||
183 mseq
->profile_idc
== 128 || mseq
->profile_idc
== 138) {
184 ue(vseq_field(chroma_format_idc
));
186 if (vseq
->seq_fields
.bits
.chroma_format_idc
== 3)
187 u(1, mseq_var(separate_colour_plane_flag
));
189 ue(vseq_var(bit_depth_luma_minus8
));
190 ue(vseq_var(bit_depth_chroma_minus8
));
192 u(1, mseq_var(qpprime_y_zero_transform_bypass_flag
));
194 u(1, vseq_field(seq_scaling_matrix_present_flag
));
195 if (vseq
->seq_fields
.bits
.seq_scaling_matrix_present_flag
) {
196 av_assert0(0 && "scaling matrices not supported");
200 ue(vseq_field(log2_max_frame_num_minus4
));
201 ue(vseq_field(pic_order_cnt_type
));
203 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 0) {
204 ue(vseq_field(log2_max_pic_order_cnt_lsb_minus4
));
205 } else if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 1) {
206 u(1, mseq_var(delta_pic_order_always_zero_flag
));
207 se(vseq_var(offset_for_non_ref_pic
));
208 se(vseq_var(offset_for_top_to_bottom_field
));
209 ue(vseq_var(num_ref_frames_in_pic_order_cnt_cycle
));
211 for (i
= 0; i
< vseq
->num_ref_frames_in_pic_order_cnt_cycle
; i
++)
212 se(vseq_var(offset_for_ref_frame
[i
]));
215 ue(vseq_var(max_num_ref_frames
));
216 u(1, mseq_var(gaps_in_frame_num_allowed_flag
));
218 ue(vseq
->picture_width_in_mbs
- 1, pic_width_in_mbs_minus1
);
219 ue(vseq
->picture_height_in_mbs
- 1, pic_height_in_mbs_minus1
);
221 u(1, vseq_field(frame_mbs_only_flag
));
222 if (!vseq
->seq_fields
.bits
.frame_mbs_only_flag
)
223 u(1, vseq_field(mb_adaptive_frame_field_flag
));
225 u(1, vseq_field(direct_8x8_inference_flag
));
227 u(1, vseq_var(frame_cropping_flag
));
228 if (vseq
->frame_cropping_flag
) {
229 ue(vseq_var(frame_crop_left_offset
));
230 ue(vseq_var(frame_crop_right_offset
));
231 ue(vseq_var(frame_crop_top_offset
));
232 ue(vseq_var(frame_crop_bottom_offset
));
235 u(1, mseq_var(vui_parameters_present_flag
));
237 vaapi_encode_h264_write_trailing_rbsp(pbc
);
240 static void vaapi_encode_h264_write_pps(PutBitContext
*pbc
,
241 VAAPIEncodeContext
*ctx
)
243 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
244 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
245 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
247 vaapi_encode_h264_write_nal_header(pbc
, NAL_PPS
, 3);
249 ue(vpic_var(pic_parameter_set_id
));
250 ue(vpic_var(seq_parameter_set_id
));
252 u(1, vpic_field(entropy_coding_mode_flag
));
253 u(1, mseq_var(bottom_field_pic_order_in_frame_present_flag
));
255 ue(mseq_var(num_slice_groups_minus1
));
256 if (mseq
->num_slice_groups_minus1
> 0) {
257 ue(mseq_var(slice_group_map_type
));
258 av_assert0(0 && "slice groups not supported");
261 ue(vpic_var(num_ref_idx_l0_active_minus1
));
262 ue(vpic_var(num_ref_idx_l1_active_minus1
));
264 u(1, vpic_field(weighted_pred_flag
));
265 u(2, vpic_field(weighted_bipred_idc
));
267 se(vpic
->pic_init_qp
- 26, pic_init_qp_minus26
);
268 se(mseq_var(pic_init_qs_minus26
));
269 se(vpic_var(chroma_qp_index_offset
));
271 u(1, vpic_field(deblocking_filter_control_present_flag
));
272 u(1, vpic_field(constrained_intra_pred_flag
));
273 u(1, vpic_field(redundant_pic_cnt_present_flag
));
274 u(1, vpic_field(transform_8x8_mode_flag
));
276 u(1, vpic_field(pic_scaling_matrix_present_flag
));
277 if (vpic
->pic_fields
.bits
.pic_scaling_matrix_present_flag
) {
278 av_assert0(0 && "scaling matrices not supported");
281 se(vpic_var(second_chroma_qp_index_offset
));
283 vaapi_encode_h264_write_trailing_rbsp(pbc
);
286 static void vaapi_encode_h264_write_slice_header2(PutBitContext
*pbc
,
287 VAAPIEncodeContext
*ctx
,
288 VAAPIEncodePicture
*pic
,
289 VAAPIEncodeSlice
*slice
)
291 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
292 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
293 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
294 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
295 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
296 VAAPIEncodeH264Slice
*pslice
= slice
->priv_data
;
297 VAAPIEncodeH264MiscSliceParams
*mslice
= &pslice
->misc_slice_params
;
299 vaapi_encode_h264_write_nal_header(pbc
, mslice
->nal_unit_type
,
300 mslice
->nal_ref_idc
);
302 ue(vslice
->macroblock_address
, first_mb_in_slice
);
303 ue(vslice_var(slice_type
));
304 ue(vpic_var(pic_parameter_set_id
));
306 if (mseq
->separate_colour_plane_flag
) {
307 u(2, mslice_var(colour_plane_id
));
310 u(4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
,
312 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
)) - 1)),
315 if (!vseq
->seq_fields
.bits
.frame_mbs_only_flag
) {
316 u(1, mslice_var(field_pic_flag
));
317 if (mslice
->field_pic_flag
)
318 u(1, mslice_var(bottom_field_flag
));
321 if (vpic
->pic_fields
.bits
.idr_pic_flag
) {
322 ue(vslice_var(idr_pic_id
));
325 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 0) {
326 u(4 + vseq
->seq_fields
.bits
.log2_max_pic_order_cnt_lsb_minus4
,
327 vslice_var(pic_order_cnt_lsb
));
328 if (mseq
->bottom_field_pic_order_in_frame_present_flag
&&
329 !mslice
->field_pic_flag
) {
330 se(vslice_var(delta_pic_order_cnt_bottom
));
334 if (vseq
->seq_fields
.bits
.pic_order_cnt_type
== 1 &&
335 !vseq
->seq_fields
.bits
.delta_pic_order_always_zero_flag
) {
336 se(vslice_var(delta_pic_order_cnt
[0]));
337 if (mseq
->bottom_field_pic_order_in_frame_present_flag
&&
338 !mslice
->field_pic_flag
) {
339 se(vslice_var(delta_pic_order_cnt
[1]));
343 if (vpic
->pic_fields
.bits
.redundant_pic_cnt_present_flag
) {
344 ue(mslice_var(redundant_pic_cnt
));
347 if (vslice
->slice_type
== SLICE_TYPE_B
) {
348 u(1, vslice_var(direct_spatial_mv_pred_flag
));
351 if (vslice
->slice_type
== SLICE_TYPE_P
||
352 vslice
->slice_type
== SLICE_TYPE_SP
||
353 vslice
->slice_type
== SLICE_TYPE_B
) {
354 u(1, vslice_var(num_ref_idx_active_override_flag
));
355 if (vslice
->num_ref_idx_active_override_flag
) {
356 ue(vslice_var(num_ref_idx_l0_active_minus1
));
357 if (vslice
->slice_type
== SLICE_TYPE_B
)
358 ue(vslice_var(num_ref_idx_l1_active_minus1
));
362 if (mslice
->nal_unit_type
== 20 || mslice
->nal_unit_type
== 21) {
363 av_assert0(0 && "no MVC support");
365 if (vslice
->slice_type
% 5 != 2 && vslice
->slice_type
% 5 != 4) {
366 u(1, mslice_var(ref_pic_list_modification_flag_l0
));
367 if (mslice
->ref_pic_list_modification_flag_l0
) {
368 av_assert0(0 && "ref pic list modification");
371 if (vslice
->slice_type
% 5 == 1) {
372 u(1, mslice_var(ref_pic_list_modification_flag_l1
));
373 if (mslice
->ref_pic_list_modification_flag_l1
) {
374 av_assert0(0 && "ref pic list modification");
379 if ((vpic
->pic_fields
.bits
.weighted_pred_flag
&&
380 (vslice
->slice_type
== SLICE_TYPE_P
||
381 vslice
->slice_type
== SLICE_TYPE_SP
)) ||
382 (vpic
->pic_fields
.bits
.weighted_bipred_idc
== 1 &&
383 vslice
->slice_type
== SLICE_TYPE_B
)) {
384 av_assert0(0 && "prediction weights not supported");
387 av_assert0(mslice
->nal_ref_idc
> 0 ==
388 vpic
->pic_fields
.bits
.reference_pic_flag
);
389 if (mslice
->nal_ref_idc
!= 0) {
390 if (vpic
->pic_fields
.bits
.idr_pic_flag
) {
391 u(1, mslice_var(no_output_of_prior_pics_flag
));
392 u(1, mslice_var(long_term_reference_flag
));
394 u(1, mslice_var(adaptive_ref_pic_marking_mode_flag
));
395 if (mslice
->adaptive_ref_pic_marking_mode_flag
) {
396 av_assert0(0 && "MMCOs not supported");
401 if (vpic
->pic_fields
.bits
.entropy_coding_mode_flag
&&
402 vslice
->slice_type
!= SLICE_TYPE_I
&&
403 vslice
->slice_type
!= SLICE_TYPE_SI
) {
404 ue(vslice_var(cabac_init_idc
));
407 se(vslice_var(slice_qp_delta
));
408 if (vslice
->slice_type
== SLICE_TYPE_SP
||
409 vslice
->slice_type
== SLICE_TYPE_SI
) {
410 if (vslice
->slice_type
== SLICE_TYPE_SP
)
411 u(1, mslice_var(sp_for_switch_flag
));
412 se(mslice_var(slice_qs_delta
));
415 if (vpic
->pic_fields
.bits
.deblocking_filter_control_present_flag
) {
416 ue(vslice_var(disable_deblocking_filter_idc
));
417 if (vslice
->disable_deblocking_filter_idc
!= 1) {
418 se(vslice_var(slice_alpha_c0_offset_div2
));
419 se(vslice_var(slice_beta_offset_div2
));
423 if (mseq
->num_slice_groups_minus1
> 0 &&
424 mseq
->slice_group_map_type
>= 3 && mseq
->slice_group_map_type
<= 5) {
425 av_assert0(0 && "slice groups not supported");
428 // No alignment - this need not be a byte boundary.
431 static int vaapi_encode_h264_write_sequence_header(AVCodecContext
*avctx
,
432 char *data
, size_t *data_len
)
434 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
438 size_t nal_len
, bit_len
, bit_pos
, next_len
;
443 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
444 vaapi_encode_h264_write_sps(&pbc
, ctx
);
445 nal_len
= put_bits_count(&pbc
);
446 flush_put_bits(&pbc
);
448 next_len
= bit_len
- bit_pos
;
449 err
= ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
+ bit_pos
/ 8,
456 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
457 vaapi_encode_h264_write_pps(&pbc
, ctx
);
458 nal_len
= put_bits_count(&pbc
);
459 flush_put_bits(&pbc
);
461 next_len
= bit_len
- bit_pos
;
462 err
= ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
+ bit_pos
/ 8,
473 static int vaapi_encode_h264_write_slice_header(AVCodecContext
*avctx
,
474 VAAPIEncodePicture
*pic
,
475 VAAPIEncodeSlice
*slice
,
476 char *data
, size_t *data_len
)
478 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
483 init_put_bits(&pbc
, tmp
, sizeof(tmp
));
484 vaapi_encode_h264_write_slice_header2(&pbc
, ctx
, pic
, slice
);
485 header_len
= put_bits_count(&pbc
);
486 flush_put_bits(&pbc
);
488 return ff_vaapi_encode_h26x_nal_unit_to_byte_stream(data
, data_len
,
492 static int vaapi_encode_h264_init_sequence_params(AVCodecContext
*avctx
)
494 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
495 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
496 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
497 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
498 VAAPIEncodeH264MiscSequenceParams
*mseq
= &priv
->misc_sequence_params
;
502 vseq
->seq_parameter_set_id
= 0;
504 vseq
->level_idc
= avctx
->level
;
506 vseq
->max_num_ref_frames
= 2;
508 vseq
->picture_width_in_mbs
= priv
->mb_width
;
509 vseq
->picture_height_in_mbs
= priv
->mb_height
;
511 vseq
->seq_fields
.bits
.chroma_format_idc
= 1;
512 vseq
->seq_fields
.bits
.frame_mbs_only_flag
= 1;
513 vseq
->seq_fields
.bits
.direct_8x8_inference_flag
= 1;
514 vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
= 4;
515 vseq
->seq_fields
.bits
.pic_order_cnt_type
= 0;
517 if (ctx
->input_width
!= ctx
->aligned_width
||
518 ctx
->input_height
!= ctx
->aligned_height
) {
519 vseq
->frame_cropping_flag
= 1;
521 vseq
->frame_crop_left_offset
= 0;
522 vseq
->frame_crop_right_offset
=
523 (ctx
->aligned_width
- ctx
->input_width
) / 2;
524 vseq
->frame_crop_top_offset
= 0;
525 vseq
->frame_crop_bottom_offset
=
526 (ctx
->aligned_height
- ctx
->input_height
) / 2;
528 vseq
->frame_cropping_flag
= 0;
531 vseq
->bits_per_second
= avctx
->bit_rate
;
532 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
533 vseq
->num_units_in_tick
= avctx
->framerate
.num
;
534 vseq
->time_scale
= 2 * avctx
->framerate
.den
;
536 vseq
->num_units_in_tick
= avctx
->time_base
.num
;
537 vseq
->time_scale
= 2 * avctx
->time_base
.den
;
540 vseq
->intra_period
= ctx
->p_per_i
* (ctx
->b_per_p
+ 1);
541 vseq
->intra_idr_period
= vseq
->intra_period
;
542 vseq
->ip_period
= ctx
->b_per_p
+ 1;
546 vpic
->CurrPic
.picture_id
= VA_INVALID_ID
;
547 vpic
->CurrPic
.flags
= VA_PICTURE_H264_INVALID
;
549 for (i
= 0; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
550 vpic
->ReferenceFrames
[i
].picture_id
= VA_INVALID_ID
;
551 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_INVALID
;
554 vpic
->coded_buf
= VA_INVALID_ID
;
556 vpic
->pic_parameter_set_id
= 0;
557 vpic
->seq_parameter_set_id
= 0;
559 vpic
->num_ref_idx_l0_active_minus1
= 0;
560 vpic
->num_ref_idx_l1_active_minus1
= 0;
562 vpic
->pic_fields
.bits
.entropy_coding_mode_flag
=
563 ((avctx
->profile
& 0xff) != 66);
564 vpic
->pic_fields
.bits
.weighted_pred_flag
= 0;
565 vpic
->pic_fields
.bits
.weighted_bipred_idc
= 0;
566 vpic
->pic_fields
.bits
.transform_8x8_mode_flag
=
567 ((avctx
->profile
& 0xff) >= 100);
569 vpic
->pic_init_qp
= priv
->fixed_qp_idr
;
573 mseq
->profile_idc
= avctx
->profile
& 0xff;
575 if (avctx
->profile
& FF_PROFILE_H264_CONSTRAINED
)
576 mseq
->constraint_set1_flag
= 1;
577 if (avctx
->profile
& FF_PROFILE_H264_INTRA
)
578 mseq
->constraint_set3_flag
= 1;
584 static int vaapi_encode_h264_init_picture_params(AVCodecContext
*avctx
,
585 VAAPIEncodePicture
*pic
)
587 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
588 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
589 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
590 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
593 if (pic
->type
== PICTURE_TYPE_IDR
) {
594 av_assert0(pic
->display_order
== pic
->encode_order
);
596 priv
->next_frame_num
= 1;
598 vpic
->frame_num
= priv
->next_frame_num
;
599 if (pic
->type
!= PICTURE_TYPE_B
) {
601 ++priv
->next_frame_num
;
605 vpic
->frame_num
= vpic
->frame_num
&
606 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_frame_num_minus4
)) - 1);
608 vpic
->CurrPic
.picture_id
= pic
->recon_surface
;
609 vpic
->CurrPic
.frame_idx
= vpic
->frame_num
;
610 vpic
->CurrPic
.flags
= 0;
611 vpic
->CurrPic
.TopFieldOrderCnt
= pic
->display_order
;
612 vpic
->CurrPic
.BottomFieldOrderCnt
= pic
->display_order
;
614 for (i
= 0; i
< pic
->nb_refs
; i
++) {
615 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
616 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
617 vpic
->ReferenceFrames
[i
].picture_id
= ref
->recon_surface
;
618 vpic
->ReferenceFrames
[i
].frame_idx
= ref
->encode_order
;
619 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_SHORT_TERM_REFERENCE
;
620 vpic
->ReferenceFrames
[i
].TopFieldOrderCnt
= ref
->display_order
;
621 vpic
->ReferenceFrames
[i
].BottomFieldOrderCnt
= ref
->display_order
;
623 for (; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
624 vpic
->ReferenceFrames
[i
].picture_id
= VA_INVALID_ID
;
625 vpic
->ReferenceFrames
[i
].flags
= VA_PICTURE_H264_INVALID
;
628 vpic
->coded_buf
= pic
->output_buffer
;
630 vpic
->pic_fields
.bits
.idr_pic_flag
= (pic
->type
== PICTURE_TYPE_IDR
);
631 vpic
->pic_fields
.bits
.reference_pic_flag
= (pic
->type
!= PICTURE_TYPE_B
);
638 static int vaapi_encode_h264_init_slice_params(AVCodecContext
*avctx
,
639 VAAPIEncodePicture
*pic
,
640 VAAPIEncodeSlice
*slice
)
642 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
643 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
644 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
645 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
646 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
647 VAAPIEncodeH264Slice
*pslice
;
648 VAAPIEncodeH264MiscSliceParams
*mslice
;
651 slice
->priv_data
= av_mallocz(sizeof(*pslice
));
652 if (!slice
->priv_data
)
653 return AVERROR(ENOMEM
);
654 pslice
= slice
->priv_data
;
655 mslice
= &pslice
->misc_slice_params
;
657 if (pic
->type
== PICTURE_TYPE_IDR
)
658 mslice
->nal_unit_type
= NAL_IDR_SLICE
;
660 mslice
->nal_unit_type
= NAL_SLICE
;
663 case PICTURE_TYPE_IDR
:
664 vslice
->slice_type
= SLICE_TYPE_I
;
665 mslice
->nal_ref_idc
= 3;
668 vslice
->slice_type
= SLICE_TYPE_I
;
669 mslice
->nal_ref_idc
= 2;
672 vslice
->slice_type
= SLICE_TYPE_P
;
673 mslice
->nal_ref_idc
= 1;
676 vslice
->slice_type
= SLICE_TYPE_B
;
677 mslice
->nal_ref_idc
= 0;
680 av_assert0(0 && "invalid picture type");
683 // Only one slice per frame.
684 vslice
->macroblock_address
= 0;
685 vslice
->num_macroblocks
= priv
->mb_width
* priv
->mb_height
;
687 vslice
->macroblock_info
= VA_INVALID_ID
;
689 vslice
->pic_parameter_set_id
= vpic
->pic_parameter_set_id
;
690 vslice
->idr_pic_id
= priv
->idr_pic_count
++;
692 vslice
->pic_order_cnt_lsb
= pic
->display_order
&
693 ((1 << (4 + vseq
->seq_fields
.bits
.log2_max_pic_order_cnt_lsb_minus4
)) - 1);
695 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->RefPicList0
); i
++) {
696 vslice
->RefPicList0
[i
].picture_id
= VA_INVALID_ID
;
697 vslice
->RefPicList0
[i
].flags
= VA_PICTURE_H264_INVALID
;
698 vslice
->RefPicList1
[i
].picture_id
= VA_INVALID_ID
;
699 vslice
->RefPicList1
[i
].flags
= VA_PICTURE_H264_INVALID
;
702 av_assert0(pic
->nb_refs
<= 2);
703 if (pic
->nb_refs
>= 1) {
704 // Backward reference for P- or B-frame.
705 av_assert0(pic
->type
== PICTURE_TYPE_P
||
706 pic
->type
== PICTURE_TYPE_B
);
708 vslice
->num_ref_idx_l0_active_minus1
= 0;
709 vslice
->RefPicList0
[0] = vpic
->ReferenceFrames
[0];
711 if (pic
->nb_refs
>= 2) {
712 // Forward reference for B-frame.
713 av_assert0(pic
->type
== PICTURE_TYPE_B
);
715 vslice
->num_ref_idx_l1_active_minus1
= 0;
716 vslice
->RefPicList1
[0] = vpic
->ReferenceFrames
[1];
719 if (pic
->type
== PICTURE_TYPE_B
)
720 vslice
->slice_qp_delta
= priv
->fixed_qp_b
- vpic
->pic_init_qp
;
721 else if (pic
->type
== PICTURE_TYPE_P
)
722 vslice
->slice_qp_delta
= priv
->fixed_qp_p
- vpic
->pic_init_qp
;
724 vslice
->slice_qp_delta
= priv
->fixed_qp_idr
- vpic
->pic_init_qp
;
726 vslice
->direct_spatial_mv_pred_flag
= 1;
731 static av_cold
int vaapi_encode_h264_init_constant_bitrate(AVCodecContext
*avctx
)
733 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
734 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
736 int hrd_initial_buffer_fullness
;
738 if (avctx
->rc_buffer_size
)
739 hrd_buffer_size
= avctx
->rc_buffer_size
;
741 hrd_buffer_size
= avctx
->bit_rate
;
742 if (avctx
->rc_initial_buffer_occupancy
)
743 hrd_initial_buffer_fullness
= avctx
->rc_initial_buffer_occupancy
;
745 hrd_initial_buffer_fullness
= hrd_buffer_size
* 3 / 4;
747 priv
->rc_params
.misc
.type
= VAEncMiscParameterTypeRateControl
;
748 priv
->rc_params
.rc
= (VAEncMiscParameterRateControl
) {
749 .bits_per_second
= avctx
->bit_rate
,
750 .target_percentage
= 66,
752 .initial_qp
= (avctx
->qmax
>= 0 ? avctx
->qmax
: 40),
753 .min_qp
= (avctx
->qmin
>= 0 ? avctx
->qmin
: 18),
754 .basic_unit_size
= 0,
756 ctx
->global_params
[ctx
->nb_global_params
] =
757 &priv
->rc_params
.misc
;
758 ctx
->global_params_size
[ctx
->nb_global_params
++] =
759 sizeof(priv
->rc_params
);
761 priv
->hrd_params
.misc
.type
= VAEncMiscParameterTypeHRD
;
762 priv
->hrd_params
.hrd
= (VAEncMiscParameterHRD
) {
763 .initial_buffer_fullness
= hrd_initial_buffer_fullness
,
764 .buffer_size
= hrd_buffer_size
,
766 ctx
->global_params
[ctx
->nb_global_params
] =
767 &priv
->hrd_params
.misc
;
768 ctx
->global_params_size
[ctx
->nb_global_params
++] =
769 sizeof(priv
->hrd_params
);
771 // These still need to be set for pic_init_qp/slice_qp_delta.
772 priv
->fixed_qp_idr
= 26;
773 priv
->fixed_qp_p
= 26;
774 priv
->fixed_qp_b
= 26;
776 av_log(avctx
, AV_LOG_DEBUG
, "Using constant-bitrate = %d bps.\n",
781 static av_cold
int vaapi_encode_h264_init_fixed_qp(AVCodecContext
*avctx
)
783 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
784 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
785 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
787 priv
->fixed_qp_p
= opt
->qp
;
788 if (avctx
->i_quant_factor
> 0.0)
789 priv
->fixed_qp_idr
= (int)((priv
->fixed_qp_p
* avctx
->i_quant_factor
+
790 avctx
->i_quant_offset
) + 0.5);
792 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
793 if (avctx
->b_quant_factor
> 0.0)
794 priv
->fixed_qp_b
= (int)((priv
->fixed_qp_p
* avctx
->b_quant_factor
+
795 avctx
->b_quant_offset
) + 0.5);
797 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
799 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
800 "%d / %d / %d for IDR- / P- / B-frames.\n",
801 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
805 static av_cold
int vaapi_encode_h264_init_internal(AVCodecContext
*avctx
)
807 static const VAConfigAttrib default_config_attributes
[] = {
808 { .type
= VAConfigAttribRTFormat
,
809 .value
= VA_RT_FORMAT_YUV420
},
810 { .type
= VAConfigAttribEncPackedHeaders
,
811 .value
= (VA_ENC_PACKED_HEADER_SEQUENCE
|
812 VA_ENC_PACKED_HEADER_SLICE
) },
815 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
816 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
817 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
820 switch (avctx
->profile
) {
821 case FF_PROFILE_H264_CONSTRAINED_BASELINE
:
822 ctx
->va_profile
= VAProfileH264ConstrainedBaseline
;
824 case FF_PROFILE_H264_BASELINE
:
825 ctx
->va_profile
= VAProfileH264Baseline
;
827 case FF_PROFILE_H264_MAIN
:
828 ctx
->va_profile
= VAProfileH264Main
;
830 case FF_PROFILE_H264_EXTENDED
:
831 av_log(avctx
, AV_LOG_ERROR
, "H.264 extended profile "
832 "is not supported.\n");
833 return AVERROR_PATCHWELCOME
;
834 case FF_PROFILE_UNKNOWN
:
835 case FF_PROFILE_H264_HIGH
:
836 ctx
->va_profile
= VAProfileH264High
;
838 case FF_PROFILE_H264_HIGH_10
:
839 case FF_PROFILE_H264_HIGH_10_INTRA
:
840 av_log(avctx
, AV_LOG_ERROR
, "H.264 10-bit profiles "
841 "are not supported.\n");
842 return AVERROR_PATCHWELCOME
;
843 case FF_PROFILE_H264_HIGH_422
:
844 case FF_PROFILE_H264_HIGH_422_INTRA
:
845 case FF_PROFILE_H264_HIGH_444
:
846 case FF_PROFILE_H264_HIGH_444_PREDICTIVE
:
847 case FF_PROFILE_H264_HIGH_444_INTRA
:
848 case FF_PROFILE_H264_CAVLC_444
:
849 av_log(avctx
, AV_LOG_ERROR
, "H.264 non-4:2:0 profiles "
850 "are not supported.\n");
851 return AVERROR_PATCHWELCOME
;
853 av_log(avctx
, AV_LOG_ERROR
, "Unknown H.264 profile %d.\n",
855 return AVERROR(EINVAL
);
857 ctx
->va_entrypoint
= VAEntrypointEncSlice
;
859 ctx
->input_width
= avctx
->width
;
860 ctx
->input_height
= avctx
->height
;
861 ctx
->aligned_width
= FFALIGN(ctx
->input_width
, 16);
862 ctx
->aligned_height
= FFALIGN(ctx
->input_height
, 16);
863 priv
->mb_width
= ctx
->aligned_width
/ 16;
864 priv
->mb_height
= ctx
->aligned_height
/ 16;
866 for (i
= 0; i
< FF_ARRAY_ELEMS(default_config_attributes
); i
++) {
867 ctx
->config_attributes
[ctx
->nb_config_attributes
++] =
868 default_config_attributes
[i
];
871 if (avctx
->bit_rate
> 0) {
872 ctx
->va_rc_mode
= VA_RC_CBR
;
873 err
= vaapi_encode_h264_init_constant_bitrate(avctx
);
875 ctx
->va_rc_mode
= VA_RC_CQP
;
876 err
= vaapi_encode_h264_init_fixed_qp(avctx
);
881 ctx
->config_attributes
[ctx
->nb_config_attributes
++] = (VAConfigAttrib
) {
882 .type
= VAConfigAttribRateControl
,
883 .value
= ctx
->va_rc_mode
,
886 if (opt
->quality
> 0) {
887 #if VA_CHECK_VERSION(0, 36, 0)
888 priv
->quality_params
.misc
.type
=
889 VAEncMiscParameterTypeQualityLevel
;
890 priv
->quality_params
.quality
.quality_level
= opt
->quality
;
892 ctx
->global_params
[ctx
->nb_global_params
] =
893 &priv
->quality_params
.misc
;
894 ctx
->global_params_size
[ctx
->nb_global_params
++] =
895 sizeof(priv
->quality_params
);
897 av_log(avctx
, AV_LOG_WARNING
, "The encode quality option is not "
898 "supported with this VAAPI version.\n");
902 ctx
->nb_recon_frames
= 20;
907 static VAAPIEncodeType vaapi_encode_type_h264
= {
908 .priv_data_size
= sizeof(VAAPIEncodeH264Context
),
910 .init
= &vaapi_encode_h264_init_internal
,
912 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferH264
),
913 .init_sequence_params
= &vaapi_encode_h264_init_sequence_params
,
915 .picture_params_size
= sizeof(VAEncPictureParameterBufferH264
),
916 .init_picture_params
= &vaapi_encode_h264_init_picture_params
,
918 .slice_params_size
= sizeof(VAEncSliceParameterBufferH264
),
919 .init_slice_params
= &vaapi_encode_h264_init_slice_params
,
921 .sequence_header_type
= VAEncPackedHeaderSequence
,
922 .write_sequence_header
= &vaapi_encode_h264_write_sequence_header
,
924 .slice_header_type
= VAEncPackedHeaderH264_Slice
,
925 .write_slice_header
= &vaapi_encode_h264_write_slice_header
,
928 static av_cold
int vaapi_encode_h264_init(AVCodecContext
*avctx
)
930 return ff_vaapi_encode_init(avctx
, &vaapi_encode_type_h264
);
933 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
934 offsetof(VAAPIEncodeH264Options, x))
935 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
936 static const AVOption vaapi_encode_h264_options
[] = {
937 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
938 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 20 }, 0, 52, FLAGS
},
939 { "quality", "Set encode quality (trades off against speed, higher is faster)",
940 OFFSET(quality
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 2, FLAGS
},
944 static const AVCodecDefault vaapi_encode_h264_defaults
[] = {
945 { "profile", "100" },
950 { "i_qfactor", "1.0" },
951 { "i_qoffset", "0.0" },
952 { "b_qfactor", "1.2" },
953 { "b_qoffset", "0.0" },
957 static const AVClass vaapi_encode_h264_class
= {
958 .class_name
= "h264_vaapi",
959 .item_name
= av_default_item_name
,
960 .option
= vaapi_encode_h264_options
,
961 .version
= LIBAVUTIL_VERSION_INT
,
964 AVCodec ff_h264_vaapi_encoder
= {
965 .name
= "h264_vaapi",
966 .long_name
= NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
967 .type
= AVMEDIA_TYPE_VIDEO
,
968 .id
= AV_CODEC_ID_H264
,
969 .priv_data_size
= (sizeof(VAAPIEncodeContext
) +
970 sizeof(VAAPIEncodeH264Options
)),
971 .init
= &vaapi_encode_h264_init
,
972 .encode2
= &ff_vaapi_encode2
,
973 .close
= &ff_vaapi_encode_close
,
974 .priv_class
= &vaapi_encode_h264_class
,
975 .capabilities
= AV_CODEC_CAP_DELAY
,
976 .defaults
= vaapi_encode_h264_defaults
,
977 .pix_fmts
= (const enum AVPixelFormat
[]) {