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_hevc.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"
29 #include "libavutil/mastering_display_metadata.h"
35 #include "hw_base_encode_h265.h"
36 #include "codec_internal.h"
37 #include "h2645data.h"
38 #include "h265_profile_level.h"
39 #include "vaapi_encode.h"
41 #include "hevc/hevc.h"
44 SEI_MASTERING_DISPLAY
= 0x08,
45 SEI_CONTENT_LIGHT_LEVEL
= 0x10,
49 typedef struct VAAPIEncodeH265Picture
{
52 int64_t last_idr_frame
;
57 } VAAPIEncodeH265Picture
;
59 typedef struct VAAPIEncodeH265Context
{
60 VAAPIEncodeContext common
;
81 FFHWBaseEncodeH265 units
;
82 FFHWBaseEncodeH265Opts unit_opts
;
84 H265RawSlice raw_slice
;
86 SEIRawMasteringDisplayColourVolume sei_mastering_display
;
87 SEIRawContentLightLevelInfo sei_content_light_level
;
88 SEIRawUserDataRegistered sei_a53cc
;
91 CodedBitstreamContext
*cbc
;
92 CodedBitstreamFragment current_access_unit
;
95 } VAAPIEncodeH265Context
;
98 static int vaapi_encode_h265_write_access_unit(AVCodecContext
*avctx
,
99 char *data
, size_t *data_len
,
100 CodedBitstreamFragment
*au
)
102 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
105 err
= ff_cbs_write_fragment_data(priv
->cbc
, au
);
107 av_log(avctx
, AV_LOG_ERROR
, "Failed to write packed header.\n");
111 if (*data_len
< 8 * au
->data_size
- au
->data_bit_padding
) {
112 av_log(avctx
, AV_LOG_ERROR
, "Access unit too large: "
113 "%zu < %zu.\n", *data_len
,
114 8 * au
->data_size
- au
->data_bit_padding
);
115 return AVERROR(ENOSPC
);
118 memcpy(data
, au
->data
, au
->data_size
);
119 *data_len
= 8 * au
->data_size
- au
->data_bit_padding
;
124 static int vaapi_encode_h265_add_nal(AVCodecContext
*avctx
,
125 CodedBitstreamFragment
*au
,
128 H265RawNALUnitHeader
*header
= nal_unit
;
131 err
= ff_cbs_insert_unit_content(au
, -1,
132 header
->nal_unit_type
, nal_unit
, NULL
);
134 av_log(avctx
, AV_LOG_ERROR
, "Failed to add NAL unit: "
135 "type = %d.\n", header
->nal_unit_type
);
142 static int vaapi_encode_h265_write_sequence_header(AVCodecContext
*avctx
,
143 char *data
, size_t *data_len
)
145 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
146 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
149 if (priv
->aud_needed
) {
150 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_aud
);
153 priv
->aud_needed
= 0;
156 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->units
.raw_vps
);
160 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->units
.raw_sps
);
164 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->units
.raw_pps
);
168 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
170 ff_cbs_fragment_reset(au
);
174 static int vaapi_encode_h265_write_slice_header(AVCodecContext
*avctx
,
175 VAAPIEncodePicture
*pic
,
176 VAAPIEncodeSlice
*slice
,
177 char *data
, size_t *data_len
)
179 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
180 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
183 if (priv
->aud_needed
) {
184 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_aud
);
187 priv
->aud_needed
= 0;
190 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_slice
);
194 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
196 ff_cbs_fragment_reset(au
);
200 static int vaapi_encode_h265_write_extra_header(AVCodecContext
*avctx
,
201 FFHWBaseEncodePicture
*base
,
202 int index
, int *type
,
203 char *data
, size_t *data_len
)
205 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
206 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
209 if (priv
->sei_needed
) {
210 if (priv
->aud_needed
) {
211 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->aud
);
214 priv
->aud_needed
= 0;
217 if (priv
->sei_needed
& SEI_MASTERING_DISPLAY
) {
218 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
219 SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME
,
220 &priv
->sei_mastering_display
, NULL
);
225 if (priv
->sei_needed
& SEI_CONTENT_LIGHT_LEVEL
) {
226 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
227 SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO
,
228 &priv
->sei_content_light_level
, NULL
);
232 if (priv
->sei_needed
& SEI_A53_CC
) {
233 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
234 SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35
,
235 &priv
->sei_a53cc
, NULL
);
240 priv
->sei_needed
= 0;
242 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
246 ff_cbs_fragment_reset(au
);
248 *type
= VAEncPackedHeaderRawData
;
255 ff_cbs_fragment_reset(au
);
259 static int vaapi_encode_h265_init_sequence_params(AVCodecContext
*avctx
)
261 FFHWBaseEncodeContext
*base_ctx
= avctx
->priv_data
;
262 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
263 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
264 H265RawVPS
*vps
= &priv
->units
.raw_vps
;
265 H265RawSPS
*sps
= &priv
->units
.raw_sps
;
266 H265RawPPS
*pps
= &priv
->units
.raw_pps
;
267 VAEncSequenceParameterBufferHEVC
*vseq
= ctx
->codec_sequence_params
;
268 VAEncPictureParameterBufferHEVC
*vpic
= ctx
->codec_picture_params
;
271 // priv->unit_opts.tier already set
272 // priv->unit_opts.fixed_qp_idr already set
273 priv
->unit_opts
.cu_qp_delta_enabled_flag
= (ctx
->va_rc_mode
!= VA_RC_CQP
);
274 priv
->unit_opts
.tile_rows
= ctx
->tile_rows
;
275 priv
->unit_opts
.tile_cols
= ctx
->tile_cols
;
276 priv
->unit_opts
.nb_slices
= ctx
->nb_slices
;
277 priv
->unit_opts
.slice_block_rows
= ctx
->slice_block_rows
;
278 priv
->unit_opts
.slice_block_cols
= ctx
->slice_block_cols
;
279 memcpy(priv
->unit_opts
.col_width
, ctx
->col_width
,
280 ctx
->tile_rows
*sizeof(*priv
->unit_opts
.col_width
));
281 memcpy(priv
->unit_opts
.row_height
, ctx
->row_height
,
282 ctx
->tile_cols
*sizeof(*priv
->unit_opts
.row_height
));
284 err
= ff_hw_base_encode_init_params_h265(base_ctx
, avctx
,
285 &priv
->units
, &priv
->unit_opts
);
289 #if VA_CHECK_VERSION(1, 13, 0)
290 // update sps setting according to queried result
291 if (priv
->va_features
) {
292 VAConfigAttribValEncHEVCFeatures features
= { .value
= priv
->va_features
};
294 // Enable feature if get queried result is VA_FEATURE_SUPPORTED | VA_FEATURE_REQUIRED
295 sps
->amp_enabled_flag
=
297 sps
->sample_adaptive_offset_enabled_flag
=
299 sps
->sps_temporal_mvp_enabled_flag
=
300 !!features
.bits
.temporal_mvp
;
301 sps
->pcm_enabled_flag
=
306 VAConfigAttribValEncHEVCBlockSizes bs
= { .value
= priv
->va_bs
};
307 sps
->log2_min_luma_coding_block_size_minus3
=
308 ff_ctz(priv
->min_cb_size
) - 3;
309 sps
->log2_diff_max_min_luma_coding_block_size
=
310 ff_ctz(priv
->ctu_size
) - ff_ctz(priv
->min_cb_size
);
312 sps
->log2_min_luma_transform_block_size_minus2
=
313 bs
.bits
.log2_min_luma_transform_block_size_minus2
;
314 sps
->log2_diff_max_min_luma_transform_block_size
=
315 bs
.bits
.log2_max_luma_transform_block_size_minus2
-
316 bs
.bits
.log2_min_luma_transform_block_size_minus2
;
318 sps
->max_transform_hierarchy_depth_inter
=
319 bs
.bits
.max_max_transform_hierarchy_depth_inter
;
320 sps
->max_transform_hierarchy_depth_intra
=
321 bs
.bits
.max_max_transform_hierarchy_depth_intra
;
324 // update pps setting according to queried result
325 if (priv
->va_features
) {
326 VAConfigAttribValEncHEVCFeatures features
= { .value
= priv
->va_features
};
327 if (ctx
->va_rc_mode
!= VA_RC_CQP
)
328 pps
->cu_qp_delta_enabled_flag
=
329 !!features
.bits
.cu_qp_delta
;
331 pps
->transform_skip_enabled_flag
=
332 !!features
.bits
.transform_skip
;
333 // set diff_cu_qp_delta_depth as its max value if cu_qp_delta enabled. Otherwise
334 // 0 will make cu_qp_delta invalid.
335 if (pps
->cu_qp_delta_enabled_flag
)
336 pps
->diff_cu_qp_delta_depth
= sps
->log2_diff_max_min_luma_coding_block_size
;
340 // Fill VAAPI parameter buffers.
342 *vseq
= (VAEncSequenceParameterBufferHEVC
) {
343 .general_profile_idc
= vps
->profile_tier_level
.general_profile_idc
,
344 .general_level_idc
= vps
->profile_tier_level
.general_level_idc
,
345 .general_tier_flag
= vps
->profile_tier_level
.general_tier_flag
,
347 .intra_period
= base_ctx
->gop_size
,
348 .intra_idr_period
= base_ctx
->gop_size
,
349 .ip_period
= base_ctx
->b_per_p
+ 1,
350 .bits_per_second
= ctx
->va_bit_rate
,
352 .pic_width_in_luma_samples
= sps
->pic_width_in_luma_samples
,
353 .pic_height_in_luma_samples
= sps
->pic_height_in_luma_samples
,
356 .chroma_format_idc
= sps
->chroma_format_idc
,
357 .separate_colour_plane_flag
= sps
->separate_colour_plane_flag
,
358 .bit_depth_luma_minus8
= sps
->bit_depth_luma_minus8
,
359 .bit_depth_chroma_minus8
= sps
->bit_depth_chroma_minus8
,
360 .scaling_list_enabled_flag
= sps
->scaling_list_enabled_flag
,
361 .strong_intra_smoothing_enabled_flag
=
362 sps
->strong_intra_smoothing_enabled_flag
,
363 .amp_enabled_flag
= sps
->amp_enabled_flag
,
364 .sample_adaptive_offset_enabled_flag
=
365 sps
->sample_adaptive_offset_enabled_flag
,
366 .pcm_enabled_flag
= sps
->pcm_enabled_flag
,
367 .pcm_loop_filter_disabled_flag
= sps
->pcm_loop_filter_disabled_flag
,
368 .sps_temporal_mvp_enabled_flag
= sps
->sps_temporal_mvp_enabled_flag
,
371 .log2_min_luma_coding_block_size_minus3
=
372 sps
->log2_min_luma_coding_block_size_minus3
,
373 .log2_diff_max_min_luma_coding_block_size
=
374 sps
->log2_diff_max_min_luma_coding_block_size
,
375 .log2_min_transform_block_size_minus2
=
376 sps
->log2_min_luma_transform_block_size_minus2
,
377 .log2_diff_max_min_transform_block_size
=
378 sps
->log2_diff_max_min_luma_transform_block_size
,
379 .max_transform_hierarchy_depth_inter
=
380 sps
->max_transform_hierarchy_depth_inter
,
381 .max_transform_hierarchy_depth_intra
=
382 sps
->max_transform_hierarchy_depth_intra
,
384 .pcm_sample_bit_depth_luma_minus1
=
385 sps
->pcm_sample_bit_depth_luma_minus1
,
386 .pcm_sample_bit_depth_chroma_minus1
=
387 sps
->pcm_sample_bit_depth_chroma_minus1
,
388 .log2_min_pcm_luma_coding_block_size_minus3
=
389 sps
->log2_min_pcm_luma_coding_block_size_minus3
,
390 .log2_max_pcm_luma_coding_block_size_minus3
=
391 sps
->log2_min_pcm_luma_coding_block_size_minus3
+
392 sps
->log2_diff_max_min_pcm_luma_coding_block_size
,
394 .vui_parameters_present_flag
= 0,
397 *vpic
= (VAEncPictureParameterBufferHEVC
) {
398 .decoded_curr_pic
= {
399 .picture_id
= VA_INVALID_ID
,
400 .flags
= VA_PICTURE_HEVC_INVALID
,
403 .coded_buf
= VA_INVALID_ID
,
405 .collocated_ref_pic_index
= sps
->sps_temporal_mvp_enabled_flag
?
409 .pic_init_qp
= pps
->init_qp_minus26
+ 26,
410 .diff_cu_qp_delta_depth
= pps
->diff_cu_qp_delta_depth
,
411 .pps_cb_qp_offset
= pps
->pps_cb_qp_offset
,
412 .pps_cr_qp_offset
= pps
->pps_cr_qp_offset
,
414 .num_tile_columns_minus1
= pps
->num_tile_columns_minus1
,
415 .num_tile_rows_minus1
= pps
->num_tile_rows_minus1
,
417 .log2_parallel_merge_level_minus2
= pps
->log2_parallel_merge_level_minus2
,
418 .ctu_max_bitsize_allowed
= 0,
420 .num_ref_idx_l0_default_active_minus1
=
421 pps
->num_ref_idx_l0_default_active_minus1
,
422 .num_ref_idx_l1_default_active_minus1
=
423 pps
->num_ref_idx_l1_default_active_minus1
,
425 .slice_pic_parameter_set_id
= pps
->pps_pic_parameter_set_id
,
428 .sign_data_hiding_enabled_flag
= pps
->sign_data_hiding_enabled_flag
,
429 .constrained_intra_pred_flag
= pps
->constrained_intra_pred_flag
,
430 .transform_skip_enabled_flag
= pps
->transform_skip_enabled_flag
,
431 .cu_qp_delta_enabled_flag
= pps
->cu_qp_delta_enabled_flag
,
432 .weighted_pred_flag
= pps
->weighted_pred_flag
,
433 .weighted_bipred_flag
= pps
->weighted_bipred_flag
,
434 .transquant_bypass_enabled_flag
= pps
->transquant_bypass_enabled_flag
,
435 .tiles_enabled_flag
= pps
->tiles_enabled_flag
,
436 .entropy_coding_sync_enabled_flag
= pps
->entropy_coding_sync_enabled_flag
,
437 .loop_filter_across_tiles_enabled_flag
=
438 pps
->loop_filter_across_tiles_enabled_flag
,
439 .pps_loop_filter_across_slices_enabled_flag
=
440 pps
->pps_loop_filter_across_slices_enabled_flag
,
441 .scaling_list_data_present_flag
= (sps
->sps_scaling_list_data_present_flag
|
442 pps
->pps_scaling_list_data_present_flag
),
443 .screen_content_flag
= 0,
444 .enable_gpu_weighted_prediction
= 0,
445 .no_output_of_prior_pics_flag
= 0,
449 if (pps
->tiles_enabled_flag
) {
450 for (i
= 0; i
<= vpic
->num_tile_rows_minus1
; i
++)
451 vpic
->row_height_minus1
[i
] = pps
->row_height_minus1
[i
];
452 for (i
= 0; i
<= vpic
->num_tile_columns_minus1
; i
++)
453 vpic
->column_width_minus1
[i
] = pps
->column_width_minus1
[i
];
459 static int vaapi_encode_h265_init_picture_params(AVCodecContext
*avctx
,
460 FFHWBaseEncodePicture
*pic
)
462 FFHWBaseEncodeContext
*base_ctx
= avctx
->priv_data
;
463 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
464 VAAPIEncodePicture
*vaapi_pic
= pic
->priv
;
465 VAAPIEncodeH265Picture
*hpic
= pic
->codec_priv
;
466 FFHWBaseEncodePicture
*prev
= pic
->prev
;
467 VAAPIEncodeH265Picture
*hprev
= prev
? prev
->codec_priv
: NULL
;
468 VAEncPictureParameterBufferHEVC
*vpic
= vaapi_pic
->codec_picture_params
;
471 if (pic
->type
== FF_HW_PICTURE_TYPE_IDR
) {
472 av_assert0(pic
->display_order
== pic
->encode_order
);
474 hpic
->last_idr_frame
= pic
->display_order
;
476 hpic
->slice_nal_unit
= HEVC_NAL_IDR_W_RADL
;
477 hpic
->slice_type
= HEVC_SLICE_I
;
481 hpic
->last_idr_frame
= hprev
->last_idr_frame
;
483 if (pic
->type
== FF_HW_PICTURE_TYPE_I
) {
484 hpic
->slice_nal_unit
= HEVC_NAL_CRA_NUT
;
485 hpic
->slice_type
= HEVC_SLICE_I
;
487 } else if (pic
->type
== FF_HW_PICTURE_TYPE_P
) {
488 av_assert0(pic
->refs
[0]);
489 hpic
->slice_nal_unit
= HEVC_NAL_TRAIL_R
;
490 hpic
->slice_type
= HEVC_SLICE_P
;
493 FFHWBaseEncodePicture
*irap_ref
;
494 av_assert0(pic
->refs
[0][0] && pic
->refs
[1][0]);
495 for (irap_ref
= pic
; irap_ref
; irap_ref
= irap_ref
->refs
[1][0]) {
496 if (irap_ref
->type
== FF_HW_PICTURE_TYPE_I
)
499 if (pic
->b_depth
== base_ctx
->max_b_depth
) {
500 hpic
->slice_nal_unit
= irap_ref
? HEVC_NAL_RASL_N
503 hpic
->slice_nal_unit
= irap_ref
? HEVC_NAL_RASL_R
506 hpic
->slice_type
= HEVC_SLICE_B
;
510 hpic
->pic_order_cnt
= pic
->display_order
- hpic
->last_idr_frame
;
513 priv
->aud_needed
= 1;
514 priv
->raw_aud
= (H265RawAUD
) {
516 .nal_unit_type
= HEVC_NAL_AUD
,
518 .nuh_temporal_id_plus1
= 1,
520 .pic_type
= hpic
->pic_type
,
523 priv
->aud_needed
= 0;
526 priv
->sei_needed
= 0;
528 // Only look for the metadata on I/IDR frame on the output. We
529 // may force an IDR frame on the output where the medadata gets
530 // changed on the input frame.
531 if ((priv
->sei
& SEI_MASTERING_DISPLAY
) &&
532 (pic
->type
== FF_HW_PICTURE_TYPE_I
|| pic
->type
== FF_HW_PICTURE_TYPE_IDR
)) {
533 AVFrameSideData
*sd
=
534 av_frame_get_side_data(pic
->input_image
,
535 AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
);
538 AVMasteringDisplayMetadata
*mdm
=
539 (AVMasteringDisplayMetadata
*)sd
->data
;
541 // SEI is needed when both the primaries and luminance are set
542 if (mdm
->has_primaries
&& mdm
->has_luminance
) {
543 SEIRawMasteringDisplayColourVolume
*mdcv
=
544 &priv
->sei_mastering_display
;
545 const int mapping
[3] = {1, 2, 0};
546 const int chroma_den
= 50000;
547 const int luma_den
= 10000;
549 for (i
= 0; i
< 3; i
++) {
550 const int j
= mapping
[i
];
551 mdcv
->display_primaries_x
[i
] =
552 FFMIN(lrint(chroma_den
*
553 av_q2d(mdm
->display_primaries
[j
][0])),
555 mdcv
->display_primaries_y
[i
] =
556 FFMIN(lrint(chroma_den
*
557 av_q2d(mdm
->display_primaries
[j
][1])),
561 mdcv
->white_point_x
=
562 FFMIN(lrint(chroma_den
* av_q2d(mdm
->white_point
[0])),
564 mdcv
->white_point_y
=
565 FFMIN(lrint(chroma_den
* av_q2d(mdm
->white_point
[1])),
568 mdcv
->max_display_mastering_luminance
=
569 lrint(luma_den
* av_q2d(mdm
->max_luminance
));
570 mdcv
->min_display_mastering_luminance
=
571 FFMIN(lrint(luma_den
* av_q2d(mdm
->min_luminance
)),
572 mdcv
->max_display_mastering_luminance
);
574 priv
->sei_needed
|= SEI_MASTERING_DISPLAY
;
579 if ((priv
->sei
& SEI_CONTENT_LIGHT_LEVEL
) &&
580 (pic
->type
== FF_HW_PICTURE_TYPE_I
|| pic
->type
== FF_HW_PICTURE_TYPE_IDR
)) {
581 AVFrameSideData
*sd
=
582 av_frame_get_side_data(pic
->input_image
,
583 AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
);
586 AVContentLightMetadata
*clm
=
587 (AVContentLightMetadata
*)sd
->data
;
588 SEIRawContentLightLevelInfo
*clli
=
589 &priv
->sei_content_light_level
;
591 clli
->max_content_light_level
= FFMIN(clm
->MaxCLL
, 65535);
592 clli
->max_pic_average_light_level
= FFMIN(clm
->MaxFALL
, 65535);
594 priv
->sei_needed
|= SEI_CONTENT_LIGHT_LEVEL
;
598 if (priv
->sei
& SEI_A53_CC
) {
600 size_t sei_a53cc_len
;
601 av_freep(&priv
->sei_a53cc_data
);
602 err
= ff_alloc_a53_sei(pic
->input_image
, 0, &priv
->sei_a53cc_data
, &sei_a53cc_len
);
605 if (priv
->sei_a53cc_data
!= NULL
) {
606 priv
->sei_a53cc
.itu_t_t35_country_code
= 181;
607 priv
->sei_a53cc
.data
= (uint8_t *)priv
->sei_a53cc_data
+ 1;
608 priv
->sei_a53cc
.data_length
= sei_a53cc_len
- 1;
610 priv
->sei_needed
|= SEI_A53_CC
;
614 vpic
->decoded_curr_pic
= (VAPictureHEVC
) {
615 .picture_id
= vaapi_pic
->recon_surface
,
616 .pic_order_cnt
= hpic
->pic_order_cnt
,
620 for (int k
= 0; k
< MAX_REFERENCE_LIST_NUM
; k
++) {
621 for (i
= 0; i
< pic
->nb_refs
[k
]; i
++) {
622 FFHWBaseEncodePicture
*ref
= pic
->refs
[k
][i
];
623 VAAPIEncodeH265Picture
*href
;
625 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
626 href
= ref
->codec_priv
;
628 vpic
->reference_frames
[j
++] = (VAPictureHEVC
) {
629 .picture_id
= ((VAAPIEncodePicture
*)ref
->priv
)->recon_surface
,
630 .pic_order_cnt
= href
->pic_order_cnt
,
631 .flags
= (ref
->display_order
< pic
->display_order
?
632 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE
: 0) |
633 (ref
->display_order
> pic
->display_order
?
634 VA_PICTURE_HEVC_RPS_ST_CURR_AFTER
: 0),
639 for (; j
< FF_ARRAY_ELEMS(vpic
->reference_frames
); j
++) {
640 vpic
->reference_frames
[j
] = (VAPictureHEVC
) {
641 .picture_id
= VA_INVALID_ID
,
642 .flags
= VA_PICTURE_HEVC_INVALID
,
646 vpic
->coded_buf
= vaapi_pic
->output_buffer
;
648 vpic
->nal_unit_type
= hpic
->slice_nal_unit
;
650 vpic
->pic_fields
.bits
.reference_pic_flag
= pic
->is_reference
;
652 case FF_HW_PICTURE_TYPE_IDR
:
653 vpic
->pic_fields
.bits
.idr_pic_flag
= 1;
654 vpic
->pic_fields
.bits
.coding_type
= 1;
656 case FF_HW_PICTURE_TYPE_I
:
657 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
658 vpic
->pic_fields
.bits
.coding_type
= 1;
660 case FF_HW_PICTURE_TYPE_P
:
661 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
662 vpic
->pic_fields
.bits
.coding_type
= 2;
664 case FF_HW_PICTURE_TYPE_B
:
665 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
666 vpic
->pic_fields
.bits
.coding_type
= 3;
669 av_assert0(0 && "invalid picture type");
675 static int vaapi_encode_h265_init_slice_params(AVCodecContext
*avctx
,
676 FFHWBaseEncodePicture
*pic
,
677 VAAPIEncodeSlice
*slice
)
679 FFHWBaseEncodeContext
*base_ctx
= avctx
->priv_data
;
680 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
681 VAAPIEncodePicture
*vaapi_pic
= pic
->priv
;
682 VAAPIEncodeH265Picture
*hpic
= pic
->codec_priv
;
683 const H265RawSPS
*sps
= &priv
->units
.raw_sps
;
684 const H265RawPPS
*pps
= &priv
->units
.raw_pps
;
685 H265RawSliceHeader
*sh
= &priv
->raw_slice
.header
;
686 VAEncPictureParameterBufferHEVC
*vpic
= vaapi_pic
->codec_picture_params
;
687 VAEncSliceParameterBufferHEVC
*vslice
= slice
->codec_slice_params
;
690 sh
->nal_unit_header
= (H265RawNALUnitHeader
) {
691 .nal_unit_type
= hpic
->slice_nal_unit
,
693 .nuh_temporal_id_plus1
= 1,
696 sh
->slice_pic_parameter_set_id
= pps
->pps_pic_parameter_set_id
;
698 sh
->first_slice_segment_in_pic_flag
= slice
->index
== 0;
699 sh
->slice_segment_address
= slice
->block_start
;
701 sh
->slice_type
= hpic
->slice_type
;
703 if (sh
->slice_type
== HEVC_SLICE_P
&& base_ctx
->p_to_gpb
)
704 sh
->slice_type
= HEVC_SLICE_B
;
706 sh
->slice_pic_order_cnt_lsb
= hpic
->pic_order_cnt
&
707 (1 << (sps
->log2_max_pic_order_cnt_lsb_minus4
+ 4)) - 1;
709 if (pic
->type
!= FF_HW_PICTURE_TYPE_IDR
) {
710 H265RawSTRefPicSet
*rps
;
711 const VAAPIEncodeH265Picture
*strp
;
712 int rps_poc
[MAX_DPB_SIZE
];
713 int rps_used
[MAX_DPB_SIZE
];
714 int i
, j
, poc
, rps_pics
;
716 sh
->short_term_ref_pic_set_sps_flag
= 0;
718 rps
= &sh
->short_term_ref_pic_set
;
719 memset(rps
, 0, sizeof(*rps
));
722 for (i
= 0; i
< MAX_REFERENCE_LIST_NUM
; i
++) {
723 for (j
= 0; j
< pic
->nb_refs
[i
]; j
++) {
724 strp
= pic
->refs
[i
][j
]->codec_priv
;
725 rps_poc
[rps_pics
] = strp
->pic_order_cnt
;
726 rps_used
[rps_pics
] = 1;
731 for (i
= 0; i
< pic
->nb_dpb_pics
; i
++) {
732 if (pic
->dpb
[i
] == pic
)
735 for (j
= 0; j
< pic
->nb_refs
[0]; j
++) {
736 if (pic
->dpb
[i
] == pic
->refs
[0][j
])
739 if (j
< pic
->nb_refs
[0])
742 for (j
= 0; j
< pic
->nb_refs
[1]; j
++) {
743 if (pic
->dpb
[i
] == pic
->refs
[1][j
])
746 if (j
< pic
->nb_refs
[1])
749 strp
= pic
->dpb
[i
]->codec_priv
;
750 rps_poc
[rps_pics
] = strp
->pic_order_cnt
;
751 rps_used
[rps_pics
] = 0;
755 for (i
= 1; i
< rps_pics
; i
++) {
756 for (j
= i
; j
> 0; j
--) {
757 if (rps_poc
[j
] > rps_poc
[j
- 1])
759 av_assert0(rps_poc
[j
] != rps_poc
[j
- 1]);
760 FFSWAP(int, rps_poc
[j
], rps_poc
[j
- 1]);
761 FFSWAP(int, rps_used
[j
], rps_used
[j
- 1]);
765 av_log(avctx
, AV_LOG_DEBUG
, "RPS for POC %d:",
766 hpic
->pic_order_cnt
);
767 for (i
= 0; i
< rps_pics
; i
++) {
768 av_log(avctx
, AV_LOG_DEBUG
, " (%d,%d)",
769 rps_poc
[i
], rps_used
[i
]);
771 av_log(avctx
, AV_LOG_DEBUG
, "\n");
773 for (i
= 0; i
< rps_pics
; i
++) {
774 av_assert0(rps_poc
[i
] != hpic
->pic_order_cnt
);
775 if (rps_poc
[i
] > hpic
->pic_order_cnt
)
779 rps
->num_negative_pics
= i
;
780 poc
= hpic
->pic_order_cnt
;
781 for (j
= i
- 1; j
>= 0; j
--) {
782 rps
->delta_poc_s0_minus1
[i
- 1 - j
] = poc
- rps_poc
[j
] - 1;
783 rps
->used_by_curr_pic_s0_flag
[i
- 1 - j
] = rps_used
[j
];
787 rps
->num_positive_pics
= rps_pics
- i
;
788 poc
= hpic
->pic_order_cnt
;
789 for (j
= i
; j
< rps_pics
; j
++) {
790 rps
->delta_poc_s1_minus1
[j
- i
] = rps_poc
[j
] - poc
- 1;
791 rps
->used_by_curr_pic_s1_flag
[j
- i
] = rps_used
[j
];
795 sh
->num_long_term_sps
= 0;
796 sh
->num_long_term_pics
= 0;
798 // when this flag is not present, it is inerred to 1.
799 sh
->collocated_from_l0_flag
= 1;
800 sh
->slice_temporal_mvp_enabled_flag
=
801 sps
->sps_temporal_mvp_enabled_flag
;
802 if (sh
->slice_temporal_mvp_enabled_flag
) {
803 if (sh
->slice_type
== HEVC_SLICE_B
)
804 sh
->collocated_from_l0_flag
= 1;
805 sh
->collocated_ref_idx
= 0;
808 sh
->num_ref_idx_active_override_flag
= 0;
809 sh
->num_ref_idx_l0_active_minus1
= pps
->num_ref_idx_l0_default_active_minus1
;
810 sh
->num_ref_idx_l1_active_minus1
= pps
->num_ref_idx_l1_default_active_minus1
;
813 sh
->slice_sao_luma_flag
= sh
->slice_sao_chroma_flag
=
814 sps
->sample_adaptive_offset_enabled_flag
;
816 if (pic
->type
== FF_HW_PICTURE_TYPE_B
)
817 sh
->slice_qp_delta
= priv
->fixed_qp_b
- (pps
->init_qp_minus26
+ 26);
818 else if (pic
->type
== FF_HW_PICTURE_TYPE_P
)
819 sh
->slice_qp_delta
= priv
->fixed_qp_p
- (pps
->init_qp_minus26
+ 26);
821 sh
->slice_qp_delta
= priv
->unit_opts
.fixed_qp_idr
- (pps
->init_qp_minus26
+ 26);
824 *vslice
= (VAEncSliceParameterBufferHEVC
) {
825 .slice_segment_address
= sh
->slice_segment_address
,
826 .num_ctu_in_slice
= slice
->block_size
,
828 .slice_type
= sh
->slice_type
,
829 .slice_pic_parameter_set_id
= sh
->slice_pic_parameter_set_id
,
831 .num_ref_idx_l0_active_minus1
= sh
->num_ref_idx_l0_active_minus1
,
832 .num_ref_idx_l1_active_minus1
= sh
->num_ref_idx_l1_active_minus1
,
834 .luma_log2_weight_denom
= sh
->luma_log2_weight_denom
,
835 .delta_chroma_log2_weight_denom
= sh
->delta_chroma_log2_weight_denom
,
837 .max_num_merge_cand
= 5 - sh
->five_minus_max_num_merge_cand
,
839 .slice_qp_delta
= sh
->slice_qp_delta
,
840 .slice_cb_qp_offset
= sh
->slice_cb_qp_offset
,
841 .slice_cr_qp_offset
= sh
->slice_cr_qp_offset
,
843 .slice_beta_offset_div2
= sh
->slice_beta_offset_div2
,
844 .slice_tc_offset_div2
= sh
->slice_tc_offset_div2
,
846 .slice_fields
.bits
= {
847 .last_slice_of_pic_flag
= slice
->index
== vaapi_pic
->nb_slices
- 1,
848 .dependent_slice_segment_flag
= sh
->dependent_slice_segment_flag
,
849 .colour_plane_id
= sh
->colour_plane_id
,
850 .slice_temporal_mvp_enabled_flag
=
851 sh
->slice_temporal_mvp_enabled_flag
,
852 .slice_sao_luma_flag
= sh
->slice_sao_luma_flag
,
853 .slice_sao_chroma_flag
= sh
->slice_sao_chroma_flag
,
854 .num_ref_idx_active_override_flag
=
855 sh
->num_ref_idx_active_override_flag
,
856 .mvd_l1_zero_flag
= sh
->mvd_l1_zero_flag
,
857 .cabac_init_flag
= sh
->cabac_init_flag
,
858 .slice_deblocking_filter_disabled_flag
=
859 sh
->slice_deblocking_filter_disabled_flag
,
860 .slice_loop_filter_across_slices_enabled_flag
=
861 sh
->slice_loop_filter_across_slices_enabled_flag
,
862 .collocated_from_l0_flag
= sh
->collocated_from_l0_flag
,
866 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->ref_pic_list0
); i
++) {
867 vslice
->ref_pic_list0
[i
].picture_id
= VA_INVALID_ID
;
868 vslice
->ref_pic_list0
[i
].flags
= VA_PICTURE_HEVC_INVALID
;
869 vslice
->ref_pic_list1
[i
].picture_id
= VA_INVALID_ID
;
870 vslice
->ref_pic_list1
[i
].flags
= VA_PICTURE_HEVC_INVALID
;
873 if (pic
->nb_refs
[0]) {
874 // Backward reference for P- or B-frame.
875 av_assert0(pic
->type
== FF_HW_PICTURE_TYPE_P
||
876 pic
->type
== FF_HW_PICTURE_TYPE_B
);
877 vslice
->ref_pic_list0
[0] = vpic
->reference_frames
[0];
878 if (base_ctx
->p_to_gpb
&& pic
->type
== FF_HW_PICTURE_TYPE_P
)
879 // Reference for GPB B-frame, L0 == L1
880 vslice
->ref_pic_list1
[0] = vpic
->reference_frames
[0];
882 if (pic
->nb_refs
[1]) {
883 // Forward reference for B-frame.
884 av_assert0(pic
->type
== FF_HW_PICTURE_TYPE_B
);
885 vslice
->ref_pic_list1
[0] = vpic
->reference_frames
[1];
888 if (pic
->type
== FF_HW_PICTURE_TYPE_P
&& base_ctx
->p_to_gpb
) {
889 vslice
->slice_type
= HEVC_SLICE_B
;
890 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->ref_pic_list0
); i
++) {
891 vslice
->ref_pic_list1
[i
].picture_id
= vslice
->ref_pic_list0
[i
].picture_id
;
892 vslice
->ref_pic_list1
[i
].flags
= vslice
->ref_pic_list0
[i
].flags
;
899 static av_cold
int vaapi_encode_h265_get_encoder_caps(AVCodecContext
*avctx
)
901 FFHWBaseEncodeContext
*base_ctx
= avctx
->priv_data
;
902 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
904 #if VA_CHECK_VERSION(1, 13, 0)
906 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
907 VAConfigAttribValEncHEVCBlockSizes block_size
;
911 attr
.type
= VAConfigAttribEncHEVCFeatures
;
912 vas
= vaGetConfigAttributes(ctx
->hwctx
->display
, ctx
->va_profile
,
913 ctx
->va_entrypoint
, &attr
, 1);
914 if (vas
!= VA_STATUS_SUCCESS
) {
915 av_log(avctx
, AV_LOG_ERROR
, "Failed to query encoder "
916 "features, using guessed defaults.\n");
917 return AVERROR_EXTERNAL
;
918 } else if (attr
.value
== VA_ATTRIB_NOT_SUPPORTED
) {
919 av_log(avctx
, AV_LOG_WARNING
, "Driver does not advertise "
920 "encoder features, using guessed defaults.\n");
922 priv
->va_features
= attr
.value
;
925 attr
.type
= VAConfigAttribEncHEVCBlockSizes
;
926 vas
= vaGetConfigAttributes(ctx
->hwctx
->display
, ctx
->va_profile
,
927 ctx
->va_entrypoint
, &attr
, 1);
928 if (vas
!= VA_STATUS_SUCCESS
) {
929 av_log(avctx
, AV_LOG_ERROR
, "Failed to query encoder "
930 "block size, using guessed defaults.\n");
931 return AVERROR_EXTERNAL
;
932 } else if (attr
.value
== VA_ATTRIB_NOT_SUPPORTED
) {
933 av_log(avctx
, AV_LOG_WARNING
, "Driver does not advertise "
934 "encoder block size, using guessed defaults.\n");
936 priv
->va_bs
= block_size
.value
= attr
.value
;
939 1 << block_size
.bits
.log2_max_coding_tree_block_size_minus3
+ 3;
941 1 << block_size
.bits
.log2_min_luma_coding_block_size_minus3
+ 3;
946 if (!priv
->ctu_size
) {
948 priv
->min_cb_size
= 16;
950 av_log(avctx
, AV_LOG_VERBOSE
, "Using CTU size %dx%d, "
951 "min CB size %dx%d.\n", priv
->ctu_size
, priv
->ctu_size
,
952 priv
->min_cb_size
, priv
->min_cb_size
);
954 base_ctx
->surface_width
= FFALIGN(avctx
->width
,
955 FFMAX(priv
->min_cb_size
, priv
->common
.surface_alignment_width
));
956 base_ctx
->surface_height
= FFALIGN(avctx
->height
,
957 FFMAX(priv
->min_cb_size
, priv
->common
.surface_alignment_height
));
959 base_ctx
->slice_block_width
= base_ctx
->slice_block_height
= priv
->ctu_size
;
964 static av_cold
int vaapi_encode_h265_configure(AVCodecContext
*avctx
)
966 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
967 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
970 err
= ff_cbs_init(&priv
->cbc
, AV_CODEC_ID_HEVC
, avctx
);
974 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
975 // Note that VAAPI only supports positive QP values - the range is
976 // therefore always bounded below by 1, even in 10-bit mode where
977 // it should go down to -12.
979 priv
->fixed_qp_p
= av_clip(ctx
->rc_quality
, 1, 51);
980 if (avctx
->i_quant_factor
> 0.0)
981 priv
->unit_opts
.fixed_qp_idr
=
982 av_clip((avctx
->i_quant_factor
* priv
->fixed_qp_p
+
983 avctx
->i_quant_offset
) + 0.5, 1, 51);
985 priv
->unit_opts
.fixed_qp_idr
= priv
->fixed_qp_p
;
986 if (avctx
->b_quant_factor
> 0.0)
988 av_clip((avctx
->b_quant_factor
* priv
->fixed_qp_p
+
989 avctx
->b_quant_offset
) + 0.5, 1, 51);
991 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
993 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
994 "%d / %d / %d for IDR- / P- / B-frames.\n",
995 priv
->unit_opts
.fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
998 // These still need to be set for init_qp/slice_qp_delta.
999 priv
->unit_opts
.fixed_qp_idr
= 30;
1000 priv
->fixed_qp_p
= 30;
1001 priv
->fixed_qp_b
= 30;
1004 ctx
->roi_quant_range
= 51 + 6 * (ctx
->profile
->depth
- 8);
1009 static const VAAPIEncodeProfile vaapi_encode_h265_profiles
[] = {
1010 { AV_PROFILE_HEVC_MAIN
, 8, 3, 1, 1, VAProfileHEVCMain
},
1011 { AV_PROFILE_HEVC_REXT
, 8, 3, 1, 1, VAProfileHEVCMain
},
1012 #if VA_CHECK_VERSION(0, 37, 0)
1013 { AV_PROFILE_HEVC_MAIN_10
, 10, 3, 1, 1, VAProfileHEVCMain10
},
1014 { AV_PROFILE_HEVC_REXT
, 10, 3, 1, 1, VAProfileHEVCMain10
},
1016 #if VA_CHECK_VERSION(1, 2, 0)
1017 { AV_PROFILE_HEVC_REXT
, 12, 3, 1, 1, VAProfileHEVCMain12
},
1018 { AV_PROFILE_HEVC_REXT
, 8, 3, 1, 0, VAProfileHEVCMain422_10
},
1019 { AV_PROFILE_HEVC_REXT
, 10, 3, 1, 0, VAProfileHEVCMain422_10
},
1020 { AV_PROFILE_HEVC_REXT
, 12, 3, 1, 0, VAProfileHEVCMain422_12
},
1021 { AV_PROFILE_HEVC_REXT
, 8, 3, 0, 0, VAProfileHEVCMain444
},
1022 { AV_PROFILE_HEVC_REXT
, 10, 3, 0, 0, VAProfileHEVCMain444_10
},
1023 { AV_PROFILE_HEVC_REXT
, 12, 3, 0, 0, VAProfileHEVCMain444_12
},
1025 { AV_PROFILE_UNKNOWN
}
1028 static const VAAPIEncodeType vaapi_encode_type_h265
= {
1029 .profiles
= vaapi_encode_h265_profiles
,
1031 .flags
= FF_HW_FLAG_SLICE_CONTROL
|
1032 FF_HW_FLAG_B_PICTURES
|
1033 FF_HW_FLAG_B_PICTURE_REFERENCES
|
1034 FF_HW_FLAG_NON_IDR_KEY_PICTURES
,
1036 .default_quality
= 25,
1038 .get_encoder_caps
= &vaapi_encode_h265_get_encoder_caps
,
1039 .configure
= &vaapi_encode_h265_configure
,
1041 .picture_priv_data_size
= sizeof(VAAPIEncodeH265Picture
),
1043 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferHEVC
),
1044 .init_sequence_params
= &vaapi_encode_h265_init_sequence_params
,
1046 .picture_params_size
= sizeof(VAEncPictureParameterBufferHEVC
),
1047 .init_picture_params
= &vaapi_encode_h265_init_picture_params
,
1049 .slice_params_size
= sizeof(VAEncSliceParameterBufferHEVC
),
1050 .init_slice_params
= &vaapi_encode_h265_init_slice_params
,
1052 .sequence_header_type
= VAEncPackedHeaderSequence
,
1053 .write_sequence_header
= &vaapi_encode_h265_write_sequence_header
,
1055 .slice_header_type
= VAEncPackedHeaderHEVC_Slice
,
1056 .write_slice_header
= &vaapi_encode_h265_write_slice_header
,
1058 .write_extra_header
= &vaapi_encode_h265_write_extra_header
,
1061 static av_cold
int vaapi_encode_h265_init(AVCodecContext
*avctx
)
1063 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1064 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
1066 ctx
->codec
= &vaapi_encode_type_h265
;
1068 if (avctx
->profile
== AV_PROFILE_UNKNOWN
)
1069 avctx
->profile
= priv
->profile
;
1070 if (avctx
->level
== AV_LEVEL_UNKNOWN
)
1071 avctx
->level
= priv
->level
;
1073 if (avctx
->level
!= AV_LEVEL_UNKNOWN
&& avctx
->level
& ~0xff) {
1074 av_log(avctx
, AV_LOG_ERROR
, "Invalid level %d: must fit "
1075 "in 8-bit unsigned integer.\n", avctx
->level
);
1076 return AVERROR(EINVAL
);
1079 ctx
->desired_packed_headers
=
1080 VA_ENC_PACKED_HEADER_SEQUENCE
| // VPS, SPS and PPS.
1081 VA_ENC_PACKED_HEADER_SLICE
| // Slice headers.
1082 VA_ENC_PACKED_HEADER_MISC
; // SEI
1085 ctx
->explicit_qp
= priv
->qp
;
1087 return ff_vaapi_encode_init(avctx
);
1090 static av_cold
int vaapi_encode_h265_close(AVCodecContext
*avctx
)
1092 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
1094 ff_cbs_fragment_free(&priv
->current_access_unit
);
1095 ff_cbs_close(&priv
->cbc
);
1096 av_freep(&priv
->sei_a53cc_data
);
1098 return ff_vaapi_encode_close(avctx
);
1101 #define OFFSET(x) offsetof(VAAPIEncodeH265Context, x)
1102 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1103 static const AVOption vaapi_encode_h265_options
[] = {
1104 HW_BASE_ENCODE_COMMON_OPTIONS
,
1105 VAAPI_ENCODE_COMMON_OPTIONS
,
1106 VAAPI_ENCODE_RC_OPTIONS
,
1108 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1109 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 52, FLAGS
},
1111 { "aud", "Include AUD",
1112 OFFSET(aud
), AV_OPT_TYPE_BOOL
, { .i64
= 0 }, 0, 1, FLAGS
},
1114 { "profile", "Set profile (general_profile_idc)",
1115 OFFSET(profile
), AV_OPT_TYPE_INT
,
1116 { .i64
= AV_PROFILE_UNKNOWN
}, AV_PROFILE_UNKNOWN
, 0xff, FLAGS
, .unit
= "profile" },
1118 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1119 { .i64 = value }, 0, 0, FLAGS, .unit = "profile"
1120 { PROFILE("main", AV_PROFILE_HEVC_MAIN
) },
1121 { PROFILE("main10", AV_PROFILE_HEVC_MAIN_10
) },
1122 { PROFILE("rext", AV_PROFILE_HEVC_REXT
) },
1125 { "tier", "Set tier (general_tier_flag)",
1126 OFFSET(unit_opts
.tier
), AV_OPT_TYPE_INT
,
1127 { .i64
= 0 }, 0, 1, FLAGS
, .unit
= "tier" },
1128 { "main", NULL
, 0, AV_OPT_TYPE_CONST
,
1129 { .i64
= 0 }, 0, 0, FLAGS
, .unit
= "tier" },
1130 { "high", NULL
, 0, AV_OPT_TYPE_CONST
,
1131 { .i64
= 1 }, 0, 0, FLAGS
, .unit
= "tier" },
1133 { "level", "Set level (general_level_idc)",
1134 OFFSET(level
), AV_OPT_TYPE_INT
,
1135 { .i64
= AV_LEVEL_UNKNOWN
}, AV_LEVEL_UNKNOWN
, 0xff, FLAGS
, .unit
= "level" },
1137 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1138 { .i64 = value }, 0, 0, FLAGS, .unit = "level"
1141 { LEVEL("2.1", 63) },
1143 { LEVEL("3.1", 93) },
1144 { LEVEL("4", 120) },
1145 { LEVEL("4.1", 123) },
1146 { LEVEL("5", 150) },
1147 { LEVEL("5.1", 153) },
1148 { LEVEL("5.2", 156) },
1149 { LEVEL("6", 180) },
1150 { LEVEL("6.1", 183) },
1151 { LEVEL("6.2", 186) },
1154 { "sei", "Set SEI to include",
1155 OFFSET(sei
), AV_OPT_TYPE_FLAGS
,
1156 { .i64
= SEI_MASTERING_DISPLAY
| SEI_CONTENT_LIGHT_LEVEL
| SEI_A53_CC
},
1157 0, INT_MAX
, FLAGS
, .unit
= "sei" },
1159 "Include HDR metadata for mastering display colour volume "
1160 "and content light level information",
1161 0, AV_OPT_TYPE_CONST
,
1162 { .i64
= SEI_MASTERING_DISPLAY
| SEI_CONTENT_LIGHT_LEVEL
},
1163 INT_MIN
, INT_MAX
, FLAGS
, .unit
= "sei" },
1165 "Include A/53 caption data",
1166 0, AV_OPT_TYPE_CONST
,
1167 { .i64
= SEI_A53_CC
},
1168 INT_MIN
, INT_MAX
, FLAGS
, .unit
= "sei" },
1170 { "tiles", "Tile columns x rows",
1171 OFFSET(common
.tile_cols
), AV_OPT_TYPE_IMAGE_SIZE
,
1172 { .str
= NULL
}, 0, 0, FLAGS
},
1177 static const FFCodecDefault vaapi_encode_h265_defaults
[] = {
1181 { "i_qfactor", "1" },
1182 { "i_qoffset", "0" },
1183 { "b_qfactor", "6/5" },
1184 { "b_qoffset", "0" },
1190 static const AVClass vaapi_encode_h265_class
= {
1191 .class_name
= "h265_vaapi",
1192 .item_name
= av_default_item_name
,
1193 .option
= vaapi_encode_h265_options
,
1194 .version
= LIBAVUTIL_VERSION_INT
,
1197 const FFCodec ff_hevc_vaapi_encoder
= {
1198 .p
.name
= "hevc_vaapi",
1199 CODEC_LONG_NAME("H.265/HEVC (VAAPI)"),
1200 .p
.type
= AVMEDIA_TYPE_VIDEO
,
1201 .p
.id
= AV_CODEC_ID_HEVC
,
1202 .priv_data_size
= sizeof(VAAPIEncodeH265Context
),
1203 .init
= &vaapi_encode_h265_init
,
1204 FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet
),
1205 .close
= &vaapi_encode_h265_close
,
1206 .p
.priv_class
= &vaapi_encode_h265_class
,
1207 .p
.capabilities
= AV_CODEC_CAP_DELAY
| AV_CODEC_CAP_HARDWARE
|
1208 AV_CODEC_CAP_DR1
| AV_CODEC_CAP_ENCODER_REORDERED_OPAQUE
,
1209 .caps_internal
= FF_CODEC_CAP_NOT_INIT_THREADSAFE
|
1210 FF_CODEC_CAP_INIT_CLEANUP
,
1211 .defaults
= vaapi_encode_h265_defaults
,
1212 .p
.pix_fmts
= (const enum AVPixelFormat
[]) {
1216 .color_ranges
= AVCOL_RANGE_MPEG
| AVCOL_RANGE_JPEG
,
1217 .hw_configs
= ff_vaapi_encode_hw_configs
,
1218 .p
.wrapper_name
= "vaapi",