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
22 #include <va/va_enc_h264.h>
24 #include "libavutil/avassert.h"
25 #include "libavutil/common.h"
26 #include "libavutil/internal.h"
27 #include "libavutil/opt.h"
35 #include "vaapi_encode.h"
39 SEI_IDENTIFIER
= 0x02,
42 // Random (version 4) ISO 11578 UUID.
43 static const uint8_t vaapi_encode_h264_sei_identifier_uuid
[16] = {
44 0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf,
45 0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d,
48 typedef struct VAAPIEncodeH264Context
{
61 H264RawSEIBufferingPeriod buffering_period
;
62 H264RawSEIPicTiming pic_timing
;
63 H264RawSEIUserDataUnregistered identifier
;
64 char *identifier_string
;
69 int64_t last_idr_frame
;
70 int64_t idr_pic_count
;
78 CodedBitstreamContext cbc
;
79 CodedBitstreamFragment current_access_unit
;
81 } VAAPIEncodeH264Context
;
83 typedef struct VAAPIEncodeH264Options
{
88 } VAAPIEncodeH264Options
;
91 static int vaapi_encode_h264_write_access_unit(AVCodecContext
*avctx
,
92 char *data
, size_t *data_len
,
93 CodedBitstreamFragment
*au
)
95 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
96 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
99 err
= ff_cbs_write_fragment_data(&priv
->cbc
, au
);
101 av_log(avctx
, AV_LOG_ERROR
, "Failed to write packed header.\n");
105 if (*data_len
< 8 * au
->data_size
- au
->data_bit_padding
) {
106 av_log(avctx
, AV_LOG_ERROR
, "Access unit too large: "
107 "%zu < %zu.\n", *data_len
,
108 8 * au
->data_size
- au
->data_bit_padding
);
109 return AVERROR(ENOSPC
);
112 memcpy(data
, au
->data
, au
->data_size
);
113 *data_len
= 8 * au
->data_size
- au
->data_bit_padding
;
118 static int vaapi_encode_h264_add_nal(AVCodecContext
*avctx
,
119 CodedBitstreamFragment
*au
,
122 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
123 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
124 H264RawNALUnitHeader
*header
= nal_unit
;
127 err
= ff_cbs_insert_unit_content(&priv
->cbc
, au
, -1,
128 header
->nal_unit_type
, nal_unit
);
130 av_log(avctx
, AV_LOG_ERROR
, "Failed to add NAL unit: "
131 "type = %d.\n", header
->nal_unit_type
);
138 static int vaapi_encode_h264_write_sequence_header(AVCodecContext
*avctx
,
139 char *data
, size_t *data_len
)
141 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
142 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
143 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
146 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->sps
);
150 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->pps
);
154 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
156 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
160 static int vaapi_encode_h264_write_slice_header(AVCodecContext
*avctx
,
161 VAAPIEncodePicture
*pic
,
162 VAAPIEncodeSlice
*slice
,
163 char *data
, size_t *data_len
)
165 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
166 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
167 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
170 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->slice
);
174 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
176 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
180 static int vaapi_encode_h264_write_extra_header(AVCodecContext
*avctx
,
181 VAAPIEncodePicture
*pic
,
182 int index
, int *type
,
183 char *data
, size_t *data_len
)
185 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
186 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
187 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
188 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
191 if (priv
->sei_needed
) {
192 memset(&priv
->sei
, 0, sizeof(priv
->sei
));
193 priv
->sei
.nal_unit_header
.nal_unit_type
= H264_NAL_SEI
;
196 if (pic
->encode_order
== 0 && opt
->sei
& SEI_IDENTIFIER
) {
197 priv
->sei
.payload
[i
].payload_type
= H264_SEI_TYPE_USER_DATA_UNREGISTERED
;
198 priv
->sei
.payload
[i
].payload
.user_data_unregistered
= priv
->identifier
;
201 if (opt
->sei
& SEI_TIMING
) {
202 if (pic
->type
== PICTURE_TYPE_IDR
) {
203 priv
->sei
.payload
[i
].payload_type
= H264_SEI_TYPE_BUFFERING_PERIOD
;
204 priv
->sei
.payload
[i
].payload
.buffering_period
= priv
->buffering_period
;
207 priv
->sei
.payload
[i
].payload_type
= H264_SEI_TYPE_PIC_TIMING
;
208 priv
->sei
.payload
[i
].payload
.pic_timing
= priv
->pic_timing
;
212 priv
->sei
.payload_count
= i
;
213 av_assert0(priv
->sei
.payload_count
> 0);
215 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->sei
);
218 priv
->sei_needed
= 0;
220 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
224 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
226 *type
= VAEncPackedHeaderH264_SEI
;
233 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
237 static int vaapi_encode_h264_init_sequence_params(AVCodecContext
*avctx
)
239 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
240 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
241 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
242 H264RawSPS
*sps
= &priv
->sps
;
243 H264RawPPS
*pps
= &priv
->pps
;
244 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
245 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
247 memset(&priv
->current_access_unit
, 0,
248 sizeof(priv
->current_access_unit
));
250 memset(sps
, 0, sizeof(*sps
));
251 memset(pps
, 0, sizeof(*pps
));
253 sps
->nal_unit_header
.nal_ref_idc
= 3;
254 sps
->nal_unit_header
.nal_unit_type
= H264_NAL_SPS
;
256 sps
->profile_idc
= avctx
->profile
& 0xff;
257 sps
->constraint_set1_flag
=
258 !!(avctx
->profile
& FF_PROFILE_H264_CONSTRAINED
);
259 sps
->constraint_set3_flag
=
260 !!(avctx
->profile
& FF_PROFILE_H264_INTRA
);
262 sps
->level_idc
= avctx
->level
;
264 sps
->seq_parameter_set_id
= 0;
265 sps
->chroma_format_idc
= 1;
267 sps
->log2_max_frame_num_minus4
= 4;
268 sps
->pic_order_cnt_type
= 0;
269 sps
->log2_max_pic_order_cnt_lsb_minus4
=
270 av_clip(av_log2(ctx
->b_per_p
+ 1) - 2, 0, 12);
272 sps
->max_num_ref_frames
=
273 (avctx
->profile
& FF_PROFILE_H264_INTRA
) ?
0 :
274 1 + (ctx
->b_per_p
> 0);
276 sps
->pic_width_in_mbs_minus1
= priv
->mb_width
- 1;
277 sps
->pic_height_in_map_units_minus1
= priv
->mb_height
- 1;
279 sps
->frame_mbs_only_flag
= 1;
280 sps
->direct_8x8_inference_flag
= 1;
282 if (avctx
->width
!= 16 * priv
->mb_width
||
283 avctx
->height
!= 16 * priv
->mb_height
) {
284 sps
->frame_cropping_flag
= 1;
286 sps
->frame_crop_left_offset
= 0;
287 sps
->frame_crop_right_offset
=
288 (16 * priv
->mb_width
- avctx
->width
) / 2;
289 sps
->frame_crop_top_offset
= 0;
290 sps
->frame_crop_bottom_offset
=
291 (16 * priv
->mb_height
- avctx
->height
) / 2;
293 sps
->frame_cropping_flag
= 0;
296 sps
->vui_parameters_present_flag
= 1;
298 if (avctx
->sample_aspect_ratio
.num
!= 0 &&
299 avctx
->sample_aspect_ratio
.den
!= 0) {
300 static const AVRational sar_idc
[] = {
302 { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
303 { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
304 { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
305 { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
308 for (i
= 0; i
< FF_ARRAY_ELEMS(sar_idc
); i
++) {
309 if (avctx
->sample_aspect_ratio
.num
== sar_idc
[i
].num
&&
310 avctx
->sample_aspect_ratio
.den
== sar_idc
[i
].den
) {
311 sps
->vui
.aspect_ratio_idc
= i
;
315 if (i
>= FF_ARRAY_ELEMS(sar_idc
)) {
316 sps
->vui
.aspect_ratio_idc
= 255;
317 sps
->vui
.sar_width
= avctx
->sample_aspect_ratio
.num
;
318 sps
->vui
.sar_height
= avctx
->sample_aspect_ratio
.den
;
320 sps
->vui
.aspect_ratio_info_present_flag
= 1;
323 if (avctx
->color_range
!= AVCOL_RANGE_UNSPECIFIED
||
324 avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
325 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
326 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
327 sps
->vui
.video_signal_type_present_flag
= 1;
328 sps
->vui
.video_format
= 5; // Unspecified.
329 sps
->vui
.video_full_range_flag
=
330 avctx
->color_range
== AVCOL_RANGE_JPEG
;
332 if (avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
333 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
334 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
335 sps
->vui
.colour_description_present_flag
= 1;
336 sps
->vui
.colour_primaries
= avctx
->color_primaries
;
337 sps
->vui
.transfer_characteristics
= avctx
->color_trc
;
338 sps
->vui
.matrix_coefficients
= avctx
->colorspace
;
341 sps
->vui
.video_format
= 5;
342 sps
->vui
.video_full_range_flag
= 0;
343 sps
->vui
.colour_primaries
= avctx
->color_primaries
;
344 sps
->vui
.transfer_characteristics
= avctx
->color_trc
;
345 sps
->vui
.matrix_coefficients
= avctx
->colorspace
;
348 if (avctx
->chroma_sample_location
!= AVCHROMA_LOC_UNSPECIFIED
) {
349 sps
->vui
.chroma_loc_info_present_flag
= 1;
350 sps
->vui
.chroma_sample_loc_type_top_field
=
351 sps
->vui
.chroma_sample_loc_type_bottom_field
=
352 avctx
->chroma_sample_location
- 1;
355 sps
->vui
.timing_info_present_flag
= 1;
356 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
357 sps
->vui
.num_units_in_tick
= avctx
->framerate
.den
;
358 sps
->vui
.time_scale
= 2 * avctx
->framerate
.num
;
359 sps
->vui
.fixed_frame_rate_flag
= 1;
361 sps
->vui
.num_units_in_tick
= avctx
->time_base
.num
;
362 sps
->vui
.time_scale
= 2 * avctx
->time_base
.den
;
363 sps
->vui
.fixed_frame_rate_flag
= 0;
366 if (opt
->sei
& SEI_TIMING
) {
367 H264RawHRD
*hrd
= &sps
->vui
.nal_hrd_parameters
;
369 sps
->vui
.nal_hrd_parameters_present_flag
= 1;
371 hrd
->cpb_cnt_minus1
= 0;
373 // Try to scale these to a sensible range so that the
374 // golomb encode of the value is not overlong.
375 hrd
->bit_rate_scale
=
376 av_clip_uintp2(av_log2(avctx
->bit_rate
) - 15 - 6, 4);
377 hrd
->bit_rate_value_minus1
[0] =
378 (avctx
->bit_rate
>> hrd
->bit_rate_scale
+ 6) - 1;
380 hrd
->cpb_size_scale
=
381 av_clip_uintp2(av_log2(ctx
->hrd_params
.hrd
.buffer_size
) - 15 - 4, 4);
382 hrd
->cpb_size_value_minus1
[0] =
383 (ctx
->hrd_params
.hrd
.buffer_size
>> hrd
->cpb_size_scale
+ 4) - 1;
385 // CBR mode as defined for the HRD cannot be achieved without filler
386 // data, so this flag cannot be set even with VAAPI CBR modes.
387 hrd
->cbr_flag
[0] = 0;
389 hrd
->initial_cpb_removal_delay_length_minus1
= 23;
390 hrd
->cpb_removal_delay_length_minus1
= 23;
391 hrd
->dpb_output_delay_length_minus1
= 7;
392 hrd
->time_offset_length
= 0;
394 priv
->buffering_period
.seq_parameter_set_id
= sps
->seq_parameter_set_id
;
396 // This calculation can easily overflow 32 bits.
397 priv
->buffering_period
.nal
.initial_cpb_removal_delay
[0] = 90000 *
398 (uint64_t)ctx
->hrd_params
.hrd
.initial_buffer_fullness
/
399 ctx
->hrd_params
.hrd
.buffer_size
;
400 priv
->buffering_period
.nal
.initial_cpb_removal_delay_offset
[0] = 0;
402 sps
->vui
.nal_hrd_parameters_present_flag
= 0;
403 sps
->vui
.low_delay_hrd_flag
= 1 - sps
->vui
.fixed_frame_rate_flag
;
406 sps
->vui
.bitstream_restriction_flag
= 1;
407 sps
->vui
.motion_vectors_over_pic_boundaries_flag
= 1;
408 sps
->vui
.log2_max_mv_length_horizontal
= 16;
409 sps
->vui
.log2_max_mv_length_vertical
= 16;
410 sps
->vui
.max_num_reorder_frames
= (ctx
->b_per_p
> 0);
411 sps
->vui
.max_dec_frame_buffering
= vseq
->max_num_ref_frames
;
413 pps
->nal_unit_header
.nal_ref_idc
= 3;
414 pps
->nal_unit_header
.nal_unit_type
= H264_NAL_PPS
;
416 pps
->pic_parameter_set_id
= 0;
417 pps
->seq_parameter_set_id
= 0;
419 pps
->entropy_coding_mode_flag
=
420 !(sps
->profile_idc
== FF_PROFILE_H264_BASELINE
||
421 sps
->profile_idc
== FF_PROFILE_H264_EXTENDED
||
422 sps
->profile_idc
== FF_PROFILE_H264_CAVLC_444
);
424 pps
->num_ref_idx_l0_default_active_minus1
= 0;
425 pps
->num_ref_idx_l1_default_active_minus1
= 0;
427 pps
->pic_init_qp_minus26
= priv
->fixed_qp_idr
- 26;
429 if (sps
->profile_idc
== FF_PROFILE_H264_BASELINE
||
430 sps
->profile_idc
== FF_PROFILE_H264_EXTENDED
||
431 sps
->profile_idc
== FF_PROFILE_H264_MAIN
) {
432 pps
->more_rbsp_data
= 0;
434 pps
->more_rbsp_data
= 1;
436 pps
->transform_8x8_mode_flag
= 1;
439 *vseq
= (VAEncSequenceParameterBufferH264
) {
440 .seq_parameter_set_id
= sps
->seq_parameter_set_id
,
441 .level_idc
= sps
->level_idc
,
442 .intra_period
= avctx
->gop_size
,
443 .intra_idr_period
= avctx
->gop_size
,
444 .ip_period
= ctx
->b_per_p
+ 1,
446 .bits_per_second
= avctx
->bit_rate
,
447 .max_num_ref_frames
= sps
->max_num_ref_frames
,
448 .picture_width_in_mbs
= sps
->pic_width_in_mbs_minus1
+ 1,
449 .picture_height_in_mbs
= sps
->pic_height_in_map_units_minus1
+ 1,
452 .chroma_format_idc
= sps
->chroma_format_idc
,
453 .frame_mbs_only_flag
= sps
->frame_mbs_only_flag
,
454 .mb_adaptive_frame_field_flag
= sps
->mb_adaptive_frame_field_flag
,
455 .seq_scaling_matrix_present_flag
= sps
->seq_scaling_matrix_present_flag
,
456 .direct_8x8_inference_flag
= sps
->direct_8x8_inference_flag
,
457 .log2_max_frame_num_minus4
= sps
->log2_max_frame_num_minus4
,
458 .pic_order_cnt_type
= sps
->pic_order_cnt_type
,
459 .log2_max_pic_order_cnt_lsb_minus4
= sps
->log2_max_pic_order_cnt_lsb_minus4
,
460 .delta_pic_order_always_zero_flag
= sps
->delta_pic_order_always_zero_flag
,
463 .bit_depth_luma_minus8
= sps
->bit_depth_luma_minus8
,
464 .bit_depth_chroma_minus8
= sps
->bit_depth_chroma_minus8
,
466 .frame_cropping_flag
= sps
->frame_cropping_flag
,
467 .frame_crop_left_offset
= sps
->frame_crop_left_offset
,
468 .frame_crop_right_offset
= sps
->frame_crop_right_offset
,
469 .frame_crop_top_offset
= sps
->frame_crop_top_offset
,
470 .frame_crop_bottom_offset
= sps
->frame_crop_bottom_offset
,
472 .vui_parameters_present_flag
= sps
->vui_parameters_present_flag
,
475 .aspect_ratio_info_present_flag
= sps
->vui
.aspect_ratio_info_present_flag
,
476 .timing_info_present_flag
= sps
->vui
.timing_info_present_flag
,
477 .bitstream_restriction_flag
= sps
->vui
.bitstream_restriction_flag
,
478 .log2_max_mv_length_horizontal
= sps
->vui
.log2_max_mv_length_horizontal
,
479 .log2_max_mv_length_vertical
= sps
->vui
.log2_max_mv_length_vertical
,
482 .aspect_ratio_idc
= sps
->vui
.aspect_ratio_idc
,
483 .sar_width
= sps
->vui
.sar_width
,
484 .sar_height
= sps
->vui
.sar_height
,
485 .num_units_in_tick
= sps
->vui
.num_units_in_tick
,
486 .time_scale
= sps
->vui
.time_scale
,
489 *vpic
= (VAEncPictureParameterBufferH264
) {
491 .picture_id
= VA_INVALID_ID
,
492 .flags
= VA_PICTURE_H264_INVALID
,
495 .coded_buf
= VA_INVALID_ID
,
497 .pic_parameter_set_id
= pps
->pic_parameter_set_id
,
498 .seq_parameter_set_id
= pps
->seq_parameter_set_id
,
500 .pic_init_qp
= pps
->pic_init_qp_minus26
+ 26,
501 .num_ref_idx_l0_active_minus1
= pps
->num_ref_idx_l0_default_active_minus1
,
502 .num_ref_idx_l1_active_minus1
= pps
->num_ref_idx_l1_default_active_minus1
,
504 .chroma_qp_index_offset
= pps
->chroma_qp_index_offset
,
505 .second_chroma_qp_index_offset
= pps
->second_chroma_qp_index_offset
,
508 .entropy_coding_mode_flag
= pps
->entropy_coding_mode_flag
,
509 .weighted_pred_flag
= pps
->weighted_pred_flag
,
510 .weighted_bipred_idc
= pps
->weighted_bipred_idc
,
511 .constrained_intra_pred_flag
= pps
->constrained_intra_pred_flag
,
512 .transform_8x8_mode_flag
= pps
->transform_8x8_mode_flag
,
513 .deblocking_filter_control_present_flag
=
514 pps
->deblocking_filter_control_present_flag
,
515 .redundant_pic_cnt_present_flag
= pps
->redundant_pic_cnt_present_flag
,
516 .pic_order_present_flag
=
517 pps
->bottom_field_pic_order_in_frame_present_flag
,
518 .pic_scaling_matrix_present_flag
= pps
->pic_scaling_matrix_present_flag
,
525 static int vaapi_encode_h264_init_picture_params(AVCodecContext
*avctx
,
526 VAAPIEncodePicture
*pic
)
528 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
529 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
530 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
531 H264RawSPS
*sps
= &priv
->sps
;
532 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
535 memset(&priv
->current_access_unit
, 0,
536 sizeof(priv
->current_access_unit
));
538 if (pic
->type
== PICTURE_TYPE_IDR
) {
539 av_assert0(pic
->display_order
== pic
->encode_order
);
541 priv
->next_frame_num
= 1;
543 priv
->last_idr_frame
= pic
->display_order
;
544 ++priv
->idr_pic_count
;
546 priv
->slice_type
= 7;
547 priv
->primary_pic_type
= 0;
549 priv
->frame_num
= priv
->next_frame_num
;
551 if (pic
->type
!= PICTURE_TYPE_B
) {
552 // Reference picture, so frame_num advances.
553 priv
->next_frame_num
= (priv
->frame_num
+ 1) &
554 ((1 << (4 + sps
->log2_max_frame_num_minus4
)) - 1);
558 if (pic
->type
== PICTURE_TYPE_I
) {
559 priv
->slice_type
= 7;
560 priv
->primary_pic_type
= 0;
561 } else if (pic
->type
== PICTURE_TYPE_P
) {
562 priv
->slice_type
= 5;
563 priv
->primary_pic_type
= 1;
565 priv
->slice_type
= 6;
566 priv
->primary_pic_type
= 2;
569 priv
->pic_order_cnt
= pic
->display_order
- priv
->last_idr_frame
;
570 priv
->dpb_delay
= pic
->display_order
- pic
->encode_order
+ 1;
572 if (opt
->sei
& SEI_IDENTIFIER
&& pic
->encode_order
== 0)
573 priv
->sei_needed
= 1;
575 if (opt
->sei
& SEI_TIMING
) {
576 memset(&priv
->pic_timing
, 0, sizeof(priv
->pic_timing
));
578 priv
->pic_timing
.cpb_removal_delay
=
579 2 * sps
->vui
.num_units_in_tick
* priv
->cpb_delay
;
580 priv
->pic_timing
.dpb_output_delay
=
581 2 * sps
->vui
.num_units_in_tick
* priv
->dpb_delay
;
583 priv
->sei_needed
= 1;
586 vpic
->CurrPic
= (VAPictureH264
) {
587 .picture_id
= pic
->recon_surface
,
588 .frame_idx
= priv
->frame_num
,
590 .TopFieldOrderCnt
= priv
->pic_order_cnt
,
591 .BottomFieldOrderCnt
= priv
->pic_order_cnt
,
594 for (i
= 0; i
< pic
->nb_refs
; i
++) {
595 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
596 unsigned int frame_num
= (ref
->encode_order
- priv
->last_idr_frame
) &
597 ((1 << (4 + sps
->log2_max_frame_num_minus4
)) - 1);
598 unsigned int pic_order_cnt
= ref
->display_order
- priv
->last_idr_frame
;
600 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
601 vpic
->ReferenceFrames
[i
] = (VAPictureH264
) {
602 .picture_id
= ref
->recon_surface
,
603 .frame_idx
= frame_num
,
604 .flags
= VA_PICTURE_H264_SHORT_TERM_REFERENCE
,
605 .TopFieldOrderCnt
= pic_order_cnt
,
606 .BottomFieldOrderCnt
= pic_order_cnt
,
609 for (; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
610 vpic
->ReferenceFrames
[i
] = (VAPictureH264
) {
611 .picture_id
= VA_INVALID_ID
,
612 .flags
= VA_PICTURE_H264_INVALID
,
616 vpic
->coded_buf
= pic
->output_buffer
;
618 vpic
->frame_num
= priv
->frame_num
;
620 vpic
->pic_fields
.bits
.idr_pic_flag
= (pic
->type
== PICTURE_TYPE_IDR
);
621 vpic
->pic_fields
.bits
.reference_pic_flag
= (pic
->type
!= PICTURE_TYPE_B
);
628 static int vaapi_encode_h264_init_slice_params(AVCodecContext
*avctx
,
629 VAAPIEncodePicture
*pic
,
630 VAAPIEncodeSlice
*slice
)
632 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
633 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
634 H264RawSPS
*sps
= &priv
->sps
;
635 H264RawPPS
*pps
= &priv
->pps
;
636 H264RawSliceHeader
*sh
= &priv
->slice
.header
;
637 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
638 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
641 if (pic
->type
== PICTURE_TYPE_IDR
) {
642 sh
->nal_unit_header
.nal_unit_type
= H264_NAL_IDR_SLICE
;
643 sh
->nal_unit_header
.nal_ref_idc
= 3;
645 sh
->nal_unit_header
.nal_unit_type
= H264_NAL_SLICE
;
646 sh
->nal_unit_header
.nal_ref_idc
= pic
->type
!= PICTURE_TYPE_B
;
649 // Only one slice per frame.
650 sh
->first_mb_in_slice
= 0;
651 sh
->slice_type
= priv
->slice_type
;
653 sh
->pic_parameter_set_id
= pps
->pic_parameter_set_id
;
655 sh
->frame_num
= priv
->frame_num
;
656 sh
->idr_pic_id
= priv
->idr_pic_count
;
658 sh
->pic_order_cnt_lsb
= priv
->pic_order_cnt
&
659 ((1 << (4 + sps
->log2_max_pic_order_cnt_lsb_minus4
)) - 1);
661 sh
->direct_spatial_mv_pred_flag
= 1;
663 if (pic
->type
== PICTURE_TYPE_B
)
664 sh
->slice_qp_delta
= priv
->fixed_qp_b
- (pps
->pic_init_qp_minus26
+ 26);
665 else if (pic
->type
== PICTURE_TYPE_P
)
666 sh
->slice_qp_delta
= priv
->fixed_qp_p
- (pps
->pic_init_qp_minus26
+ 26);
668 sh
->slice_qp_delta
= priv
->fixed_qp_idr
- (pps
->pic_init_qp_minus26
+ 26);
671 vslice
->macroblock_address
= sh
->first_mb_in_slice
;
672 vslice
->num_macroblocks
= priv
->mb_width
* priv
->mb_height
;
674 vslice
->macroblock_info
= VA_INVALID_ID
;
676 vslice
->slice_type
= sh
->slice_type
% 5;
677 vslice
->pic_parameter_set_id
= sh
->pic_parameter_set_id
;
678 vslice
->idr_pic_id
= sh
->idr_pic_id
;
680 vslice
->pic_order_cnt_lsb
= sh
->pic_order_cnt_lsb
;
682 vslice
->direct_spatial_mv_pred_flag
= sh
->direct_spatial_mv_pred_flag
;
684 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->RefPicList0
); i
++) {
685 vslice
->RefPicList0
[i
].picture_id
= VA_INVALID_ID
;
686 vslice
->RefPicList0
[i
].flags
= VA_PICTURE_H264_INVALID
;
687 vslice
->RefPicList1
[i
].picture_id
= VA_INVALID_ID
;
688 vslice
->RefPicList1
[i
].flags
= VA_PICTURE_H264_INVALID
;
691 av_assert0(pic
->nb_refs
<= 2);
692 if (pic
->nb_refs
>= 1) {
693 // Backward reference for P- or B-frame.
694 av_assert0(pic
->type
== PICTURE_TYPE_P
||
695 pic
->type
== PICTURE_TYPE_B
);
696 vslice
->RefPicList0
[0] = vpic
->ReferenceFrames
[0];
698 if (pic
->nb_refs
>= 2) {
699 // Forward reference for B-frame.
700 av_assert0(pic
->type
== PICTURE_TYPE_B
);
701 vslice
->RefPicList1
[0] = vpic
->ReferenceFrames
[1];
704 vslice
->slice_qp_delta
= sh
->slice_qp_delta
;
709 static av_cold
int vaapi_encode_h264_configure(AVCodecContext
*avctx
)
711 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
712 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
713 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
716 err
= ff_cbs_init(&priv
->cbc
, AV_CODEC_ID_H264
, avctx
);
720 priv
->mb_width
= FFALIGN(avctx
->width
, 16) / 16;
721 priv
->mb_height
= FFALIGN(avctx
->height
, 16) / 16;
723 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
724 priv
->fixed_qp_p
= opt
->qp
;
725 if (avctx
->i_quant_factor
> 0.0)
726 priv
->fixed_qp_idr
= (int)((priv
->fixed_qp_p
* avctx
->i_quant_factor
+
727 avctx
->i_quant_offset
) + 0.5);
729 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
730 if (avctx
->b_quant_factor
> 0.0)
731 priv
->fixed_qp_b
= (int)((priv
->fixed_qp_p
* avctx
->b_quant_factor
+
732 avctx
->b_quant_offset
) + 0.5);
734 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
736 opt
->sei
&= ~SEI_TIMING
;
738 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
739 "%d / %d / %d for IDR- / P- / B-frames.\n",
740 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
742 } else if (ctx
->va_rc_mode
== VA_RC_CBR
||
743 ctx
->va_rc_mode
== VA_RC_VBR
) {
744 // These still need to be set for pic_init_qp/slice_qp_delta.
745 priv
->fixed_qp_idr
= 26;
746 priv
->fixed_qp_p
= 26;
747 priv
->fixed_qp_b
= 26;
749 av_log(avctx
, AV_LOG_DEBUG
, "Using %s-bitrate = %d bps.\n",
750 ctx
->va_rc_mode
== VA_RC_CBR ?
"constant" : "variable",
754 av_assert0(0 && "Invalid RC mode.");
757 if (avctx
->compression_level
== FF_COMPRESSION_DEFAULT
)
758 avctx
->compression_level
= opt
->quality
;
760 if (opt
->sei
& SEI_IDENTIFIER
) {
761 const char *lavc
= LIBAVCODEC_IDENT
;
762 const char *vaapi
= VA_VERSION_S
;
766 memcpy(priv
->identifier
.uuid_iso_iec_11578
,
767 vaapi_encode_h264_sei_identifier_uuid
,
768 sizeof(priv
->identifier
.uuid_iso_iec_11578
));
770 driver
= vaQueryVendorString(ctx
->hwctx
->display
);
772 driver
= "unknown driver";
774 len
= snprintf(NULL
, 0, "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
776 priv
->identifier_string
= av_malloc(len
+ 1);
777 if (!priv
->identifier_string
)
778 return AVERROR(ENOMEM
);
780 snprintf(priv
->identifier_string
, len
+ 1,
781 "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
783 priv
->identifier
.data
= priv
->identifier_string
;
784 priv
->identifier
.data_length
= len
+ 1;
791 static const VAAPIEncodeType vaapi_encode_type_h264
= {
792 .priv_data_size
= sizeof(VAAPIEncodeH264Context
),
794 .configure
= &vaapi_encode_h264_configure
,
796 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferH264
),
797 .init_sequence_params
= &vaapi_encode_h264_init_sequence_params
,
799 .picture_params_size
= sizeof(VAEncPictureParameterBufferH264
),
800 .init_picture_params
= &vaapi_encode_h264_init_picture_params
,
802 .slice_params_size
= sizeof(VAEncSliceParameterBufferH264
),
803 .init_slice_params
= &vaapi_encode_h264_init_slice_params
,
805 .sequence_header_type
= VAEncPackedHeaderSequence
,
806 .write_sequence_header
= &vaapi_encode_h264_write_sequence_header
,
808 .slice_header_type
= VAEncPackedHeaderH264_Slice
,
809 .write_slice_header
= &vaapi_encode_h264_write_slice_header
,
811 .write_extra_header
= &vaapi_encode_h264_write_extra_header
,
814 static av_cold
int vaapi_encode_h264_init(AVCodecContext
*avctx
)
816 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
817 VAAPIEncodeH264Options
*opt
=
818 (VAAPIEncodeH264Options
*)ctx
->codec_options_data
;
820 ctx
->codec
= &vaapi_encode_type_h264
;
822 switch (avctx
->profile
) {
823 case FF_PROFILE_H264_CONSTRAINED_BASELINE
:
824 ctx
->va_profile
= VAProfileH264ConstrainedBaseline
;
826 case FF_PROFILE_H264_BASELINE
:
827 ctx
->va_profile
= VAProfileH264Baseline
;
829 case FF_PROFILE_H264_MAIN
:
830 ctx
->va_profile
= VAProfileH264Main
;
832 case FF_PROFILE_H264_EXTENDED
:
833 av_log(avctx
, AV_LOG_ERROR
, "H.264 extended profile "
834 "is not supported.\n");
835 return AVERROR_PATCHWELCOME
;
836 case FF_PROFILE_UNKNOWN
:
837 case FF_PROFILE_H264_HIGH
:
838 ctx
->va_profile
= VAProfileH264High
;
840 case FF_PROFILE_H264_HIGH_10
:
841 case FF_PROFILE_H264_HIGH_10_INTRA
:
842 av_log(avctx
, AV_LOG_ERROR
, "H.264 10-bit profiles "
843 "are not supported.\n");
844 return AVERROR_PATCHWELCOME
;
845 case FF_PROFILE_H264_HIGH_422
:
846 case FF_PROFILE_H264_HIGH_422_INTRA
:
847 case FF_PROFILE_H264_HIGH_444
:
848 case FF_PROFILE_H264_HIGH_444_PREDICTIVE
:
849 case FF_PROFILE_H264_HIGH_444_INTRA
:
850 case FF_PROFILE_H264_CAVLC_444
:
851 av_log(avctx
, AV_LOG_ERROR
, "H.264 non-4:2:0 profiles "
852 "are not supported.\n");
853 return AVERROR_PATCHWELCOME
;
855 av_log(avctx
, AV_LOG_ERROR
, "Unknown H.264 profile %d.\n",
857 return AVERROR(EINVAL
);
859 if (opt
->low_power
) {
860 #if VA_CHECK_VERSION(0, 39, 2)
861 ctx
->va_entrypoint
= VAEntrypointEncSliceLP
;
863 av_log(avctx
, AV_LOG_ERROR
, "Low-power encoding is not "
864 "supported with this VAAPI version.\n");
865 return AVERROR(EINVAL
);
868 ctx
->va_entrypoint
= VAEntrypointEncSlice
;
871 // Only 8-bit encode is supported.
872 ctx
->va_rt_format
= VA_RT_FORMAT_YUV420
;
874 if (avctx
->bit_rate
> 0) {
875 if (avctx
->rc_max_rate
== avctx
->bit_rate
)
876 ctx
->va_rc_mode
= VA_RC_CBR
;
878 ctx
->va_rc_mode
= VA_RC_VBR
;
880 ctx
->va_rc_mode
= VA_RC_CQP
;
882 ctx
->va_packed_headers
=
883 VA_ENC_PACKED_HEADER_SEQUENCE
| // SPS and PPS.
884 VA_ENC_PACKED_HEADER_SLICE
| // Slice headers.
885 VA_ENC_PACKED_HEADER_MISC
; // SEI.
887 ctx
->surface_width
= FFALIGN(avctx
->width
, 16);
888 ctx
->surface_height
= FFALIGN(avctx
->height
, 16);
890 return ff_vaapi_encode_init(avctx
);
893 static av_cold
int vaapi_encode_h264_close(AVCodecContext
*avctx
)
895 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
896 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
899 ff_cbs_close(&priv
->cbc
);
900 av_freep(&priv
->identifier_string
);
903 return ff_vaapi_encode_close(avctx
);
906 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
907 offsetof(VAAPIEncodeH264Options, x))
908 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
909 static const AVOption vaapi_encode_h264_options
[] = {
910 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
911 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 20 }, 0, 52, FLAGS
},
912 { "quality", "Set encode quality (trades off against speed, higher is faster)",
913 OFFSET(quality
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 8, FLAGS
},
914 { "low_power", "Use low-power encoding mode (experimental: only supported "
915 "on some platforms, does not support all features)",
916 OFFSET(low_power
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, FLAGS
},
918 { "sei", "Set SEI to include",
919 OFFSET(sei
), AV_OPT_TYPE_FLAGS
,
920 { .i64
= SEI_IDENTIFIER
| SEI_TIMING
},
921 0, INT_MAX
, FLAGS
, "sei" },
922 { "identifier", "Include encoder version identifier",
923 0, AV_OPT_TYPE_CONST
, { .i64
= SEI_IDENTIFIER
},
924 INT_MIN
, INT_MAX
, FLAGS
, "sei" },
925 { "timing", "Include timing parameters (buffering_period and pic_timing)",
926 0, AV_OPT_TYPE_CONST
, { .i64
= SEI_TIMING
},
927 INT_MIN
, INT_MAX
, FLAGS
, "sei" },
931 static const AVCodecDefault vaapi_encode_h264_defaults
[] = {
932 { "profile", "100" },
937 { "i_qfactor", "1.0" },
938 { "i_qoffset", "0.0" },
939 { "b_qfactor", "1.2" },
940 { "b_qoffset", "0.0" },
945 static const AVClass vaapi_encode_h264_class
= {
946 .class_name
= "h264_vaapi",
947 .item_name
= av_default_item_name
,
948 .option
= vaapi_encode_h264_options
,
949 .version
= LIBAVUTIL_VERSION_INT
,
952 AVCodec ff_h264_vaapi_encoder
= {
953 .name
= "h264_vaapi",
954 .long_name
= NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
955 .type
= AVMEDIA_TYPE_VIDEO
,
956 .id
= AV_CODEC_ID_H264
,
957 .priv_data_size
= (sizeof(VAAPIEncodeContext
) +
958 sizeof(VAAPIEncodeH264Options
)),
959 .init
= &vaapi_encode_h264_init
,
960 .encode2
= &ff_vaapi_encode2
,
961 .close
= &vaapi_encode_h264_close
,
962 .priv_class
= &vaapi_encode_h264_class
,
963 .capabilities
= AV_CODEC_CAP_DELAY
,
964 .defaults
= vaapi_encode_h264_defaults
,
965 .pix_fmts
= (const enum AVPixelFormat
[]) {