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
{
62 H264RawSEIBufferingPeriod buffering_period
;
63 H264RawSEIPicTiming pic_timing
;
64 H264RawSEIUserDataUnregistered identifier
;
65 char *identifier_string
;
70 int64_t last_idr_frame
;
71 int64_t idr_pic_count
;
79 CodedBitstreamContext cbc
;
80 CodedBitstreamFragment current_access_unit
;
83 } VAAPIEncodeH264Context
;
85 typedef struct VAAPIEncodeH264Options
{
91 } VAAPIEncodeH264Options
;
94 static int vaapi_encode_h264_write_access_unit(AVCodecContext
*avctx
,
95 char *data
, size_t *data_len
,
96 CodedBitstreamFragment
*au
)
98 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
99 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
102 err
= ff_cbs_write_fragment_data(&priv
->cbc
, au
);
104 av_log(avctx
, AV_LOG_ERROR
, "Failed to write packed header.\n");
108 if (*data_len
< 8 * au
->data_size
- au
->data_bit_padding
) {
109 av_log(avctx
, AV_LOG_ERROR
, "Access unit too large: "
110 "%zu < %zu.\n", *data_len
,
111 8 * au
->data_size
- au
->data_bit_padding
);
112 return AVERROR(ENOSPC
);
115 memcpy(data
, au
->data
, au
->data_size
);
116 *data_len
= 8 * au
->data_size
- au
->data_bit_padding
;
121 static int vaapi_encode_h264_add_nal(AVCodecContext
*avctx
,
122 CodedBitstreamFragment
*au
,
125 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
126 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
127 H264RawNALUnitHeader
*header
= nal_unit
;
130 err
= ff_cbs_insert_unit_content(&priv
->cbc
, au
, -1,
131 header
->nal_unit_type
, nal_unit
);
133 av_log(avctx
, AV_LOG_ERROR
, "Failed to add NAL unit: "
134 "type = %d.\n", header
->nal_unit_type
);
141 static int vaapi_encode_h264_write_sequence_header(AVCodecContext
*avctx
,
142 char *data
, size_t *data_len
)
144 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
145 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
146 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
149 if (priv
->aud_needed
) {
150 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->aud
);
153 priv
->aud_needed
= 0;
156 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->sps
);
160 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->pps
);
164 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
166 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
170 static int vaapi_encode_h264_write_slice_header(AVCodecContext
*avctx
,
171 VAAPIEncodePicture
*pic
,
172 VAAPIEncodeSlice
*slice
,
173 char *data
, size_t *data_len
)
175 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
176 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
177 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
180 if (priv
->aud_needed
) {
181 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->aud
);
184 priv
->aud_needed
= 0;
187 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->slice
);
191 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
193 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
197 static int vaapi_encode_h264_write_extra_header(AVCodecContext
*avctx
,
198 VAAPIEncodePicture
*pic
,
199 int index
, int *type
,
200 char *data
, size_t *data_len
)
202 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
203 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
204 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
205 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
208 if (priv
->sei_needed
) {
209 if (priv
->aud_needed
) {
210 vaapi_encode_h264_add_nal(avctx
, au
, &priv
->aud
);
211 priv
->aud_needed
= 0;
214 memset(&priv
->sei
, 0, sizeof(priv
->sei
));
215 priv
->sei
.nal_unit_header
.nal_unit_type
= H264_NAL_SEI
;
218 if (pic
->encode_order
== 0 && opt
->sei
& SEI_IDENTIFIER
) {
219 priv
->sei
.payload
[i
].payload_type
= H264_SEI_TYPE_USER_DATA_UNREGISTERED
;
220 priv
->sei
.payload
[i
].payload
.user_data_unregistered
= priv
->identifier
;
223 if (opt
->sei
& SEI_TIMING
) {
224 if (pic
->type
== PICTURE_TYPE_IDR
) {
225 priv
->sei
.payload
[i
].payload_type
= H264_SEI_TYPE_BUFFERING_PERIOD
;
226 priv
->sei
.payload
[i
].payload
.buffering_period
= priv
->buffering_period
;
229 priv
->sei
.payload
[i
].payload_type
= H264_SEI_TYPE_PIC_TIMING
;
230 priv
->sei
.payload
[i
].payload
.pic_timing
= priv
->pic_timing
;
234 priv
->sei
.payload_count
= i
;
235 av_assert0(priv
->sei
.payload_count
> 0);
237 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->sei
);
240 priv
->sei_needed
= 0;
242 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
246 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
248 *type
= VAEncPackedHeaderH264_SEI
;
255 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
259 static int vaapi_encode_h264_init_sequence_params(AVCodecContext
*avctx
)
261 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
262 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
263 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
264 H264RawSPS
*sps
= &priv
->sps
;
265 H264RawPPS
*pps
= &priv
->pps
;
266 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
267 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
269 memset(&priv
->current_access_unit
, 0,
270 sizeof(priv
->current_access_unit
));
272 memset(sps
, 0, sizeof(*sps
));
273 memset(pps
, 0, sizeof(*pps
));
275 sps
->nal_unit_header
.nal_ref_idc
= 3;
276 sps
->nal_unit_header
.nal_unit_type
= H264_NAL_SPS
;
278 sps
->profile_idc
= avctx
->profile
& 0xff;
279 sps
->constraint_set1_flag
=
280 !!(avctx
->profile
& FF_PROFILE_H264_CONSTRAINED
);
281 sps
->constraint_set3_flag
=
282 !!(avctx
->profile
& FF_PROFILE_H264_INTRA
);
284 sps
->level_idc
= avctx
->level
;
286 sps
->seq_parameter_set_id
= 0;
287 sps
->chroma_format_idc
= 1;
289 sps
->log2_max_frame_num_minus4
= 4;
290 sps
->pic_order_cnt_type
= 0;
291 sps
->log2_max_pic_order_cnt_lsb_minus4
=
292 av_clip(av_log2(ctx
->b_per_p
+ 1) - 2, 0, 12);
294 sps
->max_num_ref_frames
=
295 (avctx
->profile
& FF_PROFILE_H264_INTRA
) ?
0 :
296 1 + (ctx
->b_per_p
> 0);
298 sps
->pic_width_in_mbs_minus1
= priv
->mb_width
- 1;
299 sps
->pic_height_in_map_units_minus1
= priv
->mb_height
- 1;
301 sps
->frame_mbs_only_flag
= 1;
302 sps
->direct_8x8_inference_flag
= 1;
304 if (avctx
->width
!= 16 * priv
->mb_width
||
305 avctx
->height
!= 16 * priv
->mb_height
) {
306 sps
->frame_cropping_flag
= 1;
308 sps
->frame_crop_left_offset
= 0;
309 sps
->frame_crop_right_offset
=
310 (16 * priv
->mb_width
- avctx
->width
) / 2;
311 sps
->frame_crop_top_offset
= 0;
312 sps
->frame_crop_bottom_offset
=
313 (16 * priv
->mb_height
- avctx
->height
) / 2;
315 sps
->frame_cropping_flag
= 0;
318 sps
->vui_parameters_present_flag
= 1;
320 if (avctx
->sample_aspect_ratio
.num
!= 0 &&
321 avctx
->sample_aspect_ratio
.den
!= 0) {
322 static const AVRational sar_idc
[] = {
324 { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
325 { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
326 { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
327 { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
330 for (i
= 0; i
< FF_ARRAY_ELEMS(sar_idc
); i
++) {
331 if (avctx
->sample_aspect_ratio
.num
== sar_idc
[i
].num
&&
332 avctx
->sample_aspect_ratio
.den
== sar_idc
[i
].den
) {
333 sps
->vui
.aspect_ratio_idc
= i
;
337 if (i
>= FF_ARRAY_ELEMS(sar_idc
)) {
338 sps
->vui
.aspect_ratio_idc
= 255;
339 sps
->vui
.sar_width
= avctx
->sample_aspect_ratio
.num
;
340 sps
->vui
.sar_height
= avctx
->sample_aspect_ratio
.den
;
342 sps
->vui
.aspect_ratio_info_present_flag
= 1;
345 if (avctx
->color_range
!= AVCOL_RANGE_UNSPECIFIED
||
346 avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
347 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
348 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
349 sps
->vui
.video_signal_type_present_flag
= 1;
350 sps
->vui
.video_format
= 5; // Unspecified.
351 sps
->vui
.video_full_range_flag
=
352 avctx
->color_range
== AVCOL_RANGE_JPEG
;
354 if (avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
355 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
356 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
357 sps
->vui
.colour_description_present_flag
= 1;
358 sps
->vui
.colour_primaries
= avctx
->color_primaries
;
359 sps
->vui
.transfer_characteristics
= avctx
->color_trc
;
360 sps
->vui
.matrix_coefficients
= avctx
->colorspace
;
363 sps
->vui
.video_format
= 5;
364 sps
->vui
.video_full_range_flag
= 0;
365 sps
->vui
.colour_primaries
= avctx
->color_primaries
;
366 sps
->vui
.transfer_characteristics
= avctx
->color_trc
;
367 sps
->vui
.matrix_coefficients
= avctx
->colorspace
;
370 if (avctx
->chroma_sample_location
!= AVCHROMA_LOC_UNSPECIFIED
) {
371 sps
->vui
.chroma_loc_info_present_flag
= 1;
372 sps
->vui
.chroma_sample_loc_type_top_field
=
373 sps
->vui
.chroma_sample_loc_type_bottom_field
=
374 avctx
->chroma_sample_location
- 1;
377 sps
->vui
.timing_info_present_flag
= 1;
378 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
379 sps
->vui
.num_units_in_tick
= avctx
->framerate
.den
;
380 sps
->vui
.time_scale
= 2 * avctx
->framerate
.num
;
381 sps
->vui
.fixed_frame_rate_flag
= 1;
383 sps
->vui
.num_units_in_tick
= avctx
->time_base
.num
;
384 sps
->vui
.time_scale
= 2 * avctx
->time_base
.den
;
385 sps
->vui
.fixed_frame_rate_flag
= 0;
388 if (opt
->sei
& SEI_TIMING
) {
389 H264RawHRD
*hrd
= &sps
->vui
.nal_hrd_parameters
;
391 sps
->vui
.nal_hrd_parameters_present_flag
= 1;
393 hrd
->cpb_cnt_minus1
= 0;
395 // Try to scale these to a sensible range so that the
396 // golomb encode of the value is not overlong.
397 hrd
->bit_rate_scale
=
398 av_clip_uintp2(av_log2(avctx
->bit_rate
) - 15 - 6, 4);
399 hrd
->bit_rate_value_minus1
[0] =
400 (avctx
->bit_rate
>> hrd
->bit_rate_scale
+ 6) - 1;
402 hrd
->cpb_size_scale
=
403 av_clip_uintp2(av_log2(ctx
->hrd_params
.hrd
.buffer_size
) - 15 - 4, 4);
404 hrd
->cpb_size_value_minus1
[0] =
405 (ctx
->hrd_params
.hrd
.buffer_size
>> hrd
->cpb_size_scale
+ 4) - 1;
407 // CBR mode as defined for the HRD cannot be achieved without filler
408 // data, so this flag cannot be set even with VAAPI CBR modes.
409 hrd
->cbr_flag
[0] = 0;
411 hrd
->initial_cpb_removal_delay_length_minus1
= 23;
412 hrd
->cpb_removal_delay_length_minus1
= 23;
413 hrd
->dpb_output_delay_length_minus1
= 7;
414 hrd
->time_offset_length
= 0;
416 priv
->buffering_period
.seq_parameter_set_id
= sps
->seq_parameter_set_id
;
418 // This calculation can easily overflow 32 bits.
419 priv
->buffering_period
.nal
.initial_cpb_removal_delay
[0] = 90000 *
420 (uint64_t)ctx
->hrd_params
.hrd
.initial_buffer_fullness
/
421 ctx
->hrd_params
.hrd
.buffer_size
;
422 priv
->buffering_period
.nal
.initial_cpb_removal_delay_offset
[0] = 0;
424 sps
->vui
.nal_hrd_parameters_present_flag
= 0;
425 sps
->vui
.low_delay_hrd_flag
= 1 - sps
->vui
.fixed_frame_rate_flag
;
428 sps
->vui
.bitstream_restriction_flag
= 1;
429 sps
->vui
.motion_vectors_over_pic_boundaries_flag
= 1;
430 sps
->vui
.log2_max_mv_length_horizontal
= 16;
431 sps
->vui
.log2_max_mv_length_vertical
= 16;
432 sps
->vui
.max_num_reorder_frames
= (ctx
->b_per_p
> 0);
433 sps
->vui
.max_dec_frame_buffering
= vseq
->max_num_ref_frames
;
435 pps
->nal_unit_header
.nal_ref_idc
= 3;
436 pps
->nal_unit_header
.nal_unit_type
= H264_NAL_PPS
;
438 pps
->pic_parameter_set_id
= 0;
439 pps
->seq_parameter_set_id
= 0;
441 pps
->entropy_coding_mode_flag
=
442 !(sps
->profile_idc
== FF_PROFILE_H264_BASELINE
||
443 sps
->profile_idc
== FF_PROFILE_H264_EXTENDED
||
444 sps
->profile_idc
== FF_PROFILE_H264_CAVLC_444
);
446 pps
->num_ref_idx_l0_default_active_minus1
= 0;
447 pps
->num_ref_idx_l1_default_active_minus1
= 0;
449 pps
->pic_init_qp_minus26
= priv
->fixed_qp_idr
- 26;
451 if (sps
->profile_idc
== FF_PROFILE_H264_BASELINE
||
452 sps
->profile_idc
== FF_PROFILE_H264_EXTENDED
||
453 sps
->profile_idc
== FF_PROFILE_H264_MAIN
) {
454 pps
->more_rbsp_data
= 0;
456 pps
->more_rbsp_data
= 1;
458 pps
->transform_8x8_mode_flag
= 1;
461 *vseq
= (VAEncSequenceParameterBufferH264
) {
462 .seq_parameter_set_id
= sps
->seq_parameter_set_id
,
463 .level_idc
= sps
->level_idc
,
464 .intra_period
= avctx
->gop_size
,
465 .intra_idr_period
= avctx
->gop_size
,
466 .ip_period
= ctx
->b_per_p
+ 1,
468 .bits_per_second
= avctx
->bit_rate
,
469 .max_num_ref_frames
= sps
->max_num_ref_frames
,
470 .picture_width_in_mbs
= sps
->pic_width_in_mbs_minus1
+ 1,
471 .picture_height_in_mbs
= sps
->pic_height_in_map_units_minus1
+ 1,
474 .chroma_format_idc
= sps
->chroma_format_idc
,
475 .frame_mbs_only_flag
= sps
->frame_mbs_only_flag
,
476 .mb_adaptive_frame_field_flag
= sps
->mb_adaptive_frame_field_flag
,
477 .seq_scaling_matrix_present_flag
= sps
->seq_scaling_matrix_present_flag
,
478 .direct_8x8_inference_flag
= sps
->direct_8x8_inference_flag
,
479 .log2_max_frame_num_minus4
= sps
->log2_max_frame_num_minus4
,
480 .pic_order_cnt_type
= sps
->pic_order_cnt_type
,
481 .log2_max_pic_order_cnt_lsb_minus4
= sps
->log2_max_pic_order_cnt_lsb_minus4
,
482 .delta_pic_order_always_zero_flag
= sps
->delta_pic_order_always_zero_flag
,
485 .bit_depth_luma_minus8
= sps
->bit_depth_luma_minus8
,
486 .bit_depth_chroma_minus8
= sps
->bit_depth_chroma_minus8
,
488 .frame_cropping_flag
= sps
->frame_cropping_flag
,
489 .frame_crop_left_offset
= sps
->frame_crop_left_offset
,
490 .frame_crop_right_offset
= sps
->frame_crop_right_offset
,
491 .frame_crop_top_offset
= sps
->frame_crop_top_offset
,
492 .frame_crop_bottom_offset
= sps
->frame_crop_bottom_offset
,
494 .vui_parameters_present_flag
= sps
->vui_parameters_present_flag
,
497 .aspect_ratio_info_present_flag
= sps
->vui
.aspect_ratio_info_present_flag
,
498 .timing_info_present_flag
= sps
->vui
.timing_info_present_flag
,
499 .bitstream_restriction_flag
= sps
->vui
.bitstream_restriction_flag
,
500 .log2_max_mv_length_horizontal
= sps
->vui
.log2_max_mv_length_horizontal
,
501 .log2_max_mv_length_vertical
= sps
->vui
.log2_max_mv_length_vertical
,
504 .aspect_ratio_idc
= sps
->vui
.aspect_ratio_idc
,
505 .sar_width
= sps
->vui
.sar_width
,
506 .sar_height
= sps
->vui
.sar_height
,
507 .num_units_in_tick
= sps
->vui
.num_units_in_tick
,
508 .time_scale
= sps
->vui
.time_scale
,
511 *vpic
= (VAEncPictureParameterBufferH264
) {
513 .picture_id
= VA_INVALID_ID
,
514 .flags
= VA_PICTURE_H264_INVALID
,
517 .coded_buf
= VA_INVALID_ID
,
519 .pic_parameter_set_id
= pps
->pic_parameter_set_id
,
520 .seq_parameter_set_id
= pps
->seq_parameter_set_id
,
522 .pic_init_qp
= pps
->pic_init_qp_minus26
+ 26,
523 .num_ref_idx_l0_active_minus1
= pps
->num_ref_idx_l0_default_active_minus1
,
524 .num_ref_idx_l1_active_minus1
= pps
->num_ref_idx_l1_default_active_minus1
,
526 .chroma_qp_index_offset
= pps
->chroma_qp_index_offset
,
527 .second_chroma_qp_index_offset
= pps
->second_chroma_qp_index_offset
,
530 .entropy_coding_mode_flag
= pps
->entropy_coding_mode_flag
,
531 .weighted_pred_flag
= pps
->weighted_pred_flag
,
532 .weighted_bipred_idc
= pps
->weighted_bipred_idc
,
533 .constrained_intra_pred_flag
= pps
->constrained_intra_pred_flag
,
534 .transform_8x8_mode_flag
= pps
->transform_8x8_mode_flag
,
535 .deblocking_filter_control_present_flag
=
536 pps
->deblocking_filter_control_present_flag
,
537 .redundant_pic_cnt_present_flag
= pps
->redundant_pic_cnt_present_flag
,
538 .pic_order_present_flag
=
539 pps
->bottom_field_pic_order_in_frame_present_flag
,
540 .pic_scaling_matrix_present_flag
= pps
->pic_scaling_matrix_present_flag
,
547 static int vaapi_encode_h264_init_picture_params(AVCodecContext
*avctx
,
548 VAAPIEncodePicture
*pic
)
550 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
551 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
552 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
553 H264RawSPS
*sps
= &priv
->sps
;
554 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
557 memset(&priv
->current_access_unit
, 0,
558 sizeof(priv
->current_access_unit
));
560 if (pic
->type
== PICTURE_TYPE_IDR
) {
561 av_assert0(pic
->display_order
== pic
->encode_order
);
563 priv
->next_frame_num
= 1;
565 priv
->last_idr_frame
= pic
->display_order
;
566 ++priv
->idr_pic_count
;
568 priv
->slice_type
= 7;
569 priv
->primary_pic_type
= 0;
571 priv
->frame_num
= priv
->next_frame_num
;
573 if (pic
->type
!= PICTURE_TYPE_B
) {
574 // Reference picture, so frame_num advances.
575 priv
->next_frame_num
= (priv
->frame_num
+ 1) &
576 ((1 << (4 + sps
->log2_max_frame_num_minus4
)) - 1);
580 if (pic
->type
== PICTURE_TYPE_I
) {
581 priv
->slice_type
= 7;
582 priv
->primary_pic_type
= 0;
583 } else if (pic
->type
== PICTURE_TYPE_P
) {
584 priv
->slice_type
= 5;
585 priv
->primary_pic_type
= 1;
587 priv
->slice_type
= 6;
588 priv
->primary_pic_type
= 2;
591 priv
->pic_order_cnt
= pic
->display_order
- priv
->last_idr_frame
;
592 priv
->dpb_delay
= pic
->display_order
- pic
->encode_order
+ 1;
595 priv
->aud_needed
= 1;
596 priv
->aud
.nal_unit_header
.nal_unit_type
= H264_NAL_AUD
;
597 priv
->aud
.primary_pic_type
= priv
->primary_pic_type
;
599 priv
->aud_needed
= 0;
602 if (opt
->sei
& SEI_IDENTIFIER
&& pic
->encode_order
== 0)
603 priv
->sei_needed
= 1;
605 if (opt
->sei
& SEI_TIMING
) {
606 memset(&priv
->pic_timing
, 0, sizeof(priv
->pic_timing
));
608 priv
->pic_timing
.cpb_removal_delay
=
609 2 * sps
->vui
.num_units_in_tick
* priv
->cpb_delay
;
610 priv
->pic_timing
.dpb_output_delay
=
611 2 * sps
->vui
.num_units_in_tick
* priv
->dpb_delay
;
613 priv
->sei_needed
= 1;
616 vpic
->CurrPic
= (VAPictureH264
) {
617 .picture_id
= pic
->recon_surface
,
618 .frame_idx
= priv
->frame_num
,
620 .TopFieldOrderCnt
= priv
->pic_order_cnt
,
621 .BottomFieldOrderCnt
= priv
->pic_order_cnt
,
624 for (i
= 0; i
< pic
->nb_refs
; i
++) {
625 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
626 unsigned int frame_num
= (ref
->encode_order
- priv
->last_idr_frame
) &
627 ((1 << (4 + sps
->log2_max_frame_num_minus4
)) - 1);
628 unsigned int pic_order_cnt
= ref
->display_order
- priv
->last_idr_frame
;
630 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
631 vpic
->ReferenceFrames
[i
] = (VAPictureH264
) {
632 .picture_id
= ref
->recon_surface
,
633 .frame_idx
= frame_num
,
634 .flags
= VA_PICTURE_H264_SHORT_TERM_REFERENCE
,
635 .TopFieldOrderCnt
= pic_order_cnt
,
636 .BottomFieldOrderCnt
= pic_order_cnt
,
639 for (; i
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); i
++) {
640 vpic
->ReferenceFrames
[i
] = (VAPictureH264
) {
641 .picture_id
= VA_INVALID_ID
,
642 .flags
= VA_PICTURE_H264_INVALID
,
646 vpic
->coded_buf
= pic
->output_buffer
;
648 vpic
->frame_num
= priv
->frame_num
;
650 vpic
->pic_fields
.bits
.idr_pic_flag
= (pic
->type
== PICTURE_TYPE_IDR
);
651 vpic
->pic_fields
.bits
.reference_pic_flag
= (pic
->type
!= PICTURE_TYPE_B
);
658 static int vaapi_encode_h264_init_slice_params(AVCodecContext
*avctx
,
659 VAAPIEncodePicture
*pic
,
660 VAAPIEncodeSlice
*slice
)
662 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
663 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
664 H264RawSPS
*sps
= &priv
->sps
;
665 H264RawPPS
*pps
= &priv
->pps
;
666 H264RawSliceHeader
*sh
= &priv
->slice
.header
;
667 VAEncPictureParameterBufferH264
*vpic
= pic
->codec_picture_params
;
668 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
671 if (pic
->type
== PICTURE_TYPE_IDR
) {
672 sh
->nal_unit_header
.nal_unit_type
= H264_NAL_IDR_SLICE
;
673 sh
->nal_unit_header
.nal_ref_idc
= 3;
675 sh
->nal_unit_header
.nal_unit_type
= H264_NAL_SLICE
;
676 sh
->nal_unit_header
.nal_ref_idc
= pic
->type
!= PICTURE_TYPE_B
;
679 // Only one slice per frame.
680 sh
->first_mb_in_slice
= 0;
681 sh
->slice_type
= priv
->slice_type
;
683 sh
->pic_parameter_set_id
= pps
->pic_parameter_set_id
;
685 sh
->frame_num
= priv
->frame_num
;
686 sh
->idr_pic_id
= priv
->idr_pic_count
;
688 sh
->pic_order_cnt_lsb
= priv
->pic_order_cnt
&
689 ((1 << (4 + sps
->log2_max_pic_order_cnt_lsb_minus4
)) - 1);
691 sh
->direct_spatial_mv_pred_flag
= 1;
693 if (pic
->type
== PICTURE_TYPE_B
)
694 sh
->slice_qp_delta
= priv
->fixed_qp_b
- (pps
->pic_init_qp_minus26
+ 26);
695 else if (pic
->type
== PICTURE_TYPE_P
)
696 sh
->slice_qp_delta
= priv
->fixed_qp_p
- (pps
->pic_init_qp_minus26
+ 26);
698 sh
->slice_qp_delta
= priv
->fixed_qp_idr
- (pps
->pic_init_qp_minus26
+ 26);
701 vslice
->macroblock_address
= sh
->first_mb_in_slice
;
702 vslice
->num_macroblocks
= priv
->mb_width
* priv
->mb_height
;
704 vslice
->macroblock_info
= VA_INVALID_ID
;
706 vslice
->slice_type
= sh
->slice_type
% 5;
707 vslice
->pic_parameter_set_id
= sh
->pic_parameter_set_id
;
708 vslice
->idr_pic_id
= sh
->idr_pic_id
;
710 vslice
->pic_order_cnt_lsb
= sh
->pic_order_cnt_lsb
;
712 vslice
->direct_spatial_mv_pred_flag
= sh
->direct_spatial_mv_pred_flag
;
714 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->RefPicList0
); i
++) {
715 vslice
->RefPicList0
[i
].picture_id
= VA_INVALID_ID
;
716 vslice
->RefPicList0
[i
].flags
= VA_PICTURE_H264_INVALID
;
717 vslice
->RefPicList1
[i
].picture_id
= VA_INVALID_ID
;
718 vslice
->RefPicList1
[i
].flags
= VA_PICTURE_H264_INVALID
;
721 av_assert0(pic
->nb_refs
<= 2);
722 if (pic
->nb_refs
>= 1) {
723 // Backward reference for P- or B-frame.
724 av_assert0(pic
->type
== PICTURE_TYPE_P
||
725 pic
->type
== PICTURE_TYPE_B
);
726 vslice
->RefPicList0
[0] = vpic
->ReferenceFrames
[0];
728 if (pic
->nb_refs
>= 2) {
729 // Forward reference for B-frame.
730 av_assert0(pic
->type
== PICTURE_TYPE_B
);
731 vslice
->RefPicList1
[0] = vpic
->ReferenceFrames
[1];
734 vslice
->slice_qp_delta
= sh
->slice_qp_delta
;
739 static av_cold
int vaapi_encode_h264_configure(AVCodecContext
*avctx
)
741 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
742 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
743 VAAPIEncodeH264Options
*opt
= ctx
->codec_options
;
746 err
= ff_cbs_init(&priv
->cbc
, AV_CODEC_ID_H264
, avctx
);
750 priv
->mb_width
= FFALIGN(avctx
->width
, 16) / 16;
751 priv
->mb_height
= FFALIGN(avctx
->height
, 16) / 16;
753 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
754 priv
->fixed_qp_p
= opt
->qp
;
755 if (avctx
->i_quant_factor
> 0.0)
756 priv
->fixed_qp_idr
= (int)((priv
->fixed_qp_p
* avctx
->i_quant_factor
+
757 avctx
->i_quant_offset
) + 0.5);
759 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
760 if (avctx
->b_quant_factor
> 0.0)
761 priv
->fixed_qp_b
= (int)((priv
->fixed_qp_p
* avctx
->b_quant_factor
+
762 avctx
->b_quant_offset
) + 0.5);
764 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
766 opt
->sei
&= ~SEI_TIMING
;
768 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
769 "%d / %d / %d for IDR- / P- / B-frames.\n",
770 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
772 } else if (ctx
->va_rc_mode
== VA_RC_CBR
||
773 ctx
->va_rc_mode
== VA_RC_VBR
) {
774 // These still need to be set for pic_init_qp/slice_qp_delta.
775 priv
->fixed_qp_idr
= 26;
776 priv
->fixed_qp_p
= 26;
777 priv
->fixed_qp_b
= 26;
779 av_log(avctx
, AV_LOG_DEBUG
, "Using %s-bitrate = %d bps.\n",
780 ctx
->va_rc_mode
== VA_RC_CBR ?
"constant" : "variable",
784 av_assert0(0 && "Invalid RC mode.");
787 if (avctx
->compression_level
== FF_COMPRESSION_DEFAULT
)
788 avctx
->compression_level
= opt
->quality
;
790 if (opt
->sei
& SEI_IDENTIFIER
) {
791 const char *lavc
= LIBAVCODEC_IDENT
;
792 const char *vaapi
= VA_VERSION_S
;
796 memcpy(priv
->identifier
.uuid_iso_iec_11578
,
797 vaapi_encode_h264_sei_identifier_uuid
,
798 sizeof(priv
->identifier
.uuid_iso_iec_11578
));
800 driver
= vaQueryVendorString(ctx
->hwctx
->display
);
802 driver
= "unknown driver";
804 len
= snprintf(NULL
, 0, "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
806 priv
->identifier_string
= av_malloc(len
+ 1);
807 if (!priv
->identifier_string
)
808 return AVERROR(ENOMEM
);
810 snprintf(priv
->identifier_string
, len
+ 1,
811 "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
813 priv
->identifier
.data
= priv
->identifier_string
;
814 priv
->identifier
.data_length
= len
+ 1;
821 static const VAAPIEncodeType vaapi_encode_type_h264
= {
822 .priv_data_size
= sizeof(VAAPIEncodeH264Context
),
824 .configure
= &vaapi_encode_h264_configure
,
826 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferH264
),
827 .init_sequence_params
= &vaapi_encode_h264_init_sequence_params
,
829 .picture_params_size
= sizeof(VAEncPictureParameterBufferH264
),
830 .init_picture_params
= &vaapi_encode_h264_init_picture_params
,
832 .slice_params_size
= sizeof(VAEncSliceParameterBufferH264
),
833 .init_slice_params
= &vaapi_encode_h264_init_slice_params
,
835 .sequence_header_type
= VAEncPackedHeaderSequence
,
836 .write_sequence_header
= &vaapi_encode_h264_write_sequence_header
,
838 .slice_header_type
= VAEncPackedHeaderH264_Slice
,
839 .write_slice_header
= &vaapi_encode_h264_write_slice_header
,
841 .write_extra_header
= &vaapi_encode_h264_write_extra_header
,
844 static av_cold
int vaapi_encode_h264_init(AVCodecContext
*avctx
)
846 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
847 VAAPIEncodeH264Options
*opt
=
848 (VAAPIEncodeH264Options
*)ctx
->codec_options_data
;
850 ctx
->codec
= &vaapi_encode_type_h264
;
852 switch (avctx
->profile
) {
853 case FF_PROFILE_H264_CONSTRAINED_BASELINE
:
854 ctx
->va_profile
= VAProfileH264ConstrainedBaseline
;
856 case FF_PROFILE_H264_BASELINE
:
857 ctx
->va_profile
= VAProfileH264Baseline
;
859 case FF_PROFILE_H264_MAIN
:
860 ctx
->va_profile
= VAProfileH264Main
;
862 case FF_PROFILE_H264_EXTENDED
:
863 av_log(avctx
, AV_LOG_ERROR
, "H.264 extended profile "
864 "is not supported.\n");
865 return AVERROR_PATCHWELCOME
;
866 case FF_PROFILE_UNKNOWN
:
867 case FF_PROFILE_H264_HIGH
:
868 ctx
->va_profile
= VAProfileH264High
;
870 case FF_PROFILE_H264_HIGH_10
:
871 case FF_PROFILE_H264_HIGH_10_INTRA
:
872 av_log(avctx
, AV_LOG_ERROR
, "H.264 10-bit profiles "
873 "are not supported.\n");
874 return AVERROR_PATCHWELCOME
;
875 case FF_PROFILE_H264_HIGH_422
:
876 case FF_PROFILE_H264_HIGH_422_INTRA
:
877 case FF_PROFILE_H264_HIGH_444
:
878 case FF_PROFILE_H264_HIGH_444_PREDICTIVE
:
879 case FF_PROFILE_H264_HIGH_444_INTRA
:
880 case FF_PROFILE_H264_CAVLC_444
:
881 av_log(avctx
, AV_LOG_ERROR
, "H.264 non-4:2:0 profiles "
882 "are not supported.\n");
883 return AVERROR_PATCHWELCOME
;
885 av_log(avctx
, AV_LOG_ERROR
, "Unknown H.264 profile %d.\n",
887 return AVERROR(EINVAL
);
889 if (opt
->low_power
) {
890 #if VA_CHECK_VERSION(0, 39, 2)
891 ctx
->va_entrypoint
= VAEntrypointEncSliceLP
;
893 av_log(avctx
, AV_LOG_ERROR
, "Low-power encoding is not "
894 "supported with this VAAPI version.\n");
895 return AVERROR(EINVAL
);
898 ctx
->va_entrypoint
= VAEntrypointEncSlice
;
901 // Only 8-bit encode is supported.
902 ctx
->va_rt_format
= VA_RT_FORMAT_YUV420
;
904 if (avctx
->bit_rate
> 0) {
905 if (avctx
->rc_max_rate
== avctx
->bit_rate
)
906 ctx
->va_rc_mode
= VA_RC_CBR
;
908 ctx
->va_rc_mode
= VA_RC_VBR
;
910 ctx
->va_rc_mode
= VA_RC_CQP
;
912 ctx
->va_packed_headers
=
913 VA_ENC_PACKED_HEADER_SEQUENCE
| // SPS and PPS.
914 VA_ENC_PACKED_HEADER_SLICE
| // Slice headers.
915 VA_ENC_PACKED_HEADER_MISC
; // SEI.
917 ctx
->surface_width
= FFALIGN(avctx
->width
, 16);
918 ctx
->surface_height
= FFALIGN(avctx
->height
, 16);
920 return ff_vaapi_encode_init(avctx
);
923 static av_cold
int vaapi_encode_h264_close(AVCodecContext
*avctx
)
925 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
926 VAAPIEncodeH264Context
*priv
= ctx
->priv_data
;
929 ff_cbs_close(&priv
->cbc
);
930 av_freep(&priv
->identifier_string
);
933 return ff_vaapi_encode_close(avctx
);
936 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
937 offsetof(VAAPIEncodeH264Options, x))
938 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
939 static const AVOption vaapi_encode_h264_options
[] = {
940 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
941 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 20 }, 0, 52, FLAGS
},
942 { "quality", "Set encode quality (trades off against speed, higher is faster)",
943 OFFSET(quality
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 8, FLAGS
},
944 { "low_power", "Use low-power encoding mode (experimental: only supported "
945 "on some platforms, does not support all features)",
946 OFFSET(low_power
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, FLAGS
},
948 { "aud", "Include AUD",
949 OFFSET(aud
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, FLAGS
},
951 { "sei", "Set SEI to include",
952 OFFSET(sei
), AV_OPT_TYPE_FLAGS
,
953 { .i64
= SEI_IDENTIFIER
| SEI_TIMING
},
954 0, INT_MAX
, FLAGS
, "sei" },
955 { "identifier", "Include encoder version identifier",
956 0, AV_OPT_TYPE_CONST
, { .i64
= SEI_IDENTIFIER
},
957 INT_MIN
, INT_MAX
, FLAGS
, "sei" },
958 { "timing", "Include timing parameters (buffering_period and pic_timing)",
959 0, AV_OPT_TYPE_CONST
, { .i64
= SEI_TIMING
},
960 INT_MIN
, INT_MAX
, FLAGS
, "sei" },
964 static const AVCodecDefault vaapi_encode_h264_defaults
[] = {
965 { "profile", "100" },
970 { "i_qfactor", "1.0" },
971 { "i_qoffset", "0.0" },
972 { "b_qfactor", "1.2" },
973 { "b_qoffset", "0.0" },
978 static const AVClass vaapi_encode_h264_class
= {
979 .class_name
= "h264_vaapi",
980 .item_name
= av_default_item_name
,
981 .option
= vaapi_encode_h264_options
,
982 .version
= LIBAVUTIL_VERSION_INT
,
985 AVCodec ff_h264_vaapi_encoder
= {
986 .name
= "h264_vaapi",
987 .long_name
= NULL_IF_CONFIG_SMALL("H.264/AVC (VAAPI)"),
988 .type
= AVMEDIA_TYPE_VIDEO
,
989 .id
= AV_CODEC_ID_H264
,
990 .priv_data_size
= (sizeof(VAAPIEncodeContext
) +
991 sizeof(VAAPIEncodeH264Options
)),
992 .init
= &vaapi_encode_h264_init
,
993 .encode2
= &ff_vaapi_encode2
,
994 .close
= &vaapi_encode_h264_close
,
995 .priv_class
= &vaapi_encode_h264_class
,
996 .capabilities
= AV_CODEC_CAP_DELAY
,
997 .defaults
= vaapi_encode_h264_defaults
,
998 .pix_fmts
= (const enum AVPixelFormat
[]) {