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/pixdesc.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/mastering_display_metadata.h"
33 #include "codec_internal.h"
34 #include "h265_profile_level.h"
38 #include "vaapi_encode.h"
41 SEI_MASTERING_DISPLAY
= 0x08,
42 SEI_CONTENT_LIGHT_LEVEL
= 0x10,
45 typedef struct VAAPIEncodeH265Picture
{
48 int64_t last_idr_frame
;
53 } VAAPIEncodeH265Picture
;
55 typedef struct VAAPIEncodeH265Context
{
56 VAAPIEncodeContext common
;
83 H265RawSlice raw_slice
;
85 SEIRawMasteringDisplayColourVolume sei_mastering_display
;
86 SEIRawContentLightLevelInfo sei_content_light_level
;
88 CodedBitstreamContext
*cbc
;
89 CodedBitstreamFragment current_access_unit
;
92 } VAAPIEncodeH265Context
;
95 static int vaapi_encode_h265_write_access_unit(AVCodecContext
*avctx
,
96 char *data
, size_t *data_len
,
97 CodedBitstreamFragment
*au
)
99 VAAPIEncodeH265Context
*priv
= avctx
->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_h265_add_nal(AVCodecContext
*avctx
,
122 CodedBitstreamFragment
*au
,
125 H265RawNALUnitHeader
*header
= nal_unit
;
128 err
= ff_cbs_insert_unit_content(au
, -1,
129 header
->nal_unit_type
, nal_unit
, NULL
);
131 av_log(avctx
, AV_LOG_ERROR
, "Failed to add NAL unit: "
132 "type = %d.\n", header
->nal_unit_type
);
139 static int vaapi_encode_h265_write_sequence_header(AVCodecContext
*avctx
,
140 char *data
, size_t *data_len
)
142 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
143 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
146 if (priv
->aud_needed
) {
147 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_aud
);
150 priv
->aud_needed
= 0;
153 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_vps
);
157 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_sps
);
161 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_pps
);
165 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
167 ff_cbs_fragment_reset(au
);
171 static int vaapi_encode_h265_write_slice_header(AVCodecContext
*avctx
,
172 VAAPIEncodePicture
*pic
,
173 VAAPIEncodeSlice
*slice
,
174 char *data
, size_t *data_len
)
176 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
177 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
180 if (priv
->aud_needed
) {
181 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_aud
);
184 priv
->aud_needed
= 0;
187 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->raw_slice
);
191 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
193 ff_cbs_fragment_reset(au
);
197 static int vaapi_encode_h265_write_extra_header(AVCodecContext
*avctx
,
198 VAAPIEncodePicture
*pic
,
199 int index
, int *type
,
200 char *data
, size_t *data_len
)
202 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
203 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
206 if (priv
->sei_needed
) {
207 if (priv
->aud_needed
) {
208 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->aud
);
211 priv
->aud_needed
= 0;
214 if (priv
->sei_needed
& SEI_MASTERING_DISPLAY
) {
215 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
216 SEI_TYPE_MASTERING_DISPLAY_COLOUR_VOLUME
,
217 &priv
->sei_mastering_display
, NULL
);
222 if (priv
->sei_needed
& SEI_CONTENT_LIGHT_LEVEL
) {
223 err
= ff_cbs_sei_add_message(priv
->cbc
, au
, 1,
224 SEI_TYPE_CONTENT_LIGHT_LEVEL_INFO
,
225 &priv
->sei_content_light_level
, NULL
);
230 priv
->sei_needed
= 0;
232 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
236 ff_cbs_fragment_reset(au
);
238 *type
= VAEncPackedHeaderRawData
;
245 ff_cbs_fragment_reset(au
);
249 static int vaapi_encode_h265_init_sequence_params(AVCodecContext
*avctx
)
251 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
252 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
253 H265RawVPS
*vps
= &priv
->raw_vps
;
254 H265RawSPS
*sps
= &priv
->raw_sps
;
255 H265RawPPS
*pps
= &priv
->raw_pps
;
256 H265RawProfileTierLevel
*ptl
= &vps
->profile_tier_level
;
257 H265RawVUI
*vui
= &sps
->vui
;
258 VAEncSequenceParameterBufferHEVC
*vseq
= ctx
->codec_sequence_params
;
259 VAEncPictureParameterBufferHEVC
*vpic
= ctx
->codec_picture_params
;
260 const AVPixFmtDescriptor
*desc
;
261 int chroma_format
, bit_depth
;
264 memset(vps
, 0, sizeof(*vps
));
265 memset(sps
, 0, sizeof(*sps
));
266 memset(pps
, 0, sizeof(*pps
));
269 desc
= av_pix_fmt_desc_get(priv
->common
.input_frames
->sw_format
);
271 if (desc
->nb_components
== 1) {
274 if (desc
->log2_chroma_w
== 1 && desc
->log2_chroma_h
== 1) {
276 } else if (desc
->log2_chroma_w
== 1 && desc
->log2_chroma_h
== 0) {
278 } else if (desc
->log2_chroma_w
== 0 && desc
->log2_chroma_h
== 0) {
281 av_log(avctx
, AV_LOG_ERROR
, "Chroma format of input pixel format "
282 "%s is not supported.\n", desc
->name
);
283 return AVERROR(EINVAL
);
286 bit_depth
= desc
->comp
[0].depth
;
291 vps
->nal_unit_header
= (H265RawNALUnitHeader
) {
292 .nal_unit_type
= HEVC_NAL_VPS
,
294 .nuh_temporal_id_plus1
= 1,
297 vps
->vps_video_parameter_set_id
= 0;
299 vps
->vps_base_layer_internal_flag
= 1;
300 vps
->vps_base_layer_available_flag
= 1;
301 vps
->vps_max_layers_minus1
= 0;
302 vps
->vps_max_sub_layers_minus1
= 0;
303 vps
->vps_temporal_id_nesting_flag
= 1;
305 ptl
->general_profile_space
= 0;
306 ptl
->general_profile_idc
= avctx
->profile
;
307 ptl
->general_tier_flag
= priv
->tier
;
309 ptl
->general_profile_compatibility_flag
[ptl
->general_profile_idc
] = 1;
311 if (ptl
->general_profile_compatibility_flag
[1])
312 ptl
->general_profile_compatibility_flag
[2] = 1;
313 if (ptl
->general_profile_compatibility_flag
[3]) {
314 ptl
->general_profile_compatibility_flag
[1] = 1;
315 ptl
->general_profile_compatibility_flag
[2] = 1;
318 ptl
->general_progressive_source_flag
= 1;
319 ptl
->general_interlaced_source_flag
= 0;
320 ptl
->general_non_packed_constraint_flag
= 1;
321 ptl
->general_frame_only_constraint_flag
= 1;
323 ptl
->general_max_14bit_constraint_flag
= bit_depth
<= 14;
324 ptl
->general_max_12bit_constraint_flag
= bit_depth
<= 12;
325 ptl
->general_max_10bit_constraint_flag
= bit_depth
<= 10;
326 ptl
->general_max_8bit_constraint_flag
= bit_depth
== 8;
328 ptl
->general_max_422chroma_constraint_flag
= chroma_format
<= 2;
329 ptl
->general_max_420chroma_constraint_flag
= chroma_format
<= 1;
330 ptl
->general_max_monochrome_constraint_flag
= chroma_format
== 0;
332 ptl
->general_intra_constraint_flag
= ctx
->gop_size
== 1;
333 ptl
->general_one_picture_only_constraint_flag
= 0;
335 ptl
->general_lower_bit_rate_constraint_flag
= 1;
337 if (avctx
->level
!= FF_LEVEL_UNKNOWN
) {
338 ptl
->general_level_idc
= avctx
->level
;
340 const H265LevelDescriptor
*level
;
342 level
= ff_h265_guess_level(ptl
, avctx
->bit_rate
,
343 ctx
->surface_width
, ctx
->surface_height
,
344 ctx
->nb_slices
, ctx
->tile_rows
, ctx
->tile_cols
,
345 (ctx
->b_per_p
> 0) + 1);
347 av_log(avctx
, AV_LOG_VERBOSE
, "Using level %s.\n", level
->name
);
348 ptl
->general_level_idc
= level
->level_idc
;
350 av_log(avctx
, AV_LOG_VERBOSE
, "Stream will not conform to "
351 "any normal level; using level 8.5.\n");
352 ptl
->general_level_idc
= 255;
353 // The tier flag must be set in level 8.5.
354 ptl
->general_tier_flag
= 1;
358 vps
->vps_sub_layer_ordering_info_present_flag
= 0;
359 vps
->vps_max_dec_pic_buffering_minus1
[0] = ctx
->max_b_depth
+ 1;
360 vps
->vps_max_num_reorder_pics
[0] = ctx
->max_b_depth
;
361 vps
->vps_max_latency_increase_plus1
[0] = 0;
363 vps
->vps_max_layer_id
= 0;
364 vps
->vps_num_layer_sets_minus1
= 0;
365 vps
->layer_id_included_flag
[0][0] = 1;
367 vps
->vps_timing_info_present_flag
= 1;
368 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
369 vps
->vps_num_units_in_tick
= avctx
->framerate
.den
;
370 vps
->vps_time_scale
= avctx
->framerate
.num
;
371 vps
->vps_poc_proportional_to_timing_flag
= 1;
372 vps
->vps_num_ticks_poc_diff_one_minus1
= 0;
374 vps
->vps_num_units_in_tick
= avctx
->time_base
.num
;
375 vps
->vps_time_scale
= avctx
->time_base
.den
;
376 vps
->vps_poc_proportional_to_timing_flag
= 0;
378 vps
->vps_num_hrd_parameters
= 0;
383 sps
->nal_unit_header
= (H265RawNALUnitHeader
) {
384 .nal_unit_type
= HEVC_NAL_SPS
,
386 .nuh_temporal_id_plus1
= 1,
389 sps
->sps_video_parameter_set_id
= vps
->vps_video_parameter_set_id
;
391 sps
->sps_max_sub_layers_minus1
= vps
->vps_max_sub_layers_minus1
;
392 sps
->sps_temporal_id_nesting_flag
= vps
->vps_temporal_id_nesting_flag
;
394 sps
->profile_tier_level
= vps
->profile_tier_level
;
396 sps
->sps_seq_parameter_set_id
= 0;
398 sps
->chroma_format_idc
= chroma_format
;
399 sps
->separate_colour_plane_flag
= 0;
401 sps
->pic_width_in_luma_samples
= ctx
->surface_width
;
402 sps
->pic_height_in_luma_samples
= ctx
->surface_height
;
404 if (avctx
->width
!= ctx
->surface_width
||
405 avctx
->height
!= ctx
->surface_height
) {
406 sps
->conformance_window_flag
= 1;
407 sps
->conf_win_left_offset
= 0;
408 sps
->conf_win_right_offset
=
409 (ctx
->surface_width
- avctx
->width
) >> desc
->log2_chroma_w
;
410 sps
->conf_win_top_offset
= 0;
411 sps
->conf_win_bottom_offset
=
412 (ctx
->surface_height
- avctx
->height
) >> desc
->log2_chroma_h
;
414 sps
->conformance_window_flag
= 0;
417 sps
->bit_depth_luma_minus8
= bit_depth
- 8;
418 sps
->bit_depth_chroma_minus8
= bit_depth
- 8;
420 sps
->log2_max_pic_order_cnt_lsb_minus4
= 8;
422 sps
->sps_sub_layer_ordering_info_present_flag
=
423 vps
->vps_sub_layer_ordering_info_present_flag
;
424 for (i
= 0; i
<= sps
->sps_max_sub_layers_minus1
; i
++) {
425 sps
->sps_max_dec_pic_buffering_minus1
[i
] =
426 vps
->vps_max_dec_pic_buffering_minus1
[i
];
427 sps
->sps_max_num_reorder_pics
[i
] =
428 vps
->vps_max_num_reorder_pics
[i
];
429 sps
->sps_max_latency_increase_plus1
[i
] =
430 vps
->vps_max_latency_increase_plus1
[i
];
433 // These values come from the capabilities of the first encoder
434 // implementation in the i965 driver on Intel Skylake. They may
435 // fail badly with other platforms or drivers.
436 // CTB size from 8x8 to 32x32.
437 sps
->log2_min_luma_coding_block_size_minus3
= 0;
438 sps
->log2_diff_max_min_luma_coding_block_size
= 2;
439 // Transform size from 4x4 to 32x32.
440 sps
->log2_min_luma_transform_block_size_minus2
= 0;
441 sps
->log2_diff_max_min_luma_transform_block_size
= 3;
442 // Full transform hierarchy allowed (2-5).
443 sps
->max_transform_hierarchy_depth_inter
= 3;
444 sps
->max_transform_hierarchy_depth_intra
= 3;
446 sps
->amp_enabled_flag
= 1;
447 // SAO and temporal MVP do not work.
448 sps
->sample_adaptive_offset_enabled_flag
= 0;
449 sps
->sps_temporal_mvp_enabled_flag
= 0;
451 sps
->pcm_enabled_flag
= 0;
453 // update sps setting according to queried result
454 #if VA_CHECK_VERSION(1, 13, 0)
455 if (priv
->va_features
) {
456 VAConfigAttribValEncHEVCFeatures features
= { .value
= priv
->va_features
};
458 // Enable feature if get queried result is VA_FEATURE_SUPPORTED | VA_FEATURE_REQUIRED
459 sps
->amp_enabled_flag
=
461 sps
->sample_adaptive_offset_enabled_flag
=
463 sps
->sps_temporal_mvp_enabled_flag
=
464 !!features
.bits
.temporal_mvp
;
465 sps
->pcm_enabled_flag
=
470 VAConfigAttribValEncHEVCBlockSizes bs
= { .value
= priv
->va_bs
};
471 sps
->log2_min_luma_coding_block_size_minus3
=
472 ff_ctz(priv
->min_cb_size
) - 3;
473 sps
->log2_diff_max_min_luma_coding_block_size
=
474 ff_ctz(priv
->ctu_size
) - ff_ctz(priv
->min_cb_size
);
476 sps
->log2_min_luma_transform_block_size_minus2
=
477 bs
.bits
.log2_min_luma_transform_block_size_minus2
;
478 sps
->log2_diff_max_min_luma_transform_block_size
=
479 bs
.bits
.log2_max_luma_transform_block_size_minus2
-
480 bs
.bits
.log2_min_luma_transform_block_size_minus2
;
482 sps
->max_transform_hierarchy_depth_inter
=
483 bs
.bits
.max_max_transform_hierarchy_depth_inter
;
484 sps
->max_transform_hierarchy_depth_intra
=
485 bs
.bits
.max_max_transform_hierarchy_depth_intra
;
489 // STRPSs should ideally be here rather than defined individually in
490 // each slice, but the structure isn't completely fixed so for now
492 sps
->num_short_term_ref_pic_sets
= 0;
493 sps
->long_term_ref_pics_present_flag
= 0;
495 sps
->vui_parameters_present_flag
= 1;
497 if (avctx
->sample_aspect_ratio
.num
!= 0 &&
498 avctx
->sample_aspect_ratio
.den
!= 0) {
499 static const AVRational sar_idc
[] = {
501 { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
502 { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
503 { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
504 { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
507 av_reduce(&num
, &den
, avctx
->sample_aspect_ratio
.num
,
508 avctx
->sample_aspect_ratio
.den
, 65535);
509 for (i
= 0; i
< FF_ARRAY_ELEMS(sar_idc
); i
++) {
510 if (num
== sar_idc
[i
].num
&&
511 den
== sar_idc
[i
].den
) {
512 vui
->aspect_ratio_idc
= i
;
516 if (i
>= FF_ARRAY_ELEMS(sar_idc
)) {
517 vui
->aspect_ratio_idc
= 255;
518 vui
->sar_width
= num
;
519 vui
->sar_height
= den
;
521 vui
->aspect_ratio_info_present_flag
= 1;
524 // Unspecified video format, from table E-2.
525 vui
->video_format
= 5;
526 vui
->video_full_range_flag
=
527 avctx
->color_range
== AVCOL_RANGE_JPEG
;
528 vui
->colour_primaries
= avctx
->color_primaries
;
529 vui
->transfer_characteristics
= avctx
->color_trc
;
530 vui
->matrix_coefficients
= avctx
->colorspace
;
531 if (avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
532 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
533 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
)
534 vui
->colour_description_present_flag
= 1;
535 if (avctx
->color_range
!= AVCOL_RANGE_UNSPECIFIED
||
536 vui
->colour_description_present_flag
)
537 vui
->video_signal_type_present_flag
= 1;
539 if (avctx
->chroma_sample_location
!= AVCHROMA_LOC_UNSPECIFIED
) {
540 vui
->chroma_loc_info_present_flag
= 1;
541 vui
->chroma_sample_loc_type_top_field
=
542 vui
->chroma_sample_loc_type_bottom_field
=
543 avctx
->chroma_sample_location
- 1;
546 vui
->vui_timing_info_present_flag
= 1;
547 vui
->vui_num_units_in_tick
= vps
->vps_num_units_in_tick
;
548 vui
->vui_time_scale
= vps
->vps_time_scale
;
549 vui
->vui_poc_proportional_to_timing_flag
= vps
->vps_poc_proportional_to_timing_flag
;
550 vui
->vui_num_ticks_poc_diff_one_minus1
= vps
->vps_num_ticks_poc_diff_one_minus1
;
551 vui
->vui_hrd_parameters_present_flag
= 0;
553 vui
->bitstream_restriction_flag
= 1;
554 vui
->motion_vectors_over_pic_boundaries_flag
= 1;
555 vui
->restricted_ref_pic_lists_flag
= 1;
556 vui
->max_bytes_per_pic_denom
= 0;
557 vui
->max_bits_per_min_cu_denom
= 0;
558 vui
->log2_max_mv_length_horizontal
= 15;
559 vui
->log2_max_mv_length_vertical
= 15;
564 pps
->nal_unit_header
= (H265RawNALUnitHeader
) {
565 .nal_unit_type
= HEVC_NAL_PPS
,
567 .nuh_temporal_id_plus1
= 1,
570 pps
->pps_pic_parameter_set_id
= 0;
571 pps
->pps_seq_parameter_set_id
= sps
->sps_seq_parameter_set_id
;
573 pps
->num_ref_idx_l0_default_active_minus1
= 0;
574 pps
->num_ref_idx_l1_default_active_minus1
= 0;
576 pps
->init_qp_minus26
= priv
->fixed_qp_idr
- 26;
578 pps
->cu_qp_delta_enabled_flag
= (ctx
->va_rc_mode
!= VA_RC_CQP
);
579 pps
->diff_cu_qp_delta_depth
= 0;
581 // update pps setting according to queried result
582 #if VA_CHECK_VERSION(1, 13, 0)
583 if (priv
->va_features
) {
584 VAConfigAttribValEncHEVCFeatures features
= { .value
= priv
->va_features
};
585 if (ctx
->va_rc_mode
!= VA_RC_CQP
)
586 pps
->cu_qp_delta_enabled_flag
=
587 !!features
.bits
.cu_qp_delta
;
589 pps
->transform_skip_enabled_flag
=
590 !!features
.bits
.transform_skip
;
591 // set diff_cu_qp_delta_depth as its max value if cu_qp_delta enabled. Otherwise
592 // 0 will make cu_qp_delta invalid.
593 if (pps
->cu_qp_delta_enabled_flag
)
594 pps
->diff_cu_qp_delta_depth
= sps
->log2_diff_max_min_luma_coding_block_size
;
598 if (ctx
->tile_rows
&& ctx
->tile_cols
) {
601 pps
->tiles_enabled_flag
= 1;
602 pps
->num_tile_columns_minus1
= ctx
->tile_cols
- 1;
603 pps
->num_tile_rows_minus1
= ctx
->tile_rows
- 1;
605 // Test whether the spacing provided matches the H.265 uniform
606 // spacing, and set the flag if it does.
608 for (i
= 0; i
<= pps
->num_tile_columns_minus1
&&
609 uniform_spacing
; i
++) {
610 if (ctx
->col_width
[i
] !=
611 (i
+ 1) * ctx
->slice_block_cols
/ ctx
->tile_cols
-
612 i
* ctx
->slice_block_cols
/ ctx
->tile_cols
)
615 for (i
= 0; i
<= pps
->num_tile_rows_minus1
&&
616 uniform_spacing
; i
++) {
617 if (ctx
->row_height
[i
] !=
618 (i
+ 1) * ctx
->slice_block_rows
/ ctx
->tile_rows
-
619 i
* ctx
->slice_block_rows
/ ctx
->tile_rows
)
622 pps
->uniform_spacing_flag
= uniform_spacing
;
624 for (i
= 0; i
<= pps
->num_tile_columns_minus1
; i
++)
625 pps
->column_width_minus1
[i
] = ctx
->col_width
[i
] - 1;
626 for (i
= 0; i
<= pps
->num_tile_rows_minus1
; i
++)
627 pps
->row_height_minus1
[i
] = ctx
->row_height
[i
] - 1;
629 pps
->loop_filter_across_tiles_enabled_flag
= 1;
632 pps
->pps_loop_filter_across_slices_enabled_flag
= 1;
634 // Fill VAAPI parameter buffers.
636 *vseq
= (VAEncSequenceParameterBufferHEVC
) {
637 .general_profile_idc
= vps
->profile_tier_level
.general_profile_idc
,
638 .general_level_idc
= vps
->profile_tier_level
.general_level_idc
,
639 .general_tier_flag
= vps
->profile_tier_level
.general_tier_flag
,
641 .intra_period
= ctx
->gop_size
,
642 .intra_idr_period
= ctx
->gop_size
,
643 .ip_period
= ctx
->b_per_p
+ 1,
644 .bits_per_second
= ctx
->va_bit_rate
,
646 .pic_width_in_luma_samples
= sps
->pic_width_in_luma_samples
,
647 .pic_height_in_luma_samples
= sps
->pic_height_in_luma_samples
,
650 .chroma_format_idc
= sps
->chroma_format_idc
,
651 .separate_colour_plane_flag
= sps
->separate_colour_plane_flag
,
652 .bit_depth_luma_minus8
= sps
->bit_depth_luma_minus8
,
653 .bit_depth_chroma_minus8
= sps
->bit_depth_chroma_minus8
,
654 .scaling_list_enabled_flag
= sps
->scaling_list_enabled_flag
,
655 .strong_intra_smoothing_enabled_flag
=
656 sps
->strong_intra_smoothing_enabled_flag
,
657 .amp_enabled_flag
= sps
->amp_enabled_flag
,
658 .sample_adaptive_offset_enabled_flag
=
659 sps
->sample_adaptive_offset_enabled_flag
,
660 .pcm_enabled_flag
= sps
->pcm_enabled_flag
,
661 .pcm_loop_filter_disabled_flag
= sps
->pcm_loop_filter_disabled_flag
,
662 .sps_temporal_mvp_enabled_flag
= sps
->sps_temporal_mvp_enabled_flag
,
665 .log2_min_luma_coding_block_size_minus3
=
666 sps
->log2_min_luma_coding_block_size_minus3
,
667 .log2_diff_max_min_luma_coding_block_size
=
668 sps
->log2_diff_max_min_luma_coding_block_size
,
669 .log2_min_transform_block_size_minus2
=
670 sps
->log2_min_luma_transform_block_size_minus2
,
671 .log2_diff_max_min_transform_block_size
=
672 sps
->log2_diff_max_min_luma_transform_block_size
,
673 .max_transform_hierarchy_depth_inter
=
674 sps
->max_transform_hierarchy_depth_inter
,
675 .max_transform_hierarchy_depth_intra
=
676 sps
->max_transform_hierarchy_depth_intra
,
678 .pcm_sample_bit_depth_luma_minus1
=
679 sps
->pcm_sample_bit_depth_luma_minus1
,
680 .pcm_sample_bit_depth_chroma_minus1
=
681 sps
->pcm_sample_bit_depth_chroma_minus1
,
682 .log2_min_pcm_luma_coding_block_size_minus3
=
683 sps
->log2_min_pcm_luma_coding_block_size_minus3
,
684 .log2_max_pcm_luma_coding_block_size_minus3
=
685 sps
->log2_min_pcm_luma_coding_block_size_minus3
+
686 sps
->log2_diff_max_min_pcm_luma_coding_block_size
,
688 .vui_parameters_present_flag
= 0,
691 *vpic
= (VAEncPictureParameterBufferHEVC
) {
692 .decoded_curr_pic
= {
693 .picture_id
= VA_INVALID_ID
,
694 .flags
= VA_PICTURE_HEVC_INVALID
,
697 .coded_buf
= VA_INVALID_ID
,
699 .collocated_ref_pic_index
= sps
->sps_temporal_mvp_enabled_flag
?
703 .pic_init_qp
= pps
->init_qp_minus26
+ 26,
704 .diff_cu_qp_delta_depth
= pps
->diff_cu_qp_delta_depth
,
705 .pps_cb_qp_offset
= pps
->pps_cb_qp_offset
,
706 .pps_cr_qp_offset
= pps
->pps_cr_qp_offset
,
708 .num_tile_columns_minus1
= pps
->num_tile_columns_minus1
,
709 .num_tile_rows_minus1
= pps
->num_tile_rows_minus1
,
711 .log2_parallel_merge_level_minus2
= pps
->log2_parallel_merge_level_minus2
,
712 .ctu_max_bitsize_allowed
= 0,
714 .num_ref_idx_l0_default_active_minus1
=
715 pps
->num_ref_idx_l0_default_active_minus1
,
716 .num_ref_idx_l1_default_active_minus1
=
717 pps
->num_ref_idx_l1_default_active_minus1
,
719 .slice_pic_parameter_set_id
= pps
->pps_pic_parameter_set_id
,
722 .sign_data_hiding_enabled_flag
= pps
->sign_data_hiding_enabled_flag
,
723 .constrained_intra_pred_flag
= pps
->constrained_intra_pred_flag
,
724 .transform_skip_enabled_flag
= pps
->transform_skip_enabled_flag
,
725 .cu_qp_delta_enabled_flag
= pps
->cu_qp_delta_enabled_flag
,
726 .weighted_pred_flag
= pps
->weighted_pred_flag
,
727 .weighted_bipred_flag
= pps
->weighted_bipred_flag
,
728 .transquant_bypass_enabled_flag
= pps
->transquant_bypass_enabled_flag
,
729 .tiles_enabled_flag
= pps
->tiles_enabled_flag
,
730 .entropy_coding_sync_enabled_flag
= pps
->entropy_coding_sync_enabled_flag
,
731 .loop_filter_across_tiles_enabled_flag
=
732 pps
->loop_filter_across_tiles_enabled_flag
,
733 .pps_loop_filter_across_slices_enabled_flag
=
734 pps
->pps_loop_filter_across_slices_enabled_flag
,
735 .scaling_list_data_present_flag
= (sps
->sps_scaling_list_data_present_flag
|
736 pps
->pps_scaling_list_data_present_flag
),
737 .screen_content_flag
= 0,
738 .enable_gpu_weighted_prediction
= 0,
739 .no_output_of_prior_pics_flag
= 0,
743 if (pps
->tiles_enabled_flag
) {
744 for (i
= 0; i
<= vpic
->num_tile_rows_minus1
; i
++)
745 vpic
->row_height_minus1
[i
] = pps
->row_height_minus1
[i
];
746 for (i
= 0; i
<= vpic
->num_tile_columns_minus1
; i
++)
747 vpic
->column_width_minus1
[i
] = pps
->column_width_minus1
[i
];
753 static int vaapi_encode_h265_init_picture_params(AVCodecContext
*avctx
,
754 VAAPIEncodePicture
*pic
)
756 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
757 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
758 VAAPIEncodeH265Picture
*hpic
= pic
->priv_data
;
759 VAAPIEncodePicture
*prev
= pic
->prev
;
760 VAAPIEncodeH265Picture
*hprev
= prev
? prev
->priv_data
: NULL
;
761 VAEncPictureParameterBufferHEVC
*vpic
= pic
->codec_picture_params
;
764 if (pic
->type
== PICTURE_TYPE_IDR
) {
765 av_assert0(pic
->display_order
== pic
->encode_order
);
767 hpic
->last_idr_frame
= pic
->display_order
;
769 hpic
->slice_nal_unit
= HEVC_NAL_IDR_W_RADL
;
770 hpic
->slice_type
= HEVC_SLICE_I
;
774 hpic
->last_idr_frame
= hprev
->last_idr_frame
;
776 if (pic
->type
== PICTURE_TYPE_I
) {
777 hpic
->slice_nal_unit
= HEVC_NAL_CRA_NUT
;
778 hpic
->slice_type
= HEVC_SLICE_I
;
780 } else if (pic
->type
== PICTURE_TYPE_P
) {
781 av_assert0(pic
->refs
[0]);
782 hpic
->slice_nal_unit
= HEVC_NAL_TRAIL_R
;
783 hpic
->slice_type
= HEVC_SLICE_P
;
786 VAAPIEncodePicture
*irap_ref
;
787 av_assert0(pic
->refs
[0] && pic
->refs
[1]);
788 for (irap_ref
= pic
; irap_ref
; irap_ref
= irap_ref
->refs
[1]) {
789 if (irap_ref
->type
== PICTURE_TYPE_I
)
792 if (pic
->b_depth
== ctx
->max_b_depth
) {
793 hpic
->slice_nal_unit
= irap_ref
? HEVC_NAL_RASL_N
796 hpic
->slice_nal_unit
= irap_ref
? HEVC_NAL_RASL_R
799 hpic
->slice_type
= HEVC_SLICE_B
;
803 hpic
->pic_order_cnt
= pic
->display_order
- hpic
->last_idr_frame
;
806 priv
->aud_needed
= 1;
807 priv
->raw_aud
= (H265RawAUD
) {
809 .nal_unit_type
= HEVC_NAL_AUD
,
811 .nuh_temporal_id_plus1
= 1,
813 .pic_type
= hpic
->pic_type
,
816 priv
->aud_needed
= 0;
819 priv
->sei_needed
= 0;
821 // Only look for the metadata on I/IDR frame on the output. We
822 // may force an IDR frame on the output where the medadata gets
823 // changed on the input frame.
824 if ((priv
->sei
& SEI_MASTERING_DISPLAY
) &&
825 (pic
->type
== PICTURE_TYPE_I
|| pic
->type
== PICTURE_TYPE_IDR
)) {
826 AVFrameSideData
*sd
=
827 av_frame_get_side_data(pic
->input_image
,
828 AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
);
831 AVMasteringDisplayMetadata
*mdm
=
832 (AVMasteringDisplayMetadata
*)sd
->data
;
834 // SEI is needed when both the primaries and luminance are set
835 if (mdm
->has_primaries
&& mdm
->has_luminance
) {
836 SEIRawMasteringDisplayColourVolume
*mdcv
=
837 &priv
->sei_mastering_display
;
838 const int mapping
[3] = {1, 2, 0};
839 const int chroma_den
= 50000;
840 const int luma_den
= 10000;
842 for (i
= 0; i
< 3; i
++) {
843 const int j
= mapping
[i
];
844 mdcv
->display_primaries_x
[i
] =
845 FFMIN(lrint(chroma_den
*
846 av_q2d(mdm
->display_primaries
[j
][0])),
848 mdcv
->display_primaries_y
[i
] =
849 FFMIN(lrint(chroma_den
*
850 av_q2d(mdm
->display_primaries
[j
][1])),
854 mdcv
->white_point_x
=
855 FFMIN(lrint(chroma_den
* av_q2d(mdm
->white_point
[0])),
857 mdcv
->white_point_y
=
858 FFMIN(lrint(chroma_den
* av_q2d(mdm
->white_point
[1])),
861 mdcv
->max_display_mastering_luminance
=
862 lrint(luma_den
* av_q2d(mdm
->max_luminance
));
863 mdcv
->min_display_mastering_luminance
=
864 FFMIN(lrint(luma_den
* av_q2d(mdm
->min_luminance
)),
865 mdcv
->max_display_mastering_luminance
);
867 priv
->sei_needed
|= SEI_MASTERING_DISPLAY
;
872 if ((priv
->sei
& SEI_CONTENT_LIGHT_LEVEL
) &&
873 (pic
->type
== PICTURE_TYPE_I
|| pic
->type
== PICTURE_TYPE_IDR
)) {
874 AVFrameSideData
*sd
=
875 av_frame_get_side_data(pic
->input_image
,
876 AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
);
879 AVContentLightMetadata
*clm
=
880 (AVContentLightMetadata
*)sd
->data
;
881 SEIRawContentLightLevelInfo
*clli
=
882 &priv
->sei_content_light_level
;
884 clli
->max_content_light_level
= FFMIN(clm
->MaxCLL
, 65535);
885 clli
->max_pic_average_light_level
= FFMIN(clm
->MaxFALL
, 65535);
887 priv
->sei_needed
|= SEI_CONTENT_LIGHT_LEVEL
;
891 vpic
->decoded_curr_pic
= (VAPictureHEVC
) {
892 .picture_id
= pic
->recon_surface
,
893 .pic_order_cnt
= hpic
->pic_order_cnt
,
897 for (i
= 0; i
< pic
->nb_refs
; i
++) {
898 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
899 VAAPIEncodeH265Picture
*href
;
901 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
902 href
= ref
->priv_data
;
904 vpic
->reference_frames
[i
] = (VAPictureHEVC
) {
905 .picture_id
= ref
->recon_surface
,
906 .pic_order_cnt
= href
->pic_order_cnt
,
907 .flags
= (ref
->display_order
< pic
->display_order
?
908 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE
: 0) |
909 (ref
->display_order
> pic
->display_order
?
910 VA_PICTURE_HEVC_RPS_ST_CURR_AFTER
: 0),
913 for (; i
< FF_ARRAY_ELEMS(vpic
->reference_frames
); i
++) {
914 vpic
->reference_frames
[i
] = (VAPictureHEVC
) {
915 .picture_id
= VA_INVALID_ID
,
916 .flags
= VA_PICTURE_HEVC_INVALID
,
920 vpic
->coded_buf
= pic
->output_buffer
;
922 vpic
->nal_unit_type
= hpic
->slice_nal_unit
;
925 case PICTURE_TYPE_IDR
:
926 vpic
->pic_fields
.bits
.idr_pic_flag
= 1;
927 vpic
->pic_fields
.bits
.coding_type
= 1;
928 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
931 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
932 vpic
->pic_fields
.bits
.coding_type
= 1;
933 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
936 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
937 vpic
->pic_fields
.bits
.coding_type
= 2;
938 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
941 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
942 vpic
->pic_fields
.bits
.coding_type
= 3;
943 vpic
->pic_fields
.bits
.reference_pic_flag
= 0;
946 av_assert0(0 && "invalid picture type");
952 static int vaapi_encode_h265_init_slice_params(AVCodecContext
*avctx
,
953 VAAPIEncodePicture
*pic
,
954 VAAPIEncodeSlice
*slice
)
956 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
957 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
958 VAAPIEncodeH265Picture
*hpic
= pic
->priv_data
;
959 const H265RawSPS
*sps
= &priv
->raw_sps
;
960 const H265RawPPS
*pps
= &priv
->raw_pps
;
961 H265RawSliceHeader
*sh
= &priv
->raw_slice
.header
;
962 VAEncPictureParameterBufferHEVC
*vpic
= pic
->codec_picture_params
;
963 VAEncSliceParameterBufferHEVC
*vslice
= slice
->codec_slice_params
;
966 sh
->nal_unit_header
= (H265RawNALUnitHeader
) {
967 .nal_unit_type
= hpic
->slice_nal_unit
,
969 .nuh_temporal_id_plus1
= 1,
972 sh
->slice_pic_parameter_set_id
= pps
->pps_pic_parameter_set_id
;
974 sh
->first_slice_segment_in_pic_flag
= slice
->index
== 0;
975 sh
->slice_segment_address
= slice
->block_start
;
977 sh
->slice_type
= hpic
->slice_type
;
979 if (sh
->slice_type
== HEVC_SLICE_P
&& ctx
->p_to_gpb
)
980 sh
->slice_type
= HEVC_SLICE_B
;
982 sh
->slice_pic_order_cnt_lsb
= hpic
->pic_order_cnt
&
983 (1 << (sps
->log2_max_pic_order_cnt_lsb_minus4
+ 4)) - 1;
985 if (pic
->type
!= PICTURE_TYPE_IDR
) {
986 H265RawSTRefPicSet
*rps
;
987 const VAAPIEncodeH265Picture
*strp
;
988 int rps_poc
[MAX_DPB_SIZE
];
989 int rps_used
[MAX_DPB_SIZE
];
990 int i
, j
, poc
, rps_pics
;
992 sh
->short_term_ref_pic_set_sps_flag
= 0;
994 rps
= &sh
->short_term_ref_pic_set
;
995 memset(rps
, 0, sizeof(*rps
));
998 for (i
= 0; i
< pic
->nb_refs
; i
++) {
999 strp
= pic
->refs
[i
]->priv_data
;
1000 rps_poc
[rps_pics
] = strp
->pic_order_cnt
;
1001 rps_used
[rps_pics
] = 1;
1004 for (i
= 0; i
< pic
->nb_dpb_pics
; i
++) {
1005 if (pic
->dpb
[i
] == pic
)
1007 for (j
= 0; j
< pic
->nb_refs
; j
++) {
1008 if (pic
->dpb
[i
] == pic
->refs
[j
])
1011 if (j
< pic
->nb_refs
)
1013 strp
= pic
->dpb
[i
]->priv_data
;
1014 rps_poc
[rps_pics
] = strp
->pic_order_cnt
;
1015 rps_used
[rps_pics
] = 0;
1019 for (i
= 1; i
< rps_pics
; i
++) {
1020 for (j
= i
; j
> 0; j
--) {
1021 if (rps_poc
[j
] > rps_poc
[j
- 1])
1023 av_assert0(rps_poc
[j
] != rps_poc
[j
- 1]);
1024 FFSWAP(int, rps_poc
[j
], rps_poc
[j
- 1]);
1025 FFSWAP(int, rps_used
[j
], rps_used
[j
- 1]);
1029 av_log(avctx
, AV_LOG_DEBUG
, "RPS for POC %d:",
1030 hpic
->pic_order_cnt
);
1031 for (i
= 0; i
< rps_pics
; i
++) {
1032 av_log(avctx
, AV_LOG_DEBUG
, " (%d,%d)",
1033 rps_poc
[i
], rps_used
[i
]);
1035 av_log(avctx
, AV_LOG_DEBUG
, "\n");
1037 for (i
= 0; i
< rps_pics
; i
++) {
1038 av_assert0(rps_poc
[i
] != hpic
->pic_order_cnt
);
1039 if (rps_poc
[i
] > hpic
->pic_order_cnt
)
1043 rps
->num_negative_pics
= i
;
1044 poc
= hpic
->pic_order_cnt
;
1045 for (j
= i
- 1; j
>= 0; j
--) {
1046 rps
->delta_poc_s0_minus1
[i
- 1 - j
] = poc
- rps_poc
[j
] - 1;
1047 rps
->used_by_curr_pic_s0_flag
[i
- 1 - j
] = rps_used
[j
];
1051 rps
->num_positive_pics
= rps_pics
- i
;
1052 poc
= hpic
->pic_order_cnt
;
1053 for (j
= i
; j
< rps_pics
; j
++) {
1054 rps
->delta_poc_s1_minus1
[j
- i
] = rps_poc
[j
] - poc
- 1;
1055 rps
->used_by_curr_pic_s1_flag
[j
- i
] = rps_used
[j
];
1059 sh
->num_long_term_sps
= 0;
1060 sh
->num_long_term_pics
= 0;
1062 // when this flag is not present, it is inerred to 1.
1063 sh
->collocated_from_l0_flag
= 1;
1064 sh
->slice_temporal_mvp_enabled_flag
=
1065 sps
->sps_temporal_mvp_enabled_flag
;
1066 if (sh
->slice_temporal_mvp_enabled_flag
) {
1067 if (sh
->slice_type
== HEVC_SLICE_B
)
1068 sh
->collocated_from_l0_flag
= 1;
1069 sh
->collocated_ref_idx
= 0;
1072 sh
->num_ref_idx_active_override_flag
= 0;
1073 sh
->num_ref_idx_l0_active_minus1
= pps
->num_ref_idx_l0_default_active_minus1
;
1074 sh
->num_ref_idx_l1_active_minus1
= pps
->num_ref_idx_l1_default_active_minus1
;
1077 sh
->slice_sao_luma_flag
= sh
->slice_sao_chroma_flag
=
1078 sps
->sample_adaptive_offset_enabled_flag
;
1080 if (pic
->type
== PICTURE_TYPE_B
)
1081 sh
->slice_qp_delta
= priv
->fixed_qp_b
- (pps
->init_qp_minus26
+ 26);
1082 else if (pic
->type
== PICTURE_TYPE_P
)
1083 sh
->slice_qp_delta
= priv
->fixed_qp_p
- (pps
->init_qp_minus26
+ 26);
1085 sh
->slice_qp_delta
= priv
->fixed_qp_idr
- (pps
->init_qp_minus26
+ 26);
1088 *vslice
= (VAEncSliceParameterBufferHEVC
) {
1089 .slice_segment_address
= sh
->slice_segment_address
,
1090 .num_ctu_in_slice
= slice
->block_size
,
1092 .slice_type
= sh
->slice_type
,
1093 .slice_pic_parameter_set_id
= sh
->slice_pic_parameter_set_id
,
1095 .num_ref_idx_l0_active_minus1
= sh
->num_ref_idx_l0_active_minus1
,
1096 .num_ref_idx_l1_active_minus1
= sh
->num_ref_idx_l1_active_minus1
,
1098 .luma_log2_weight_denom
= sh
->luma_log2_weight_denom
,
1099 .delta_chroma_log2_weight_denom
= sh
->delta_chroma_log2_weight_denom
,
1101 .max_num_merge_cand
= 5 - sh
->five_minus_max_num_merge_cand
,
1103 .slice_qp_delta
= sh
->slice_qp_delta
,
1104 .slice_cb_qp_offset
= sh
->slice_cb_qp_offset
,
1105 .slice_cr_qp_offset
= sh
->slice_cr_qp_offset
,
1107 .slice_beta_offset_div2
= sh
->slice_beta_offset_div2
,
1108 .slice_tc_offset_div2
= sh
->slice_tc_offset_div2
,
1110 .slice_fields
.bits
= {
1111 .last_slice_of_pic_flag
= slice
->index
== pic
->nb_slices
- 1,
1112 .dependent_slice_segment_flag
= sh
->dependent_slice_segment_flag
,
1113 .colour_plane_id
= sh
->colour_plane_id
,
1114 .slice_temporal_mvp_enabled_flag
=
1115 sh
->slice_temporal_mvp_enabled_flag
,
1116 .slice_sao_luma_flag
= sh
->slice_sao_luma_flag
,
1117 .slice_sao_chroma_flag
= sh
->slice_sao_chroma_flag
,
1118 .num_ref_idx_active_override_flag
=
1119 sh
->num_ref_idx_active_override_flag
,
1120 .mvd_l1_zero_flag
= sh
->mvd_l1_zero_flag
,
1121 .cabac_init_flag
= sh
->cabac_init_flag
,
1122 .slice_deblocking_filter_disabled_flag
=
1123 sh
->slice_deblocking_filter_disabled_flag
,
1124 .slice_loop_filter_across_slices_enabled_flag
=
1125 sh
->slice_loop_filter_across_slices_enabled_flag
,
1126 .collocated_from_l0_flag
= sh
->collocated_from_l0_flag
,
1130 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->ref_pic_list0
); i
++) {
1131 vslice
->ref_pic_list0
[i
].picture_id
= VA_INVALID_ID
;
1132 vslice
->ref_pic_list0
[i
].flags
= VA_PICTURE_HEVC_INVALID
;
1133 vslice
->ref_pic_list1
[i
].picture_id
= VA_INVALID_ID
;
1134 vslice
->ref_pic_list1
[i
].flags
= VA_PICTURE_HEVC_INVALID
;
1137 av_assert0(pic
->nb_refs
<= 2);
1138 if (pic
->nb_refs
>= 1) {
1139 // Backward reference for P- or B-frame.
1140 av_assert0(pic
->type
== PICTURE_TYPE_P
||
1141 pic
->type
== PICTURE_TYPE_B
);
1142 vslice
->ref_pic_list0
[0] = vpic
->reference_frames
[0];
1143 if (ctx
->p_to_gpb
&& pic
->type
== PICTURE_TYPE_P
)
1144 // Reference for GPB B-frame, L0 == L1
1145 vslice
->ref_pic_list1
[0] = vpic
->reference_frames
[0];
1147 if (pic
->nb_refs
>= 2) {
1148 // Forward reference for B-frame.
1149 av_assert0(pic
->type
== PICTURE_TYPE_B
);
1150 vslice
->ref_pic_list1
[0] = vpic
->reference_frames
[1];
1153 if (pic
->type
== PICTURE_TYPE_P
&& ctx
->p_to_gpb
) {
1154 vslice
->slice_type
= HEVC_SLICE_B
;
1155 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->ref_pic_list0
); i
++) {
1156 vslice
->ref_pic_list1
[i
].picture_id
= vslice
->ref_pic_list0
[i
].picture_id
;
1157 vslice
->ref_pic_list1
[i
].flags
= vslice
->ref_pic_list0
[i
].flags
;
1164 static av_cold
int vaapi_encode_h265_get_encoder_caps(AVCodecContext
*avctx
)
1166 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1167 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
1169 #if VA_CHECK_VERSION(1, 13, 0)
1171 VAConfigAttribValEncHEVCBlockSizes block_size
;
1172 VAConfigAttrib attr
;
1175 attr
.type
= VAConfigAttribEncHEVCFeatures
;
1176 vas
= vaGetConfigAttributes(ctx
->hwctx
->display
, ctx
->va_profile
,
1177 ctx
->va_entrypoint
, &attr
, 1);
1178 if (vas
!= VA_STATUS_SUCCESS
) {
1179 av_log(avctx
, AV_LOG_ERROR
, "Failed to query encoder "
1180 "features, using guessed defaults.\n");
1181 return AVERROR_EXTERNAL
;
1182 } else if (attr
.value
== VA_ATTRIB_NOT_SUPPORTED
) {
1183 av_log(avctx
, AV_LOG_WARNING
, "Driver does not advertise "
1184 "encoder features, using guessed defaults.\n");
1186 priv
->va_features
= attr
.value
;
1189 attr
.type
= VAConfigAttribEncHEVCBlockSizes
;
1190 vas
= vaGetConfigAttributes(ctx
->hwctx
->display
, ctx
->va_profile
,
1191 ctx
->va_entrypoint
, &attr
, 1);
1192 if (vas
!= VA_STATUS_SUCCESS
) {
1193 av_log(avctx
, AV_LOG_ERROR
, "Failed to query encoder "
1194 "block size, using guessed defaults.\n");
1195 return AVERROR_EXTERNAL
;
1196 } else if (attr
.value
== VA_ATTRIB_NOT_SUPPORTED
) {
1197 av_log(avctx
, AV_LOG_WARNING
, "Driver does not advertise "
1198 "encoder block size, using guessed defaults.\n");
1200 priv
->va_bs
= block_size
.value
= attr
.value
;
1203 1 << block_size
.bits
.log2_max_coding_tree_block_size_minus3
+ 3;
1205 1 << block_size
.bits
.log2_min_luma_coding_block_size_minus3
+ 3;
1210 if (!priv
->ctu_size
) {
1211 priv
->ctu_size
= 32;
1212 priv
->min_cb_size
= 16;
1214 av_log(avctx
, AV_LOG_VERBOSE
, "Using CTU size %dx%d, "
1215 "min CB size %dx%d.\n", priv
->ctu_size
, priv
->ctu_size
,
1216 priv
->min_cb_size
, priv
->min_cb_size
);
1218 ctx
->surface_width
= FFALIGN(avctx
->width
, priv
->min_cb_size
);
1219 ctx
->surface_height
= FFALIGN(avctx
->height
, priv
->min_cb_size
);
1221 ctx
->slice_block_width
= ctx
->slice_block_height
= priv
->ctu_size
;
1226 static av_cold
int vaapi_encode_h265_configure(AVCodecContext
*avctx
)
1228 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1229 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
1232 err
= ff_cbs_init(&priv
->cbc
, AV_CODEC_ID_HEVC
, avctx
);
1236 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
1237 // Note that VAAPI only supports positive QP values - the range is
1238 // therefore always bounded below by 1, even in 10-bit mode where
1239 // it should go down to -12.
1241 priv
->fixed_qp_p
= av_clip(ctx
->rc_quality
, 1, 51);
1242 if (avctx
->i_quant_factor
> 0.0)
1243 priv
->fixed_qp_idr
=
1244 av_clip((avctx
->i_quant_factor
* priv
->fixed_qp_p
+
1245 avctx
->i_quant_offset
) + 0.5, 1, 51);
1247 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
1248 if (avctx
->b_quant_factor
> 0.0)
1250 av_clip((avctx
->b_quant_factor
* priv
->fixed_qp_p
+
1251 avctx
->b_quant_offset
) + 0.5, 1, 51);
1253 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
1255 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
1256 "%d / %d / %d for IDR- / P- / B-frames.\n",
1257 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
1260 // These still need to be set for init_qp/slice_qp_delta.
1261 priv
->fixed_qp_idr
= 30;
1262 priv
->fixed_qp_p
= 30;
1263 priv
->fixed_qp_b
= 30;
1266 ctx
->roi_quant_range
= 51 + 6 * (ctx
->profile
->depth
- 8);
1271 static const VAAPIEncodeProfile vaapi_encode_h265_profiles
[] = {
1272 { FF_PROFILE_HEVC_MAIN
, 8, 3, 1, 1, VAProfileHEVCMain
},
1273 { FF_PROFILE_HEVC_REXT
, 8, 3, 1, 1, VAProfileHEVCMain
},
1274 #if VA_CHECK_VERSION(0, 37, 0)
1275 { FF_PROFILE_HEVC_MAIN_10
, 10, 3, 1, 1, VAProfileHEVCMain10
},
1276 { FF_PROFILE_HEVC_REXT
, 10, 3, 1, 1, VAProfileHEVCMain10
},
1278 #if VA_CHECK_VERSION(1, 2, 0)
1279 { FF_PROFILE_HEVC_REXT
, 8, 3, 1, 0, VAProfileHEVCMain422_10
},
1280 { FF_PROFILE_HEVC_REXT
, 10, 3, 1, 0, VAProfileHEVCMain422_10
},
1282 { FF_PROFILE_UNKNOWN
}
1285 static const VAAPIEncodeType vaapi_encode_type_h265
= {
1286 .profiles
= vaapi_encode_h265_profiles
,
1288 .flags
= FLAG_SLICE_CONTROL
|
1290 FLAG_B_PICTURE_REFERENCES
|
1291 FLAG_NON_IDR_KEY_PICTURES
,
1293 .default_quality
= 25,
1295 .get_encoder_caps
= &vaapi_encode_h265_get_encoder_caps
,
1296 .configure
= &vaapi_encode_h265_configure
,
1298 .picture_priv_data_size
= sizeof(VAAPIEncodeH265Picture
),
1300 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferHEVC
),
1301 .init_sequence_params
= &vaapi_encode_h265_init_sequence_params
,
1303 .picture_params_size
= sizeof(VAEncPictureParameterBufferHEVC
),
1304 .init_picture_params
= &vaapi_encode_h265_init_picture_params
,
1306 .slice_params_size
= sizeof(VAEncSliceParameterBufferHEVC
),
1307 .init_slice_params
= &vaapi_encode_h265_init_slice_params
,
1309 .sequence_header_type
= VAEncPackedHeaderSequence
,
1310 .write_sequence_header
= &vaapi_encode_h265_write_sequence_header
,
1312 .slice_header_type
= VAEncPackedHeaderHEVC_Slice
,
1313 .write_slice_header
= &vaapi_encode_h265_write_slice_header
,
1315 .write_extra_header
= &vaapi_encode_h265_write_extra_header
,
1318 static av_cold
int vaapi_encode_h265_init(AVCodecContext
*avctx
)
1320 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
1321 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
1323 ctx
->codec
= &vaapi_encode_type_h265
;
1325 if (avctx
->profile
== FF_PROFILE_UNKNOWN
)
1326 avctx
->profile
= priv
->profile
;
1327 if (avctx
->level
== FF_LEVEL_UNKNOWN
)
1328 avctx
->level
= priv
->level
;
1330 if (avctx
->level
!= FF_LEVEL_UNKNOWN
&& avctx
->level
& ~0xff) {
1331 av_log(avctx
, AV_LOG_ERROR
, "Invalid level %d: must fit "
1332 "in 8-bit unsigned integer.\n", avctx
->level
);
1333 return AVERROR(EINVAL
);
1336 ctx
->desired_packed_headers
=
1337 VA_ENC_PACKED_HEADER_SEQUENCE
| // VPS, SPS and PPS.
1338 VA_ENC_PACKED_HEADER_SLICE
| // Slice headers.
1339 VA_ENC_PACKED_HEADER_MISC
; // SEI
1342 ctx
->explicit_qp
= priv
->qp
;
1344 return ff_vaapi_encode_init(avctx
);
1347 static av_cold
int vaapi_encode_h265_close(AVCodecContext
*avctx
)
1349 VAAPIEncodeH265Context
*priv
= avctx
->priv_data
;
1351 ff_cbs_fragment_free(&priv
->current_access_unit
);
1352 ff_cbs_close(&priv
->cbc
);
1354 return ff_vaapi_encode_close(avctx
);
1357 #define OFFSET(x) offsetof(VAAPIEncodeH265Context, x)
1358 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
1359 static const AVOption vaapi_encode_h265_options
[] = {
1360 VAAPI_ENCODE_COMMON_OPTIONS
,
1361 VAAPI_ENCODE_RC_OPTIONS
,
1363 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
1364 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 52, FLAGS
},
1366 { "aud", "Include AUD",
1367 OFFSET(aud
), AV_OPT_TYPE_BOOL
, { .i64
= 0 }, 0, 1, FLAGS
},
1369 { "profile", "Set profile (general_profile_idc)",
1370 OFFSET(profile
), AV_OPT_TYPE_INT
,
1371 { .i64
= FF_PROFILE_UNKNOWN
}, FF_PROFILE_UNKNOWN
, 0xff, FLAGS
, "profile" },
1373 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1374 { .i64 = value }, 0, 0, FLAGS, "profile"
1375 { PROFILE("main", FF_PROFILE_HEVC_MAIN
) },
1376 { PROFILE("main10", FF_PROFILE_HEVC_MAIN_10
) },
1377 { PROFILE("rext", FF_PROFILE_HEVC_REXT
) },
1380 { "tier", "Set tier (general_tier_flag)",
1381 OFFSET(tier
), AV_OPT_TYPE_INT
,
1382 { .i64
= 0 }, 0, 1, FLAGS
, "tier" },
1383 { "main", NULL
, 0, AV_OPT_TYPE_CONST
,
1384 { .i64
= 0 }, 0, 0, FLAGS
, "tier" },
1385 { "high", NULL
, 0, AV_OPT_TYPE_CONST
,
1386 { .i64
= 1 }, 0, 0, FLAGS
, "tier" },
1388 { "level", "Set level (general_level_idc)",
1389 OFFSET(level
), AV_OPT_TYPE_INT
,
1390 { .i64
= FF_LEVEL_UNKNOWN
}, FF_LEVEL_UNKNOWN
, 0xff, FLAGS
, "level" },
1392 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
1393 { .i64 = value }, 0, 0, FLAGS, "level"
1396 { LEVEL("2.1", 63) },
1398 { LEVEL("3.1", 93) },
1399 { LEVEL("4", 120) },
1400 { LEVEL("4.1", 123) },
1401 { LEVEL("5", 150) },
1402 { LEVEL("5.1", 153) },
1403 { LEVEL("5.2", 156) },
1404 { LEVEL("6", 180) },
1405 { LEVEL("6.1", 183) },
1406 { LEVEL("6.2", 186) },
1409 { "sei", "Set SEI to include",
1410 OFFSET(sei
), AV_OPT_TYPE_FLAGS
,
1411 { .i64
= SEI_MASTERING_DISPLAY
| SEI_CONTENT_LIGHT_LEVEL
},
1412 0, INT_MAX
, FLAGS
, "sei" },
1414 "Include HDR metadata for mastering display colour volume "
1415 "and content light level information",
1416 0, AV_OPT_TYPE_CONST
,
1417 { .i64
= SEI_MASTERING_DISPLAY
| SEI_CONTENT_LIGHT_LEVEL
},
1418 INT_MIN
, INT_MAX
, FLAGS
, "sei" },
1420 { "tiles", "Tile columns x rows",
1421 OFFSET(common
.tile_cols
), AV_OPT_TYPE_IMAGE_SIZE
,
1422 { .str
= NULL
}, 0, 0, FLAGS
},
1427 static const FFCodecDefault vaapi_encode_h265_defaults
[] = {
1431 { "i_qfactor", "1" },
1432 { "i_qoffset", "0" },
1433 { "b_qfactor", "6/5" },
1434 { "b_qoffset", "0" },
1440 static const AVClass vaapi_encode_h265_class
= {
1441 .class_name
= "h265_vaapi",
1442 .item_name
= av_default_item_name
,
1443 .option
= vaapi_encode_h265_options
,
1444 .version
= LIBAVUTIL_VERSION_INT
,
1447 const FFCodec ff_hevc_vaapi_encoder
= {
1448 .p
.name
= "hevc_vaapi",
1449 .p
.long_name
= NULL_IF_CONFIG_SMALL("H.265/HEVC (VAAPI)"),
1450 .p
.type
= AVMEDIA_TYPE_VIDEO
,
1451 .p
.id
= AV_CODEC_ID_HEVC
,
1452 .priv_data_size
= sizeof(VAAPIEncodeH265Context
),
1453 .init
= &vaapi_encode_h265_init
,
1454 FF_CODEC_RECEIVE_PACKET_CB(&ff_vaapi_encode_receive_packet
),
1455 .close
= &vaapi_encode_h265_close
,
1456 .p
.priv_class
= &vaapi_encode_h265_class
,
1457 .p
.capabilities
= AV_CODEC_CAP_DELAY
| AV_CODEC_CAP_HARDWARE
|
1459 .caps_internal
= FF_CODEC_CAP_INIT_CLEANUP
,
1460 .defaults
= vaapi_encode_h265_defaults
,
1461 .p
.pix_fmts
= (const enum AVPixelFormat
[]) {
1465 .hw_configs
= ff_vaapi_encode_hw_configs
,
1466 .p
.wrapper_name
= "vaapi",