2 * This file is part of FFmpeg.
4 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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/mem.h"
27 #include "libavutil/pixdesc.h"
28 #include "libavutil/opt.h"
34 #include "codec_internal.h"
36 #include "hw_base_encode_h264.h"
37 #include "h264_levels.h"
38 #include "h2645data.h"
39 #include "vaapi_encode.h"
44 SEI_IDENTIFIER
= 0x02,
45 SEI_RECOVERY_POINT
= 0x04,
49 // Random (version 4) ISO 11578 UUID.
50 static const uint8_t vaapi_encode_h264_sei_identifier_uuid
[16] = {
51 0x59, 0x94, 0x8b, 0x28, 0x11, 0xec, 0x45, 0xaf,
52 0x96, 0x75, 0x19, 0xd4, 0x1f, 0xea, 0xa9, 0x4d,
55 typedef struct VAAPIEncodeH264Picture
{
59 int64_t last_idr_frame
;
67 } VAAPIEncodeH264Picture
;
69 typedef struct VAAPIEncodeH264Context
{
70 VAAPIEncodeContext common
;
71 FFHWBaseEncodeH264 units
;
91 CodedBitstreamContext
*cbc
;
92 CodedBitstreamFragment current_access_unit
;
95 H264RawSlice raw_slice
;
97 H264RawSEIPicTiming sei_pic_timing
;
98 H264RawSEIRecoveryPoint sei_recovery_point
;
99 SEIRawUserDataUnregistered sei_identifier
;
100 char *sei_identifier_string
;
101 SEIRawUserDataRegistered sei_a53cc
;
102 void *sei_a53cc_data
;
106 int sei_cbr_workaround_needed
;
107 } VAAPIEncodeH264Context
;
110 static int vaapi_encode_h264_write_access_unit(AVCodecContext
*avctx
,
111 char *data
, size_t *data_len
,
112 CodedBitstreamFragment
*au
)
114 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
117 err
= ff_cbs_write_fragment_data(priv
->cbc
, au
);
119 av_log(avctx
, AV_LOG_ERROR
, "Failed to write packed header.\n");
123 if (*data_len
< 8 * au
->data_size
- au
->data_bit_padding
) {
124 av_log(avctx
, AV_LOG_ERROR
, "Access unit too large: "
125 "%zu < %zu.\n", *data_len
,
126 8 * au
->data_size
- au
->data_bit_padding
);
127 return AVERROR(ENOSPC
);
130 memcpy(data
, au
->data
, au
->data_size
);
131 *data_len
= 8 * au
->data_size
- au
->data_bit_padding
;
136 static int vaapi_encode_h264_add_nal(AVCodecContext
*avctx
,
137 CodedBitstreamFragment
*au
,
140 H264RawNALUnitHeader
*header
= nal_unit
;
143 err
= ff_cbs_insert_unit_content(au
, -1,
144 header
->nal_unit_type
, nal_unit
, NULL
);
146 av_log(avctx
, AV_LOG_ERROR
, "Failed to add NAL unit: "
147 "type = %d.\n", header
->nal_unit_type
);
154 static int vaapi_encode_h264_write_sequence_header(AVCodecContext
*avctx
,
155 char *data
, size_t *data_len
)
157 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
158 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
161 if (priv
->aud_needed
) {
162 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->raw_aud
);
165 priv
->aud_needed
= 0;
168 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->units
.raw_sps
);
172 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->units
.raw_pps
);
176 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
178 ff_cbs_fragment_reset(au
);
182 static int vaapi_encode_h264_write_slice_header(AVCodecContext
*avctx
,
183 VAAPIEncodePicture
*pic
,
184 VAAPIEncodeSlice
*slice
,
185 char *data
, size_t *data_len
)
187 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
188 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
191 if (priv
->aud_needed
) {
192 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->raw_aud
);
195 priv
->aud_needed
= 0;
198 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->raw_slice
);
202 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
204 ff_cbs_fragment_reset(au
);
208 static int vaapi_encode_h264_write_extra_header(AVCodecContext
*avctx
,
209 FFHWBaseEncodePicture
*base
,
210 int index
, int *type
,
211 char *data
, size_t *data_len
)
213 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
214 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
217 if (priv
->sei_needed
) {
218 if (priv
->aud_needed
) {
219 err
= vaapi_encode_h264_add_nal(avctx
, au
, &priv
->raw_aud
);
222 priv
->aud_needed
= 0;
225 if (priv
->sei_needed
& SEI_IDENTIFIER
) {
226 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
227 SEI_TYPE_USER_DATA_UNREGISTERED
,
228 &priv
->sei_identifier
, NULL
);
232 if (priv
->sei_needed
& SEI_TIMING
) {
233 if (base
->type
== FF_HW_PICTURE_TYPE_IDR
) {
234 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
235 SEI_TYPE_BUFFERING_PERIOD
,
236 &priv
->units
.sei_buffering_period
, NULL
);
240 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
242 &priv
->sei_pic_timing
, NULL
);
246 if (priv
->sei_needed
& SEI_RECOVERY_POINT
) {
247 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
248 SEI_TYPE_RECOVERY_POINT
,
249 &priv
->sei_recovery_point
, NULL
);
253 if (priv
->sei_needed
& SEI_A53_CC
) {
254 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
255 SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
,
256 &priv
->sei_a53cc
, NULL
);
261 priv
->sei_needed
= 0;
263 err
= vaapi_encode_h264_write_access_unit(avctx
, data
, data_len
, au
);
267 ff_cbs_fragment_reset(au
);
269 *type
= VAEncPackedHeaderRawData
;
273 } else if (priv
->sei_cbr_workaround_needed
) {
274 // Insert a zero-length header using the old SEI type. This is
275 // required to avoid triggering broken behaviour on Intel platforms
276 // in CBR mode where an invalid SEI message is generated by the
277 // driver and inserted into the stream.
279 *type
= VAEncPackedHeaderH264_SEI
;
280 priv
->sei_cbr_workaround_needed
= 0;
289 ff_cbs_fragment_reset(au
);
293 static int vaapi_encode_h264_init_sequence_params(AVCodecContext
*avctx
)
295 FFHWBaseEncodeContext
*base_ctx
= avctx
->priv_data
;
296 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
297 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
298 H264RawSPS
*sps
= &priv
->units
.raw_sps
;
299 H264RawPPS
*pps
= &priv
->units
.raw_pps
;
300 VAEncSequenceParameterBufferH264
*vseq
= ctx
->codec_sequence_params
;
301 VAEncPictureParameterBufferH264
*vpic
= ctx
->codec_picture_params
;
303 FFHWBaseEncodeH264Opts unit_opts
= {
304 .flags
= (priv
->sei
& SEI_TIMING
) ? FF_HW_H264_SEI_TIMING
: 0,
305 .mb_width
= priv
->mb_width
,
306 .mb_height
= priv
->mb_height
,
307 .cabac
= priv
->coder
,
308 .hrd_buffer_size
= ctx
->hrd_params
.buffer_size
,
309 .fixed_qp_idr
= priv
->fixed_qp_idr
,
310 .initial_buffer_fullness
= ctx
->hrd_params
.initial_buffer_fullness
,
311 .bit_rate
= ctx
->va_bit_rate
,
314 int err
= ff_hw_base_encode_init_params_h264(base_ctx
, avctx
,
315 &priv
->units
, &unit_opts
);
319 *vseq
= (VAEncSequenceParameterBufferH264
) {
320 .seq_parameter_set_id
= sps
->seq_parameter_set_id
,
321 .level_idc
= sps
->level_idc
,
322 .intra_period
= base_ctx
->gop_size
,
323 .intra_idr_period
= base_ctx
->gop_size
,
324 .ip_period
= base_ctx
->b_per_p
+ 1,
326 .bits_per_second
= ctx
->va_bit_rate
,
327 .max_num_ref_frames
= sps
->max_num_ref_frames
,
328 .picture_width_in_mbs
= sps
->pic_width_in_mbs_minus1
+ 1,
329 .picture_height_in_mbs
= sps
->pic_height_in_map_units_minus1
+ 1,
332 .chroma_format_idc
= sps
->chroma_format_idc
,
333 .frame_mbs_only_flag
= sps
->frame_mbs_only_flag
,
334 .mb_adaptive_frame_field_flag
= sps
->mb_adaptive_frame_field_flag
,
335 .seq_scaling_matrix_present_flag
= sps
->seq_scaling_matrix_present_flag
,
336 .direct_8x8_inference_flag
= sps
->direct_8x8_inference_flag
,
337 .log2_max_frame_num_minus4
= sps
->log2_max_frame_num_minus4
,
338 .pic_order_cnt_type
= sps
->pic_order_cnt_type
,
339 .log2_max_pic_order_cnt_lsb_minus4
= sps
->log2_max_pic_order_cnt_lsb_minus4
,
340 .delta_pic_order_always_zero_flag
= sps
->delta_pic_order_always_zero_flag
,
343 .bit_depth_luma_minus8
= sps
->bit_depth_luma_minus8
,
344 .bit_depth_chroma_minus8
= sps
->bit_depth_chroma_minus8
,
346 .frame_cropping_flag
= sps
->frame_cropping_flag
,
347 .frame_crop_left_offset
= sps
->frame_crop_left_offset
,
348 .frame_crop_right_offset
= sps
->frame_crop_right_offset
,
349 .frame_crop_top_offset
= sps
->frame_crop_top_offset
,
350 .frame_crop_bottom_offset
= sps
->frame_crop_bottom_offset
,
352 .vui_parameters_present_flag
= sps
->vui_parameters_present_flag
,
355 .aspect_ratio_info_present_flag
= sps
->vui
.aspect_ratio_info_present_flag
,
356 .timing_info_present_flag
= sps
->vui
.timing_info_present_flag
,
357 .bitstream_restriction_flag
= sps
->vui
.bitstream_restriction_flag
,
358 .log2_max_mv_length_horizontal
= sps
->vui
.log2_max_mv_length_horizontal
,
359 .log2_max_mv_length_vertical
= sps
->vui
.log2_max_mv_length_vertical
,
362 .aspect_ratio_idc
= sps
->vui
.aspect_ratio_idc
,
363 .sar_width
= sps
->vui
.sar_width
,
364 .sar_height
= sps
->vui
.sar_height
,
365 .num_units_in_tick
= sps
->vui
.num_units_in_tick
,
366 .time_scale
= sps
->vui
.time_scale
,
369 *vpic
= (VAEncPictureParameterBufferH264
) {
371 .picture_id
= VA_INVALID_ID
,
372 .flags
= VA_PICTURE_H264_INVALID
,
375 .coded_buf
= VA_INVALID_ID
,
377 .pic_parameter_set_id
= pps
->pic_parameter_set_id
,
378 .seq_parameter_set_id
= pps
->seq_parameter_set_id
,
380 .pic_init_qp
= pps
->pic_init_qp_minus26
+ 26,
381 .num_ref_idx_l0_active_minus1
= pps
->num_ref_idx_l0_default_active_minus1
,
382 .num_ref_idx_l1_active_minus1
= pps
->num_ref_idx_l1_default_active_minus1
,
384 .chroma_qp_index_offset
= pps
->chroma_qp_index_offset
,
385 .second_chroma_qp_index_offset
= pps
->second_chroma_qp_index_offset
,
388 .entropy_coding_mode_flag
= pps
->entropy_coding_mode_flag
,
389 .weighted_pred_flag
= pps
->weighted_pred_flag
,
390 .weighted_bipred_idc
= pps
->weighted_bipred_idc
,
391 .constrained_intra_pred_flag
= pps
->constrained_intra_pred_flag
,
392 .transform_8x8_mode_flag
= pps
->transform_8x8_mode_flag
,
393 .deblocking_filter_control_present_flag
=
394 pps
->deblocking_filter_control_present_flag
,
395 .redundant_pic_cnt_present_flag
= pps
->redundant_pic_cnt_present_flag
,
396 .pic_order_present_flag
=
397 pps
->bottom_field_pic_order_in_frame_present_flag
,
398 .pic_scaling_matrix_present_flag
= pps
->pic_scaling_matrix_present_flag
,
405 static int vaapi_encode_h264_init_picture_params(AVCodecContext
*avctx
,
406 FFHWBaseEncodePicture
*pic
)
408 FFHWBaseEncodeContext
*base_ctx
= avctx
->priv_data
;
410 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
412 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
413 VAAPIEncodePicture
*vaapi_pic
= pic
->priv
;
414 VAAPIEncodeH264Picture
*hpic
= pic
->codec_priv
;
415 FFHWBaseEncodePicture
*prev
= pic
->prev
;
416 VAAPIEncodeH264Picture
*hprev
= prev
? prev
->codec_priv
: NULL
;
417 VAEncPictureParameterBufferH264
*vpic
= vaapi_pic
->codec_picture_params
;
420 if (pic
->type
== FF_HW_PICTURE_TYPE_IDR
) {
421 av_assert0(pic
->display_order
== pic
->encode_order
);
424 hpic
->last_idr_frame
= pic
->display_order
;
425 hpic
->idr_pic_id
= hprev
? hprev
->idr_pic_id
+ 1 : 0;
427 hpic
->primary_pic_type
= 0;
428 hpic
->slice_type
= 7;
432 hpic
->frame_num
= hprev
->frame_num
+ prev
->is_reference
;
434 hpic
->last_idr_frame
= hprev
->last_idr_frame
;
435 hpic
->idr_pic_id
= hprev
->idr_pic_id
;
437 if (pic
->type
== FF_HW_PICTURE_TYPE_I
) {
438 hpic
->slice_type
= 7;
439 hpic
->primary_pic_type
= 0;
440 } else if (pic
->type
== FF_HW_PICTURE_TYPE_P
) {
441 hpic
->slice_type
= 5;
442 hpic
->primary_pic_type
= 1;
444 hpic
->slice_type
= 6;
445 hpic
->primary_pic_type
= 2;
448 hpic
->pic_order_cnt
= pic
->display_order
- hpic
->last_idr_frame
;
449 if (priv
->units
.raw_sps
.pic_order_cnt_type
== 2) {
450 hpic
->pic_order_cnt
*= 2;
453 hpic
->dpb_delay
= pic
->display_order
- pic
->encode_order
+ base_ctx
->max_b_depth
;
454 hpic
->cpb_delay
= pic
->encode_order
- hpic
->last_idr_frame
;
457 priv
->aud_needed
= 1;
458 priv
->raw_aud
= (H264RawAUD
) {
460 .nal_unit_type
= H264_NAL_AUD
,
462 .primary_pic_type
= hpic
->primary_pic_type
,
465 priv
->aud_needed
= 0;
468 priv
->sei_needed
= 0;
470 if (priv
->sei
& SEI_IDENTIFIER
&& pic
->encode_order
== 0)
471 priv
->sei_needed
|= SEI_IDENTIFIER
;
473 if (ctx
->va_rc_mode
== VA_RC_CBR
)
474 priv
->sei_cbr_workaround_needed
= 1;
477 if (priv
->sei
& SEI_TIMING
) {
478 priv
->sei_pic_timing
= (H264RawSEIPicTiming
) {
479 .cpb_removal_delay
= 2 * hpic
->cpb_delay
,
480 .dpb_output_delay
= 2 * hpic
->dpb_delay
,
483 priv
->sei_needed
|= SEI_TIMING
;
486 if (priv
->sei
& SEI_RECOVERY_POINT
&& pic
->type
== FF_HW_PICTURE_TYPE_I
) {
487 priv
->sei_recovery_point
= (H264RawSEIRecoveryPoint
) {
488 .recovery_frame_cnt
= 0,
489 .exact_match_flag
= 1,
490 .broken_link_flag
= base_ctx
->b_per_p
> 0,
493 priv
->sei_needed
|= SEI_RECOVERY_POINT
;
496 if (priv
->sei
& SEI_A53_CC
) {
498 size_t sei_a53cc_len
;
499 av_freep(&priv
->sei_a53cc_data
);
500 err
= ff_alloc_a53_sei(pic
->input_image
, 0, &priv
->sei_a53cc_data
, &sei_a53cc_len
);
503 if (priv
->sei_a53cc_data
!= NULL
) {
504 priv
->sei_a53cc
.itu_t_t35_country_code
= 181;
505 priv
->sei_a53cc
.data
= (uint8_t *)priv
->sei_a53cc_data
+ 1;
506 priv
->sei_a53cc
.data_length
= sei_a53cc_len
- 1;
508 priv
->sei_needed
|= SEI_A53_CC
;
512 vpic
->CurrPic
= (VAPictureH264
) {
513 .picture_id
= vaapi_pic
->recon_surface
,
514 .frame_idx
= hpic
->frame_num
,
516 .TopFieldOrderCnt
= hpic
->pic_order_cnt
,
517 .BottomFieldOrderCnt
= hpic
->pic_order_cnt
,
519 for (int k
= 0; k
< MAX_REFERENCE_LIST_NUM
; k
++) {
520 for (i
= 0; i
< pic
->nb_refs
[k
]; i
++) {
521 FFHWBaseEncodePicture
*ref
= pic
->refs
[k
][i
];
522 VAAPIEncodeH264Picture
*href
;
524 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
525 href
= ref
->codec_priv
;
527 vpic
->ReferenceFrames
[j
++] = (VAPictureH264
) {
528 .picture_id
= ((VAAPIEncodePicture
*)ref
->priv
)->recon_surface
,
529 .frame_idx
= href
->frame_num
,
530 .flags
= VA_PICTURE_H264_SHORT_TERM_REFERENCE
,
531 .TopFieldOrderCnt
= href
->pic_order_cnt
,
532 .BottomFieldOrderCnt
= href
->pic_order_cnt
,
537 for (; j
< FF_ARRAY_ELEMS(vpic
->ReferenceFrames
); j
++) {
538 vpic
->ReferenceFrames
[j
] = (VAPictureH264
) {
539 .picture_id
= VA_INVALID_ID
,
540 .flags
= VA_PICTURE_H264_INVALID
,
544 vpic
->coded_buf
= vaapi_pic
->output_buffer
;
546 vpic
->frame_num
= hpic
->frame_num
;
548 vpic
->pic_fields
.bits
.idr_pic_flag
= (pic
->type
== FF_HW_PICTURE_TYPE_IDR
);
549 vpic
->pic_fields
.bits
.reference_pic_flag
= pic
->is_reference
;
554 static void vaapi_encode_h264_default_ref_pic_list(AVCodecContext
*avctx
,
555 FFHWBaseEncodePicture
*pic
,
556 FFHWBaseEncodePicture
**rpl0
,
557 FFHWBaseEncodePicture
**rpl1
,
560 FFHWBaseEncodePicture
*prev
;
561 VAAPIEncodeH264Picture
*hp
, *hn
, *hc
;
566 hp
= pic
->codec_priv
;
568 for (i
= 0; i
< pic
->prev
->nb_dpb_pics
; i
++) {
569 hn
= prev
->dpb
[i
]->codec_priv
;
570 av_assert0(hn
->frame_num
< hp
->frame_num
);
572 if (pic
->type
== FF_HW_PICTURE_TYPE_P
) {
573 for (j
= n
; j
> 0; j
--) {
574 hc
= rpl0
[j
- 1]->codec_priv
;
575 av_assert0(hc
->frame_num
!= hn
->frame_num
);
576 if (hc
->frame_num
> hn
->frame_num
)
578 rpl0
[j
] = rpl0
[j
- 1];
580 rpl0
[j
] = prev
->dpb
[i
];
582 } else if (pic
->type
== FF_HW_PICTURE_TYPE_B
) {
583 for (j
= n
; j
> 0; j
--) {
584 hc
= rpl0
[j
- 1]->codec_priv
;
585 av_assert0(hc
->pic_order_cnt
!= hp
->pic_order_cnt
);
586 if (hc
->pic_order_cnt
< hp
->pic_order_cnt
) {
587 if (hn
->pic_order_cnt
> hp
->pic_order_cnt
||
588 hn
->pic_order_cnt
< hc
->pic_order_cnt
)
591 if (hn
->pic_order_cnt
> hc
->pic_order_cnt
)
594 rpl0
[j
] = rpl0
[j
- 1];
596 rpl0
[j
] = prev
->dpb
[i
];
598 for (j
= n
; j
> 0; j
--) {
599 hc
= rpl1
[j
- 1]->codec_priv
;
600 av_assert0(hc
->pic_order_cnt
!= hp
->pic_order_cnt
);
601 if (hc
->pic_order_cnt
> hp
->pic_order_cnt
) {
602 if (hn
->pic_order_cnt
< hp
->pic_order_cnt
||
603 hn
->pic_order_cnt
> hc
->pic_order_cnt
)
606 if (hn
->pic_order_cnt
< hc
->pic_order_cnt
)
609 rpl1
[j
] = rpl1
[j
- 1];
611 rpl1
[j
] = prev
->dpb
[i
];
617 if (pic
->type
== FF_HW_PICTURE_TYPE_B
) {
618 for (i
= 0; i
< n
; i
++) {
619 if (rpl0
[i
] != rpl1
[i
])
623 FFSWAP(FFHWBaseEncodePicture
*, rpl1
[0], rpl1
[1]);
626 if (pic
->type
== FF_HW_PICTURE_TYPE_P
||
627 pic
->type
== FF_HW_PICTURE_TYPE_B
) {
628 av_log(avctx
, AV_LOG_DEBUG
, "Default RefPicList0 for fn=%d/poc=%d:",
629 hp
->frame_num
, hp
->pic_order_cnt
);
630 for (i
= 0; i
< n
; i
++) {
631 hn
= rpl0
[i
]->codec_priv
;
632 av_log(avctx
, AV_LOG_DEBUG
, " fn=%d/poc=%d",
633 hn
->frame_num
, hn
->pic_order_cnt
);
635 av_log(avctx
, AV_LOG_DEBUG
, "\n");
637 if (pic
->type
== FF_HW_PICTURE_TYPE_B
) {
638 av_log(avctx
, AV_LOG_DEBUG
, "Default RefPicList1 for fn=%d/poc=%d:",
639 hp
->frame_num
, hp
->pic_order_cnt
);
640 for (i
= 0; i
< n
; i
++) {
641 hn
= rpl1
[i
]->codec_priv
;
642 av_log(avctx
, AV_LOG_DEBUG
, " fn=%d/poc=%d",
643 hn
->frame_num
, hn
->pic_order_cnt
);
645 av_log(avctx
, AV_LOG_DEBUG
, "\n");
651 static int vaapi_encode_h264_init_slice_params(AVCodecContext
*avctx
,
652 FFHWBaseEncodePicture
*pic
,
653 VAAPIEncodeSlice
*slice
)
655 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
656 VAAPIEncodePicture
*vaapi_pic
= pic
->priv
;
657 VAAPIEncodeH264Picture
*hpic
= pic
->codec_priv
;
658 FFHWBaseEncodePicture
*prev
= pic
->prev
;
659 H264RawSPS
*sps
= &priv
->units
.raw_sps
;
660 H264RawPPS
*pps
= &priv
->units
.raw_pps
;
661 H264RawSliceHeader
*sh
= &priv
->raw_slice
.header
;
662 VAEncPictureParameterBufferH264
*vpic
= vaapi_pic
->codec_picture_params
;
663 VAEncSliceParameterBufferH264
*vslice
= slice
->codec_slice_params
;
666 if (pic
->type
== FF_HW_PICTURE_TYPE_IDR
) {
667 sh
->nal_unit_header
.nal_unit_type
= H264_NAL_IDR_SLICE
;
668 sh
->nal_unit_header
.nal_ref_idc
= 3;
670 sh
->nal_unit_header
.nal_unit_type
= H264_NAL_SLICE
;
671 sh
->nal_unit_header
.nal_ref_idc
= pic
->is_reference
;
674 sh
->first_mb_in_slice
= slice
->block_start
;
675 sh
->slice_type
= hpic
->slice_type
;
677 sh
->pic_parameter_set_id
= pps
->pic_parameter_set_id
;
679 sh
->frame_num
= hpic
->frame_num
&
680 ((1 << (4 + sps
->log2_max_frame_num_minus4
)) - 1);
681 sh
->idr_pic_id
= hpic
->idr_pic_id
;
682 sh
->pic_order_cnt_lsb
= hpic
->pic_order_cnt
&
683 ((1 << (4 + sps
->log2_max_pic_order_cnt_lsb_minus4
)) - 1);
685 sh
->direct_spatial_mv_pred_flag
= 1;
687 if (pic
->type
== FF_HW_PICTURE_TYPE_B
)
688 sh
->slice_qp_delta
= priv
->fixed_qp_b
- (pps
->pic_init_qp_minus26
+ 26);
689 else if (pic
->type
== FF_HW_PICTURE_TYPE_P
)
690 sh
->slice_qp_delta
= priv
->fixed_qp_p
- (pps
->pic_init_qp_minus26
+ 26);
692 sh
->slice_qp_delta
= priv
->fixed_qp_idr
- (pps
->pic_init_qp_minus26
+ 26);
694 if (pic
->is_reference
&& pic
->type
!= FF_HW_PICTURE_TYPE_IDR
) {
695 FFHWBaseEncodePicture
*discard_list
[MAX_DPB_SIZE
];
696 int discard
= 0, keep
= 0;
698 // Discard everything which is in the DPB of the previous frame but
699 // not in the DPB of this one.
700 for (i
= 0; i
< prev
->nb_dpb_pics
; i
++) {
701 for (j
= 0; j
< pic
->nb_dpb_pics
; j
++) {
702 if (prev
->dpb
[i
] == pic
->dpb
[j
])
705 if (j
== pic
->nb_dpb_pics
) {
706 discard_list
[discard
] = prev
->dpb
[i
];
712 av_assert0(keep
<= priv
->units
.dpb_frames
);
715 sh
->adaptive_ref_pic_marking_mode_flag
= 0;
717 sh
->adaptive_ref_pic_marking_mode_flag
= 1;
718 for (i
= 0; i
< discard
; i
++) {
719 VAAPIEncodeH264Picture
*old
= discard_list
[i
]->codec_priv
;
720 av_assert0(old
->frame_num
< hpic
->frame_num
);
721 sh
->mmco
[i
].memory_management_control_operation
= 1;
722 sh
->mmco
[i
].difference_of_pic_nums_minus1
=
723 hpic
->frame_num
- old
->frame_num
- 1;
725 sh
->mmco
[i
].memory_management_control_operation
= 0;
729 // If the intended references are not the first entries of RefPicListN
730 // by default, use ref-pic-list-modification to move them there.
731 if (pic
->type
== FF_HW_PICTURE_TYPE_P
|| pic
->type
== FF_HW_PICTURE_TYPE_B
) {
732 FFHWBaseEncodePicture
*def_l0
[MAX_DPB_SIZE
], *def_l1
[MAX_DPB_SIZE
];
733 VAAPIEncodeH264Picture
*href
;
736 vaapi_encode_h264_default_ref_pic_list(avctx
, pic
,
739 if (pic
->type
== FF_HW_PICTURE_TYPE_P
) {
741 for (i
= 0; i
< pic
->nb_refs
[0]; i
++) {
742 av_assert0(pic
->refs
[0][i
]);
743 if (pic
->refs
[0][i
] != (FFHWBaseEncodePicture
*)def_l0
[i
])
747 sh
->ref_pic_list_modification_flag_l0
= need_rplm
;
749 int pic_num
= hpic
->frame_num
;
750 for (i
= 0; i
< pic
->nb_refs
[0]; i
++) {
751 href
= pic
->refs
[0][i
]->codec_priv
;
752 av_assert0(href
->frame_num
!= pic_num
);
753 if (href
->frame_num
< pic_num
) {
754 sh
->rplm_l0
[i
].modification_of_pic_nums_idc
= 0;
755 sh
->rplm_l0
[i
].abs_diff_pic_num_minus1
=
756 pic_num
- href
->frame_num
- 1;
758 sh
->rplm_l0
[i
].modification_of_pic_nums_idc
= 1;
759 sh
->rplm_l0
[i
].abs_diff_pic_num_minus1
=
760 href
->frame_num
- pic_num
- 1;
762 pic_num
= href
->frame_num
;
764 sh
->rplm_l0
[i
].modification_of_pic_nums_idc
= 3;
768 int need_rplm_l0
= 0, need_rplm_l1
= 0;
770 for (i
= 0; i
< pic
->nb_refs
[0]; i
++) {
771 av_assert0(pic
->refs
[0][i
]);
772 href
= pic
->refs
[0][i
]->codec_priv
;
773 av_assert0(href
->pic_order_cnt
< hpic
->pic_order_cnt
);
774 if (pic
->refs
[0][i
] != (FFHWBaseEncodePicture
*)def_l0
[n0
])
779 for (i
= 0; i
< pic
->nb_refs
[1]; i
++) {
780 av_assert0(pic
->refs
[1][i
]);
781 href
= pic
->refs
[1][i
]->codec_priv
;
782 av_assert0(href
->pic_order_cnt
> hpic
->pic_order_cnt
);
783 if (pic
->refs
[1][i
] != (FFHWBaseEncodePicture
*)def_l1
[n1
])
788 sh
->ref_pic_list_modification_flag_l0
= need_rplm_l0
;
790 int pic_num
= hpic
->frame_num
;
791 for (i
= j
= 0; i
< pic
->nb_refs
[0]; i
++) {
792 href
= pic
->refs
[0][i
]->codec_priv
;
793 av_assert0(href
->frame_num
!= pic_num
);
794 if (href
->frame_num
< pic_num
) {
795 sh
->rplm_l0
[j
].modification_of_pic_nums_idc
= 0;
796 sh
->rplm_l0
[j
].abs_diff_pic_num_minus1
=
797 pic_num
- href
->frame_num
- 1;
799 sh
->rplm_l0
[j
].modification_of_pic_nums_idc
= 1;
800 sh
->rplm_l0
[j
].abs_diff_pic_num_minus1
=
801 href
->frame_num
- pic_num
- 1;
803 pic_num
= href
->frame_num
;
807 sh
->rplm_l0
[j
].modification_of_pic_nums_idc
= 3;
810 sh
->ref_pic_list_modification_flag_l1
= need_rplm_l1
;
812 int pic_num
= hpic
->frame_num
;
813 for (i
= j
= 0; i
< pic
->nb_refs
[1]; i
++) {
814 href
= pic
->refs
[1][i
]->codec_priv
;
815 av_assert0(href
->frame_num
!= pic_num
);
816 if (href
->frame_num
< pic_num
) {
817 sh
->rplm_l1
[j
].modification_of_pic_nums_idc
= 0;
818 sh
->rplm_l1
[j
].abs_diff_pic_num_minus1
=
819 pic_num
- href
->frame_num
- 1;
821 sh
->rplm_l1
[j
].modification_of_pic_nums_idc
= 1;
822 sh
->rplm_l1
[j
].abs_diff_pic_num_minus1
=
823 href
->frame_num
- pic_num
- 1;
825 pic_num
= href
->frame_num
;
829 sh
->rplm_l1
[j
].modification_of_pic_nums_idc
= 3;
834 vslice
->macroblock_address
= slice
->block_start
;
835 vslice
->num_macroblocks
= slice
->block_size
;
837 vslice
->macroblock_info
= VA_INVALID_ID
;
839 vslice
->slice_type
= sh
->slice_type
% 5;
840 vslice
->pic_parameter_set_id
= sh
->pic_parameter_set_id
;
841 vslice
->idr_pic_id
= sh
->idr_pic_id
;
843 vslice
->pic_order_cnt_lsb
= sh
->pic_order_cnt_lsb
;
845 vslice
->direct_spatial_mv_pred_flag
= sh
->direct_spatial_mv_pred_flag
;
847 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->RefPicList0
); i
++) {
848 vslice
->RefPicList0
[i
].picture_id
= VA_INVALID_ID
;
849 vslice
->RefPicList0
[i
].flags
= VA_PICTURE_H264_INVALID
;
850 vslice
->RefPicList1
[i
].picture_id
= VA_INVALID_ID
;
851 vslice
->RefPicList1
[i
].flags
= VA_PICTURE_H264_INVALID
;
854 if (pic
->nb_refs
[0]) {
855 // Backward reference for P- or B-frame.
856 av_assert0(pic
->type
== FF_HW_PICTURE_TYPE_P
||
857 pic
->type
== FF_HW_PICTURE_TYPE_B
);
858 vslice
->RefPicList0
[0] = vpic
->ReferenceFrames
[0];
860 if (pic
->nb_refs
[1]) {
861 // Forward reference for B-frame.
862 av_assert0(pic
->type
== FF_HW_PICTURE_TYPE_B
);
863 vslice
->RefPicList1
[0] = vpic
->ReferenceFrames
[1];
866 vslice
->slice_qp_delta
= sh
->slice_qp_delta
;
871 static av_cold
int vaapi_encode_h264_configure(AVCodecContext
*avctx
)
873 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
874 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
877 err
= ff_cbs_init(&priv
->cbc
, AV_CODEC_ID_H264
, avctx
);
881 priv
->mb_width
= FFALIGN(avctx
->width
, 16) / 16;
882 priv
->mb_height
= FFALIGN(avctx
->height
, 16) / 16;
884 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
885 priv
->fixed_qp_p
= av_clip(ctx
->rc_quality
, 1, 51);
886 if (avctx
->i_quant_factor
> 0.0)
888 av_clip((avctx
->i_quant_factor
* priv
->fixed_qp_p
+
889 avctx
->i_quant_offset
) + 0.5, 1, 51);
891 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
892 if (avctx
->b_quant_factor
> 0.0)
894 av_clip((avctx
->b_quant_factor
* priv
->fixed_qp_p
+
895 avctx
->b_quant_offset
) + 0.5, 1, 51);
897 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
899 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
900 "%d / %d / %d for IDR- / P- / B-frames.\n",
901 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
904 // These still need to be set for pic_init_qp/slice_qp_delta.
905 priv
->fixed_qp_idr
= 26;
906 priv
->fixed_qp_p
= 26;
907 priv
->fixed_qp_b
= 26;
910 if (!ctx
->rc_mode
->hrd
) {
911 // Timing SEI requires a mode respecting HRD parameters.
912 priv
->sei
&= ~SEI_TIMING
;
915 if (priv
->sei
& SEI_IDENTIFIER
) {
916 const char *lavc
= LIBAVCODEC_IDENT
;
917 const char *vaapi
= VA_VERSION_S
;
921 memcpy(priv
->sei_identifier
.uuid_iso_iec_11578
,
922 vaapi_encode_h264_sei_identifier_uuid
,
923 sizeof(priv
->sei_identifier
.uuid_iso_iec_11578
));
925 driver
= vaQueryVendorString(ctx
->hwctx
->display
);
927 driver
= "unknown driver";
929 len
= snprintf(NULL
, 0, "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
931 priv
->sei_identifier_string
= av_malloc(len
+ 1);
932 if (!priv
->sei_identifier_string
)
933 return AVERROR(ENOMEM
);
935 snprintf(priv
->sei_identifier_string
, len
+ 1,
936 "%s / VAAPI %s / %s", lavc
, vaapi
, driver
);
938 priv
->sei_identifier
.data
= priv
->sei_identifier_string
;
939 priv
->sei_identifier
.data_length
= len
+ 1;
943 ctx
->roi_quant_range
= 51 + 6 * (ctx
->profile
->depth
- 8);
948 static const VAAPIEncodeProfile vaapi_encode_h264_profiles
[] = {
949 #if VA_CHECK_VERSION(1, 18, 0)
950 { AV_PROFILE_H264_HIGH_10
, 10, 3, 1, 1, VAProfileH264High10
},
952 { AV_PROFILE_H264_HIGH
, 8, 3, 1, 1, VAProfileH264High
},
953 { AV_PROFILE_H264_MAIN
, 8, 3, 1, 1, VAProfileH264Main
},
954 { AV_PROFILE_H264_CONSTRAINED_BASELINE
,
955 8, 3, 1, 1, VAProfileH264ConstrainedBaseline
},
956 { AV_PROFILE_UNKNOWN
}
959 static const VAAPIEncodeType vaapi_encode_type_h264
= {
960 .profiles
= vaapi_encode_h264_profiles
,
962 .flags
= FF_HW_FLAG_SLICE_CONTROL
|
963 FF_HW_FLAG_B_PICTURES
|
964 FF_HW_FLAG_B_PICTURE_REFERENCES
|
965 FF_HW_FLAG_NON_IDR_KEY_PICTURES
,
967 .default_quality
= 20,
969 .configure
= &vaapi_encode_h264_configure
,
971 .picture_priv_data_size
= sizeof(VAAPIEncodeH264Picture
),
973 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferH264
),
974 .init_sequence_params
= &vaapi_encode_h264_init_sequence_params
,
976 .picture_params_size
= sizeof(VAEncPictureParameterBufferH264
),
977 .init_picture_params
= &vaapi_encode_h264_init_picture_params
,
979 .slice_params_size
= sizeof(VAEncSliceParameterBufferH264
),
980 .init_slice_params
= &vaapi_encode_h264_init_slice_params
,
982 .sequence_header_type
= VAEncPackedHeaderSequence
,
983 .write_sequence_header
= &vaapi_encode_h264_write_sequence_header
,
985 .slice_header_type
= VAEncPackedHeaderH264_Slice
,
986 .write_slice_header
= &vaapi_encode_h264_write_slice_header
,
988 .write_extra_header
= &vaapi_encode_h264_write_extra_header
,
991 static av_cold
int vaapi_encode_h264_init(AVCodecContext
*avctx
)
993 FFHWBaseEncodeContext
*base_ctx
= avctx
->priv_data
;
994 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
995 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
997 ctx
->codec
= &vaapi_encode_type_h264
;
999 if (avctx
->profile
== AV_PROFILE_UNKNOWN
)
1000 avctx
->profile
= priv
->profile
;
1001 if (avctx
->level
== AV_LEVEL_UNKNOWN
)
1002 avctx
->level
= priv
->level
;
1003 if (avctx
->compression_level
== FF_COMPRESSION_DEFAULT
)
1004 avctx
->compression_level
= priv
->quality
;
1006 // Reject unsupported profiles.
1007 switch (avctx
->profile
) {
1008 case AV_PROFILE_H264_BASELINE
:
1009 av_log(avctx
, AV_LOG_WARNING
, "H.264 baseline profile is not "
1010 "supported, using constrained baseline profile instead.\n");
1011 avctx
->profile
= AV_PROFILE_H264_CONSTRAINED_BASELINE
;
1013 case AV_PROFILE_H264_EXTENDED
:
1014 av_log(avctx
, AV_LOG_ERROR
, "H.264 extended profile "
1015 "is not supported.\n");
1016 return AVERROR_PATCHWELCOME
;
1017 case AV_PROFILE_H264_HIGH_10_INTRA
:
1018 av_log(avctx
, AV_LOG_ERROR
, "H.264 high 10 intra profile "
1019 "is not supported.\n");
1020 return AVERROR_PATCHWELCOME
;
1021 case AV_PROFILE_H264_HIGH_422
:
1022 case AV_PROFILE_H264_HIGH_422_INTRA
:
1023 case AV_PROFILE_H264_HIGH_444
:
1024 case AV_PROFILE_H264_HIGH_444_PREDICTIVE
:
1025 case AV_PROFILE_H264_HIGH_444_INTRA
:
1026 case AV_PROFILE_H264_CAVLC_444
:
1027 av_log(avctx
, AV_LOG_ERROR
, "H.264 non-4:2:0 profiles "
1028 "are not supported.\n");
1029 return AVERROR_PATCHWELCOME
;
1032 if (avctx
->level
!= AV_LEVEL_UNKNOWN
&& avctx
->level
& ~0xff) {
1033 av_log(avctx
, AV_LOG_ERROR
, "Invalid level %d: must fit "
1034 "in 8-bit unsigned integer.\n", avctx
->level
);
1035 return AVERROR(EINVAL
);
1038 ctx
->desired_packed_headers
=
1039 VA_ENC_PACKED_HEADER_SEQUENCE
| // SPS and PPS.
1040 VA_ENC_PACKED_HEADER_SLICE
| // Slice headers.
1041 VA_ENC_PACKED_HEADER_MISC
; // SEI.
1043 base_ctx
->surface_width
= FFALIGN(avctx
->width
, 16);
1044 base_ctx
->surface_height
= FFALIGN(avctx
->height
, 16);
1046 base_ctx
->slice_block_height
= base_ctx
->slice_block_width
= 16;
1049 ctx
->explicit_qp
= priv
->qp
;
1051 return ff_vaapi_encode_init(avctx
);
1054 static av_cold
int vaapi_encode_h264_close(AVCodecContext
*avctx
)
1056 VAAPIEncodeH264Context
*priv
= avctx
->priv_data
;
1058 ff_cbs_fragment_free(&priv
->current_access_unit
);
1059 ff_cbs_close(&priv
->cbc
);
1060 av_freep(&priv
->sei_identifier_string
);
1061 av_freep(&priv
->sei_a53cc_data
);
1063 return ff_vaapi_encode_close(avctx
);
1066 #define OFFSET(x) offsetof(VAAPIEncodeH264Context, x)
1067 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1068 static const AVOption vaapi_encode_h264_options
[] = {
1069 HW_BASE_ENCODE_COMMON_OPTIONS
,
1070 VAAPI_ENCODE_COMMON_OPTIONS
,
1071 VAAPI_ENCODE_RC_OPTIONS
,
1073 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1074 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 52, FLAGS
},
1075 { "quality", "Set encode quality (trades off against speed, higher is faster)",
1076 OFFSET(quality
), AV_OPT_TYPE_INT
, { .i64
= -1 }, -1, INT_MAX
, FLAGS
},
1077 { "coder", "Entropy coder type",
1078 OFFSET(coder
), AV_OPT_TYPE_INT
, { .i64
= 1 }, 0, 1, FLAGS
, .unit
= "coder" },
1079 { "cavlc", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 0 }, INT_MIN
, INT_MAX
, FLAGS
, .unit
= "coder" },
1080 { "cabac", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 1 }, INT_MIN
, INT_MAX
, FLAGS
, .unit
= "coder" },
1081 { "vlc", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 0 }, INT_MIN
, INT_MAX
, FLAGS
, .unit
= "coder" },
1082 { "ac", NULL
, 0, AV_OPT_TYPE_CONST
, { .i64
= 1 }, INT_MIN
, INT_MAX
, FLAGS
, .unit
= "coder" },
1084 { "aud", "Include AUD",
1085 OFFSET(aud
), AV_OPT_TYPE_BOOL
, { .i64
= 0 }, 0, 1, FLAGS
},
1087 { "sei", "Set SEI to include",
1088 OFFSET(sei
), AV_OPT_TYPE_FLAGS
,
1089 { .i64
= SEI_IDENTIFIER
| SEI_TIMING
| SEI_RECOVERY_POINT
| SEI_A53_CC
},
1090 0, INT_MAX
, FLAGS
, .unit
= "sei" },
1091 { "identifier", "Include encoder version identifier",
1092 0, AV_OPT_TYPE_CONST
, { .i64
= SEI_IDENTIFIER
},
1093 INT_MIN
, INT_MAX
, FLAGS
, .unit
= "sei" },
1094 { "timing", "Include timing parameters (buffering_period and pic_timing)",
1095 0, AV_OPT_TYPE_CONST
, { .i64
= SEI_TIMING
},
1096 INT_MIN
, INT_MAX
, FLAGS
, .unit
= "sei" },
1097 { "recovery_point", "Include recovery points where appropriate",
1098 0, AV_OPT_TYPE_CONST
, { .i64
= SEI_RECOVERY_POINT
},
1099 INT_MIN
, INT_MAX
, FLAGS
, .unit
= "sei" },
1100 { "a53_cc", "Include A/53 caption data",
1101 0, AV_OPT_TYPE_CONST
, { .i64
= SEI_A53_CC
},
1102 INT_MIN
, INT_MAX
, FLAGS
, .unit
= "sei" },
1104 { "profile", "Set profile (profile_idc and constraint_set*_flag)",
1105 OFFSET(profile
), AV_OPT_TYPE_INT
,
1106 { .i64
= AV_PROFILE_UNKNOWN
}, AV_PROFILE_UNKNOWN
, 0xffff, FLAGS
, .unit
= "profile" },
1108 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1109 { .i64 = value }, 0, 0, FLAGS, .unit = "profile"
1110 { PROFILE("constrained_baseline", AV_PROFILE_H264_CONSTRAINED_BASELINE
) },
1111 { PROFILE("main", AV_PROFILE_H264_MAIN
) },
1112 { PROFILE("high", AV_PROFILE_H264_HIGH
) },
1113 { PROFILE("high10", AV_PROFILE_H264_HIGH_10
) },
1116 { "level", "Set level (level_idc)",
1117 OFFSET(level
), AV_OPT_TYPE_INT
,
1118 { .i64
= AV_LEVEL_UNKNOWN
}, AV_LEVEL_UNKNOWN
, 0xff, FLAGS
, .unit
= "level" },
1120 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1121 { .i64 = value }, 0, 0, FLAGS, .unit = "level"
1123 { LEVEL("1.1", 11) },
1124 { LEVEL("1.2", 12) },
1125 { LEVEL("1.3", 13) },
1127 { LEVEL("2.1", 21) },
1128 { LEVEL("2.2", 22) },
1130 { LEVEL("3.1", 31) },
1131 { LEVEL("3.2", 32) },
1133 { LEVEL("4.1", 41) },
1134 { LEVEL("4.2", 42) },
1136 { LEVEL("5.1", 51) },
1137 { LEVEL("5.2", 52) },
1139 { LEVEL("6.1", 61) },
1140 { LEVEL("6.2", 62) },
1146 static const FFCodecDefault vaapi_encode_h264_defaults
[] = {
1150 { "i_qfactor", "1" },
1151 { "i_qoffset", "0" },
1152 { "b_qfactor", "6/5" },
1153 { "b_qoffset", "0" },
1159 static const AVClass vaapi_encode_h264_class
= {
1160 .class_name
= "h264_vaapi",
1161 .item_name
= av_default_item_name
,
1162 .option
= vaapi_encode_h264_options
,
1163 .version
= LIBAVUTIL_VERSION_INT
,
1166 const FFCodec ff_h264_vaapi_encoder
= {
1167 .p
.name
= "h264_vaapi",
1168 CODEC_LONG_NAME("H.264/AVC (VAAPI)"),
1169 .p
.type
= AVMEDIA_TYPE_VIDEO
,
1170 .p
.id
= AV_CODEC_ID_H264
,
1171 .priv_data_size
= sizeof(VAAPIEncodeH264Context
),
1172 .init
= &vaapi_encode_h264_init
,
1173 FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet
),
1174 .close
= &vaapi_encode_h264_close
,
1175 .p
.priv_class
= &vaapi_encode_h264_class
,
1176 .p
.capabilities
= AV_CODEC_CAP_DELAY
| AV_CODEC_CAP_HARDWARE
|
1177 AV_CODEC_CAP_DR1
| AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
,
1178 .caps_internal
= FF_CODEC_CAP_NOT_INIT_THREADSAFE
|
1179 FF_CODEC_CAP_INIT_CLEANUP
,
1180 .defaults
= vaapi_encode_h264_defaults
,
1181 .p
.pix_fmts
= (const enum AVPixelFormat
[]) {
1185 .color_ranges
= AVCOL_RANGE_MPEG
| AVCOL_RANGE_JPEG
,
1186 .hw_configs
= ff_vaapi_encode_hw_configs
,
1187 .p
.wrapper_name
= "vaapi",