2 * This file is part of Libav.
4 * Libav is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * Libav is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with Libav; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <va/va_enc_hevc.h>
24 #include "libavutil/avassert.h"
25 #include "libavutil/common.h"
26 #include "libavutil/opt.h"
34 #include "vaapi_encode.h"
37 typedef struct VAAPIEncodeH265Context
{
38 unsigned int ctu_width
;
39 unsigned int ctu_height
;
51 int64_t last_idr_frame
;
58 CodedBitstreamContext
*cbc
;
59 CodedBitstreamFragment current_access_unit
;
61 } VAAPIEncodeH265Context
;
63 typedef struct VAAPIEncodeH265Options
{
68 } VAAPIEncodeH265Options
;
71 static int vaapi_encode_h265_write_access_unit(AVCodecContext
*avctx
,
72 char *data
, size_t *data_len
,
73 CodedBitstreamFragment
*au
)
75 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
76 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
79 err
= ff_cbs_write_fragment_data(priv
->cbc
, au
);
81 av_log(avctx
, AV_LOG_ERROR
, "Failed to write packed header.\n");
85 if (*data_len
< 8 * au
->data_size
- au
->data_bit_padding
) {
86 av_log(avctx
, AV_LOG_ERROR
, "Access unit too large: "
87 "%zu < %zu.\n", *data_len
,
88 8 * au
->data_size
- au
->data_bit_padding
);
89 return AVERROR(ENOSPC
);
92 memcpy(data
, au
->data
, au
->data_size
);
93 *data_len
= 8 * au
->data_size
- au
->data_bit_padding
;
98 static int vaapi_encode_h265_add_nal(AVCodecContext
*avctx
,
99 CodedBitstreamFragment
*au
,
102 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
103 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
104 H265RawNALUnitHeader
*header
= nal_unit
;
107 err
= ff_cbs_insert_unit_content(priv
->cbc
, au
, -1,
108 header
->nal_unit_type
, nal_unit
, NULL
);
110 av_log(avctx
, AV_LOG_ERROR
, "Failed to add NAL unit: "
111 "type = %d.\n", header
->nal_unit_type
);
118 static int vaapi_encode_h265_write_sequence_header(AVCodecContext
*avctx
,
119 char *data
, size_t *data_len
)
121 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
122 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
123 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
126 if (priv
->aud_needed
) {
127 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->aud
);
130 priv
->aud_needed
= 0;
133 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->vps
);
137 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->sps
);
141 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->pps
);
145 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
147 ff_cbs_fragment_uninit(priv
->cbc
, au
);
151 static int vaapi_encode_h265_write_slice_header(AVCodecContext
*avctx
,
152 VAAPIEncodePicture
*pic
,
153 VAAPIEncodeSlice
*slice
,
154 char *data
, size_t *data_len
)
156 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
157 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
158 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
161 if (priv
->aud_needed
) {
162 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->aud
);
165 priv
->aud_needed
= 0;
168 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->slice
);
172 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
174 ff_cbs_fragment_uninit(priv
->cbc
, au
);
178 static int vaapi_encode_h265_init_sequence_params(AVCodecContext
*avctx
)
180 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
181 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
182 H265RawVPS
*vps
= &priv
->vps
;
183 H265RawSPS
*sps
= &priv
->sps
;
184 H265RawPPS
*pps
= &priv
->pps
;
185 H265RawVUI
*vui
= &sps
->vui
;
186 VAEncSequenceParameterBufferHEVC
*vseq
= ctx
->codec_sequence_params
;
187 VAEncPictureParameterBufferHEVC
*vpic
= ctx
->codec_picture_params
;
190 memset(&priv
->current_access_unit
, 0,
191 sizeof(priv
->current_access_unit
));
193 memset(vps
, 0, sizeof(*vps
));
194 memset(sps
, 0, sizeof(*sps
));
195 memset(pps
, 0, sizeof(*pps
));
200 vps
->nal_unit_header
= (H265RawNALUnitHeader
) {
201 .nal_unit_type
= HEVC_NAL_VPS
,
203 .nuh_temporal_id_plus1
= 1,
206 vps
->vps_video_parameter_set_id
= 0;
208 vps
->vps_base_layer_internal_flag
= 1;
209 vps
->vps_base_layer_available_flag
= 1;
210 vps
->vps_max_layers_minus1
= 0;
211 vps
->vps_max_sub_layers_minus1
= 0;
212 vps
->vps_temporal_id_nesting_flag
= 1;
214 vps
->profile_tier_level
= (H265RawProfileTierLevel
) {
215 .general_profile_space
= 0,
216 .general_profile_idc
= avctx
->profile
,
217 .general_tier_flag
= 0,
219 .general_progressive_source_flag
= 1,
220 .general_interlaced_source_flag
= 0,
221 .general_non_packed_constraint_flag
= 1,
222 .general_frame_only_constraint_flag
= 1,
224 .general_level_idc
= avctx
->level
,
226 vps
->profile_tier_level
.general_profile_compatibility_flag
[avctx
->profile
& 31] = 1;
228 vps
->vps_sub_layer_ordering_info_present_flag
= 0;
229 vps
->vps_max_dec_pic_buffering_minus1
[0] = (ctx
->b_per_p
> 0) + 1;
230 vps
->vps_max_num_reorder_pics
[0] = (ctx
->b_per_p
> 0);
231 vps
->vps_max_latency_increase_plus1
[0] = 0;
233 vps
->vps_max_layer_id
= 0;
234 vps
->vps_num_layer_sets_minus1
= 0;
235 vps
->layer_id_included_flag
[0][0] = 1;
237 vps
->vps_timing_info_present_flag
= 1;
238 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
239 vps
->vps_num_units_in_tick
= avctx
->framerate
.den
;
240 vps
->vps_time_scale
= avctx
->framerate
.num
;
241 vps
->vps_poc_proportional_to_timing_flag
= 1;
242 vps
->vps_num_ticks_poc_diff_one_minus1
= 0;
244 vps
->vps_num_units_in_tick
= avctx
->time_base
.num
;
245 vps
->vps_time_scale
= avctx
->time_base
.den
;
246 vps
->vps_poc_proportional_to_timing_flag
= 0;
248 vps
->vps_num_hrd_parameters
= 0;
253 sps
->nal_unit_header
= (H265RawNALUnitHeader
) {
254 .nal_unit_type
= HEVC_NAL_SPS
,
256 .nuh_temporal_id_plus1
= 1,
259 sps
->sps_video_parameter_set_id
= vps
->vps_video_parameter_set_id
;
261 sps
->sps_max_sub_layers_minus1
= vps
->vps_max_sub_layers_minus1
;
262 sps
->sps_temporal_id_nesting_flag
= vps
->vps_temporal_id_nesting_flag
;
264 sps
->profile_tier_level
= vps
->profile_tier_level
;
266 sps
->sps_seq_parameter_set_id
= 0;
268 sps
->chroma_format_idc
= 1; // YUV 4:2:0.
269 sps
->separate_colour_plane_flag
= 0;
271 sps
->pic_width_in_luma_samples
= ctx
->surface_width
;
272 sps
->pic_height_in_luma_samples
= ctx
->surface_height
;
274 if (avctx
->width
!= ctx
->surface_width
||
275 avctx
->height
!= ctx
->surface_height
) {
276 sps
->conformance_window_flag
= 1;
277 sps
->conf_win_left_offset
= 0;
278 sps
->conf_win_right_offset
=
279 (ctx
->surface_width
- avctx
->width
) / 2;
280 sps
->conf_win_top_offset
= 0;
281 sps
->conf_win_bottom_offset
=
282 (ctx
->surface_height
- avctx
->height
) / 2;
284 sps
->conformance_window_flag
= 0;
287 sps
->bit_depth_luma_minus8
=
288 avctx
->profile
== FF_PROFILE_HEVC_MAIN_10
? 2 : 0;
289 sps
->bit_depth_chroma_minus8
= sps
->bit_depth_luma_minus8
;
291 sps
->log2_max_pic_order_cnt_lsb_minus4
= 8;
293 sps
->sps_sub_layer_ordering_info_present_flag
=
294 vps
->vps_sub_layer_ordering_info_present_flag
;
295 for (i
= 0; i
<= sps
->sps_max_sub_layers_minus1
; i
++) {
296 sps
->sps_max_dec_pic_buffering_minus1
[i
] =
297 vps
->vps_max_dec_pic_buffering_minus1
[i
];
298 sps
->sps_max_num_reorder_pics
[i
] =
299 vps
->vps_max_num_reorder_pics
[i
];
300 sps
->sps_max_latency_increase_plus1
[i
] =
301 vps
->vps_max_latency_increase_plus1
[i
];
304 // These have to come from the capabilities of the encoder. We have no
305 // way to query them, so just hardcode parameters which work on the Intel
307 // CTB size from 8x8 to 32x32.
308 sps
->log2_min_luma_coding_block_size_minus3
= 0;
309 sps
->log2_diff_max_min_luma_coding_block_size
= 2;
310 // Transform size from 4x4 to 32x32.
311 sps
->log2_min_luma_transform_block_size_minus2
= 0;
312 sps
->log2_diff_max_min_luma_transform_block_size
= 3;
313 // Full transform hierarchy allowed (2-5).
314 sps
->max_transform_hierarchy_depth_inter
= 3;
315 sps
->max_transform_hierarchy_depth_intra
= 3;
317 sps
->amp_enabled_flag
= 1;
318 // SAO and temporal MVP do not work.
319 sps
->sample_adaptive_offset_enabled_flag
= 0;
320 sps
->sps_temporal_mvp_enabled_flag
= 0;
322 sps
->pcm_enabled_flag
= 0;
324 // STRPSs should ideally be here rather than defined individually in
325 // each slice, but the structure isn't completely fixed so for now
327 sps
->num_short_term_ref_pic_sets
= 0;
328 sps
->long_term_ref_pics_present_flag
= 0;
330 sps
->vui_parameters_present_flag
= 1;
332 if (avctx
->sample_aspect_ratio
.num
!= 0 &&
333 avctx
->sample_aspect_ratio
.den
!= 0) {
334 static const AVRational sar_idc
[] = {
336 { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
337 { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
338 { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
339 { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
342 for (i
= 0; i
< FF_ARRAY_ELEMS(sar_idc
); i
++) {
343 if (avctx
->sample_aspect_ratio
.num
== sar_idc
[i
].num
&&
344 avctx
->sample_aspect_ratio
.den
== sar_idc
[i
].den
) {
345 vui
->aspect_ratio_idc
= i
;
349 if (i
>= FF_ARRAY_ELEMS(sar_idc
)) {
350 vui
->aspect_ratio_idc
= 255;
351 vui
->sar_width
= avctx
->sample_aspect_ratio
.num
;
352 vui
->sar_height
= avctx
->sample_aspect_ratio
.den
;
354 vui
->aspect_ratio_info_present_flag
= 1;
357 if (avctx
->color_range
!= AVCOL_RANGE_UNSPECIFIED
||
358 avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
359 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
360 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
361 vui
->video_signal_type_present_flag
= 1;
362 vui
->video_format
= 5; // Unspecified.
363 vui
->video_full_range_flag
=
364 avctx
->color_range
== AVCOL_RANGE_JPEG
;
366 if (avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
367 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
368 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
369 vui
->colour_description_present_flag
= 1;
370 vui
->colour_primaries
= avctx
->color_primaries
;
371 vui
->transfer_characteristics
= avctx
->color_trc
;
372 vui
->matrix_coefficients
= avctx
->colorspace
;
375 vui
->video_format
= 5;
376 vui
->video_full_range_flag
= 0;
377 vui
->colour_primaries
= avctx
->color_primaries
;
378 vui
->transfer_characteristics
= avctx
->color_trc
;
379 vui
->matrix_coefficients
= avctx
->colorspace
;
382 if (avctx
->chroma_sample_location
!= AVCHROMA_LOC_UNSPECIFIED
) {
383 vui
->chroma_loc_info_present_flag
= 1;
384 vui
->chroma_sample_loc_type_top_field
=
385 vui
->chroma_sample_loc_type_bottom_field
=
386 avctx
->chroma_sample_location
- 1;
389 vui
->vui_timing_info_present_flag
= 1;
390 vui
->vui_num_units_in_tick
= vps
->vps_num_units_in_tick
;
391 vui
->vui_time_scale
= vps
->vps_time_scale
;
392 vui
->vui_poc_proportional_to_timing_flag
= vps
->vps_poc_proportional_to_timing_flag
;
393 vui
->vui_num_ticks_poc_diff_one_minus1
= vps
->vps_num_ticks_poc_diff_one_minus1
;
394 vui
->vui_hrd_parameters_present_flag
= 0;
396 vui
->bitstream_restriction_flag
= 1;
397 vui
->motion_vectors_over_pic_boundaries_flag
= 1;
398 vui
->restricted_ref_pic_lists_flag
= 1;
399 vui
->max_bytes_per_pic_denom
= 0;
400 vui
->max_bits_per_min_cu_denom
= 0;
401 vui
->log2_max_mv_length_horizontal
= 15;
402 vui
->log2_max_mv_length_vertical
= 15;
407 pps
->nal_unit_header
= (H265RawNALUnitHeader
) {
408 .nal_unit_type
= HEVC_NAL_PPS
,
410 .nuh_temporal_id_plus1
= 1,
413 pps
->pps_pic_parameter_set_id
= 0;
414 pps
->pps_seq_parameter_set_id
= sps
->sps_seq_parameter_set_id
;
416 pps
->num_ref_idx_l0_default_active_minus1
= 0;
417 pps
->num_ref_idx_l1_default_active_minus1
= 0;
419 pps
->init_qp_minus26
= priv
->fixed_qp_idr
- 26;
421 pps
->cu_qp_delta_enabled_flag
= (ctx
->va_rc_mode
!= VA_RC_CQP
);
422 pps
->diff_cu_qp_delta_depth
= 0;
424 pps
->pps_loop_filter_across_slices_enabled_flag
= 1;
427 // Fill VAAPI parameter buffers.
429 *vseq
= (VAEncSequenceParameterBufferHEVC
) {
430 .general_profile_idc
= vps
->profile_tier_level
.general_profile_idc
,
431 .general_level_idc
= vps
->profile_tier_level
.general_level_idc
,
432 .general_tier_flag
= vps
->profile_tier_level
.general_tier_flag
,
434 .intra_period
= avctx
->gop_size
,
435 .intra_idr_period
= avctx
->gop_size
,
436 .ip_period
= ctx
->b_per_p
+ 1,
437 .bits_per_second
= avctx
->bit_rate
,
439 .pic_width_in_luma_samples
= sps
->pic_width_in_luma_samples
,
440 .pic_height_in_luma_samples
= sps
->pic_height_in_luma_samples
,
443 .chroma_format_idc
= sps
->chroma_format_idc
,
444 .separate_colour_plane_flag
= sps
->separate_colour_plane_flag
,
445 .bit_depth_luma_minus8
= sps
->bit_depth_luma_minus8
,
446 .bit_depth_chroma_minus8
= sps
->bit_depth_chroma_minus8
,
447 .scaling_list_enabled_flag
= sps
->scaling_list_enabled_flag
,
448 .strong_intra_smoothing_enabled_flag
=
449 sps
->strong_intra_smoothing_enabled_flag
,
450 .amp_enabled_flag
= sps
->amp_enabled_flag
,
451 .sample_adaptive_offset_enabled_flag
=
452 sps
->sample_adaptive_offset_enabled_flag
,
453 .pcm_enabled_flag
= sps
->pcm_enabled_flag
,
454 .pcm_loop_filter_disabled_flag
= sps
->pcm_loop_filter_disabled_flag
,
455 .sps_temporal_mvp_enabled_flag
= sps
->sps_temporal_mvp_enabled_flag
,
458 .log2_min_luma_coding_block_size_minus3
=
459 sps
->log2_min_luma_coding_block_size_minus3
,
460 .log2_diff_max_min_luma_coding_block_size
=
461 sps
->log2_diff_max_min_luma_coding_block_size
,
462 .log2_min_transform_block_size_minus2
=
463 sps
->log2_min_luma_transform_block_size_minus2
,
464 .log2_diff_max_min_transform_block_size
=
465 sps
->log2_diff_max_min_luma_transform_block_size
,
466 .max_transform_hierarchy_depth_inter
=
467 sps
->max_transform_hierarchy_depth_inter
,
468 .max_transform_hierarchy_depth_intra
=
469 sps
->max_transform_hierarchy_depth_intra
,
471 .pcm_sample_bit_depth_luma_minus1
=
472 sps
->pcm_sample_bit_depth_luma_minus1
,
473 .pcm_sample_bit_depth_chroma_minus1
=
474 sps
->pcm_sample_bit_depth_chroma_minus1
,
475 .log2_min_pcm_luma_coding_block_size_minus3
=
476 sps
->log2_min_pcm_luma_coding_block_size_minus3
,
477 .log2_max_pcm_luma_coding_block_size_minus3
=
478 sps
->log2_min_pcm_luma_coding_block_size_minus3
+
479 sps
->log2_diff_max_min_pcm_luma_coding_block_size
,
481 .vui_parameters_present_flag
= 0,
484 *vpic
= (VAEncPictureParameterBufferHEVC
) {
485 .decoded_curr_pic
= {
486 .picture_id
= VA_INVALID_ID
,
487 .flags
= VA_PICTURE_HEVC_INVALID
,
490 .coded_buf
= VA_INVALID_ID
,
492 .collocated_ref_pic_index
= 0xff,
496 .pic_init_qp
= pps
->init_qp_minus26
+ 26,
497 .diff_cu_qp_delta_depth
= pps
->diff_cu_qp_delta_depth
,
498 .pps_cb_qp_offset
= pps
->pps_cb_qp_offset
,
499 .pps_cr_qp_offset
= pps
->pps_cr_qp_offset
,
501 .num_tile_columns_minus1
= pps
->num_tile_columns_minus1
,
502 .num_tile_rows_minus1
= pps
->num_tile_rows_minus1
,
504 .log2_parallel_merge_level_minus2
= pps
->log2_parallel_merge_level_minus2
,
505 .ctu_max_bitsize_allowed
= 0,
507 .num_ref_idx_l0_default_active_minus1
=
508 pps
->num_ref_idx_l0_default_active_minus1
,
509 .num_ref_idx_l1_default_active_minus1
=
510 pps
->num_ref_idx_l1_default_active_minus1
,
512 .slice_pic_parameter_set_id
= pps
->pps_pic_parameter_set_id
,
515 .sign_data_hiding_enabled_flag
= pps
->sign_data_hiding_enabled_flag
,
516 .constrained_intra_pred_flag
= pps
->constrained_intra_pred_flag
,
517 .transform_skip_enabled_flag
= pps
->transform_skip_enabled_flag
,
518 .cu_qp_delta_enabled_flag
= pps
->cu_qp_delta_enabled_flag
,
519 .weighted_pred_flag
= pps
->weighted_pred_flag
,
520 .weighted_bipred_flag
= pps
->weighted_bipred_flag
,
521 .transquant_bypass_enabled_flag
= pps
->transquant_bypass_enabled_flag
,
522 .tiles_enabled_flag
= pps
->tiles_enabled_flag
,
523 .entropy_coding_sync_enabled_flag
= pps
->entropy_coding_sync_enabled_flag
,
524 .loop_filter_across_tiles_enabled_flag
=
525 pps
->loop_filter_across_tiles_enabled_flag
,
526 .scaling_list_data_present_flag
= (sps
->sps_scaling_list_data_present_flag
|
527 pps
->pps_scaling_list_data_present_flag
),
528 .screen_content_flag
= 0,
529 .enable_gpu_weighted_prediction
= 0,
530 .no_output_of_prior_pics_flag
= 0,
537 static int vaapi_encode_h265_init_picture_params(AVCodecContext
*avctx
,
538 VAAPIEncodePicture
*pic
)
540 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
541 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
542 VAAPIEncodeH265Options
*opt
= ctx
->codec_options
;
543 VAEncPictureParameterBufferHEVC
*vpic
= pic
->codec_picture_params
;
546 if (pic
->type
== PICTURE_TYPE_IDR
) {
547 av_assert0(pic
->display_order
== pic
->encode_order
);
549 priv
->last_idr_frame
= pic
->display_order
;
551 priv
->slice_nal_unit
= HEVC_NAL_IDR_W_RADL
;
552 priv
->slice_type
= HEVC_SLICE_I
;
555 av_assert0(pic
->encode_order
> priv
->last_idr_frame
);
557 if (pic
->type
== PICTURE_TYPE_I
) {
558 priv
->slice_nal_unit
= HEVC_NAL_CRA_NUT
;
559 priv
->slice_type
= HEVC_SLICE_I
;
561 } else if (pic
->type
== PICTURE_TYPE_P
) {
562 av_assert0(pic
->refs
[0]);
563 priv
->slice_nal_unit
= HEVC_NAL_TRAIL_R
;
564 priv
->slice_type
= HEVC_SLICE_P
;
567 av_assert0(pic
->refs
[0] && pic
->refs
[1]);
568 if (pic
->refs
[1]->type
== PICTURE_TYPE_I
)
569 priv
->slice_nal_unit
= HEVC_NAL_RASL_N
;
571 priv
->slice_nal_unit
= HEVC_NAL_TRAIL_N
;
572 priv
->slice_type
= HEVC_SLICE_B
;
576 priv
->pic_order_cnt
= pic
->display_order
- priv
->last_idr_frame
;
579 priv
->aud_needed
= 1;
580 priv
->aud
.nal_unit_header
= (H265RawNALUnitHeader
) {
581 .nal_unit_type
= HEVC_NAL_AUD
,
583 .nuh_temporal_id_plus1
= 1,
585 priv
->aud
.pic_type
= priv
->pic_type
;
587 priv
->aud_needed
= 0;
590 vpic
->decoded_curr_pic
= (VAPictureHEVC
) {
591 .picture_id
= pic
->recon_surface
,
592 .pic_order_cnt
= priv
->pic_order_cnt
,
596 for (i
= 0; i
< pic
->nb_refs
; i
++) {
597 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
598 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
600 vpic
->reference_frames
[i
] = (VAPictureHEVC
) {
601 .picture_id
= ref
->recon_surface
,
602 .pic_order_cnt
= ref
->display_order
- priv
->last_idr_frame
,
603 .flags
= (ref
->display_order
< pic
->display_order
?
604 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE
: 0) |
605 (ref
->display_order
> pic
->display_order
?
606 VA_PICTURE_HEVC_RPS_ST_CURR_AFTER
: 0),
609 for (; i
< FF_ARRAY_ELEMS(vpic
->reference_frames
); i
++) {
610 vpic
->reference_frames
[i
] = (VAPictureHEVC
) {
611 .picture_id
= VA_INVALID_ID
,
612 .flags
= VA_PICTURE_HEVC_INVALID
,
616 vpic
->coded_buf
= pic
->output_buffer
;
618 vpic
->nal_unit_type
= priv
->slice_nal_unit
;
621 case PICTURE_TYPE_IDR
:
622 vpic
->pic_fields
.bits
.idr_pic_flag
= 1;
623 vpic
->pic_fields
.bits
.coding_type
= 1;
624 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
627 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
628 vpic
->pic_fields
.bits
.coding_type
= 1;
629 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
632 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
633 vpic
->pic_fields
.bits
.coding_type
= 2;
634 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
637 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
638 vpic
->pic_fields
.bits
.coding_type
= 3;
639 vpic
->pic_fields
.bits
.reference_pic_flag
= 0;
642 av_assert0(0 && "invalid picture type");
650 static int vaapi_encode_h265_init_slice_params(AVCodecContext
*avctx
,
651 VAAPIEncodePicture
*pic
,
652 VAAPIEncodeSlice
*slice
)
654 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
655 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
656 const H265RawSPS
*sps
= &priv
->sps
;
657 const H265RawPPS
*pps
= &priv
->pps
;
658 H265RawSliceHeader
*sh
= &priv
->slice
.header
;
659 VAEncPictureParameterBufferHEVC
*vpic
= pic
->codec_picture_params
;
660 VAEncSliceParameterBufferHEVC
*vslice
= slice
->codec_slice_params
;
663 sh
->nal_unit_header
= (H265RawNALUnitHeader
) {
664 .nal_unit_type
= priv
->slice_nal_unit
,
666 .nuh_temporal_id_plus1
= 1,
669 sh
->slice_pic_parameter_set_id
= pps
->pps_pic_parameter_set_id
;
671 // Currently we only support one slice per frame.
672 sh
->first_slice_segment_in_pic_flag
= 1;
673 sh
->slice_segment_address
= 0;
675 sh
->slice_type
= priv
->slice_type
;
677 sh
->slice_pic_order_cnt_lsb
= priv
->pic_order_cnt
&
678 (1 << (sps
->log2_max_pic_order_cnt_lsb_minus4
+ 4)) - 1;
680 if (pic
->type
!= PICTURE_TYPE_IDR
) {
681 H265RawSTRefPicSet
*rps
;
682 VAAPIEncodePicture
*st
;
685 sh
->short_term_ref_pic_set_sps_flag
= 0;
687 rps
= &sh
->short_term_ref_pic_set
;
688 memset(rps
, 0, sizeof(*rps
));
690 for (st
= ctx
->pic_start
; st
; st
= st
->next
) {
691 if (st
->encode_order
>= pic
->encode_order
) {
696 for (i
= 0; i
< pic
->nb_refs
; i
++) {
697 if (pic
->refs
[i
] == st
)
701 // Usually each picture always uses all of the others in the
702 // DPB as references. The one case we have to treat here is
703 // a non-IDR IRAP picture, which may need to hold unused
704 // references across itself to be used for the decoding of
705 // following RASL pictures. This looks for such an RASL
706 // picture, and keeps the reference if there is one.
707 VAAPIEncodePicture
*rp
;
708 for (rp
= ctx
->pic_start
; rp
; rp
= rp
->next
) {
709 if (rp
->encode_order
< pic
->encode_order
)
711 if (rp
->type
!= PICTURE_TYPE_B
)
713 if (rp
->refs
[0] == st
&& rp
->refs
[1] == pic
)
719 // This only works for one instance of each (delta_poc_sN_minus1
720 // is relative to the previous frame in the list, not relative to
721 // the current frame directly).
722 if (st
->display_order
< pic
->display_order
) {
723 rps
->delta_poc_s0_minus1
[rps
->num_negative_pics
] =
724 pic
->display_order
- st
->display_order
- 1;
725 rps
->used_by_curr_pic_s0_flag
[rps
->num_negative_pics
] = used
;
726 ++rps
->num_negative_pics
;
728 rps
->delta_poc_s1_minus1
[rps
->num_positive_pics
] =
729 st
->display_order
- pic
->display_order
- 1;
730 rps
->used_by_curr_pic_s1_flag
[rps
->num_positive_pics
] = used
;
731 ++rps
->num_positive_pics
;
735 sh
->num_long_term_sps
= 0;
736 sh
->num_long_term_pics
= 0;
738 sh
->slice_temporal_mvp_enabled_flag
=
739 sps
->sps_temporal_mvp_enabled_flag
;
740 if (sh
->slice_temporal_mvp_enabled_flag
) {
741 sh
->collocated_from_l0_flag
= sh
->slice_type
== HEVC_SLICE_B
;
742 sh
->collocated_ref_idx
= 0;
745 sh
->num_ref_idx_active_override_flag
= 0;
746 sh
->num_ref_idx_l0_active_minus1
= pps
->num_ref_idx_l0_default_active_minus1
;
747 sh
->num_ref_idx_l1_active_minus1
= pps
->num_ref_idx_l1_default_active_minus1
;
750 sh
->slice_sao_luma_flag
= sh
->slice_sao_chroma_flag
=
751 sps
->sample_adaptive_offset_enabled_flag
;
753 if (pic
->type
== PICTURE_TYPE_B
)
754 sh
->slice_qp_delta
= priv
->fixed_qp_b
- (pps
->init_qp_minus26
+ 26);
755 else if (pic
->type
== PICTURE_TYPE_P
)
756 sh
->slice_qp_delta
= priv
->fixed_qp_p
- (pps
->init_qp_minus26
+ 26);
758 sh
->slice_qp_delta
= priv
->fixed_qp_idr
- (pps
->init_qp_minus26
+ 26);
761 *vslice
= (VAEncSliceParameterBufferHEVC
) {
762 .slice_segment_address
= sh
->slice_segment_address
,
763 .num_ctu_in_slice
= priv
->ctu_width
* priv
->ctu_height
,
765 .slice_type
= sh
->slice_type
,
766 .slice_pic_parameter_set_id
= sh
->slice_pic_parameter_set_id
,
768 .num_ref_idx_l0_active_minus1
= sh
->num_ref_idx_l0_active_minus1
,
769 .num_ref_idx_l1_active_minus1
= sh
->num_ref_idx_l1_active_minus1
,
771 .luma_log2_weight_denom
= sh
->luma_log2_weight_denom
,
772 .delta_chroma_log2_weight_denom
= sh
->delta_chroma_log2_weight_denom
,
774 .max_num_merge_cand
= 5 - sh
->five_minus_max_num_merge_cand
,
776 .slice_qp_delta
= sh
->slice_qp_delta
,
777 .slice_cb_qp_offset
= sh
->slice_cb_qp_offset
,
778 .slice_cr_qp_offset
= sh
->slice_cr_qp_offset
,
780 .slice_beta_offset_div2
= sh
->slice_beta_offset_div2
,
781 .slice_tc_offset_div2
= sh
->slice_tc_offset_div2
,
783 .slice_fields
.bits
= {
784 .last_slice_of_pic_flag
= 1,
785 .dependent_slice_segment_flag
= sh
->dependent_slice_segment_flag
,
786 .colour_plane_id
= sh
->colour_plane_id
,
787 .slice_temporal_mvp_enabled_flag
=
788 sh
->slice_temporal_mvp_enabled_flag
,
789 .slice_sao_luma_flag
= sh
->slice_sao_luma_flag
,
790 .slice_sao_chroma_flag
= sh
->slice_sao_chroma_flag
,
791 .num_ref_idx_active_override_flag
=
792 sh
->num_ref_idx_active_override_flag
,
793 .mvd_l1_zero_flag
= sh
->mvd_l1_zero_flag
,
794 .cabac_init_flag
= sh
->cabac_init_flag
,
795 .slice_deblocking_filter_disabled_flag
=
796 sh
->slice_deblocking_filter_disabled_flag
,
797 .slice_loop_filter_across_slices_enabled_flag
=
798 sh
->slice_loop_filter_across_slices_enabled_flag
,
799 .collocated_from_l0_flag
= sh
->collocated_from_l0_flag
,
803 for (i
= 0; i
< FF_ARRAY_ELEMS(vslice
->ref_pic_list0
); i
++) {
804 vslice
->ref_pic_list0
[i
].picture_id
= VA_INVALID_ID
;
805 vslice
->ref_pic_list0
[i
].flags
= VA_PICTURE_HEVC_INVALID
;
806 vslice
->ref_pic_list1
[i
].picture_id
= VA_INVALID_ID
;
807 vslice
->ref_pic_list1
[i
].flags
= VA_PICTURE_HEVC_INVALID
;
810 av_assert0(pic
->nb_refs
<= 2);
811 if (pic
->nb_refs
>= 1) {
812 // Backward reference for P- or B-frame.
813 av_assert0(pic
->type
== PICTURE_TYPE_P
||
814 pic
->type
== PICTURE_TYPE_B
);
815 vslice
->ref_pic_list0
[0] = vpic
->reference_frames
[0];
817 if (pic
->nb_refs
>= 2) {
818 // Forward reference for B-frame.
819 av_assert0(pic
->type
== PICTURE_TYPE_B
);
820 vslice
->ref_pic_list1
[0] = vpic
->reference_frames
[1];
826 static av_cold
int vaapi_encode_h265_configure(AVCodecContext
*avctx
)
828 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
829 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
830 VAAPIEncodeH265Options
*opt
= ctx
->codec_options
;
833 err
= ff_cbs_init(&priv
->cbc
, AV_CODEC_ID_HEVC
, avctx
);
837 priv
->ctu_width
= FFALIGN(ctx
->surface_width
, 32) / 32;
838 priv
->ctu_height
= FFALIGN(ctx
->surface_height
, 32) / 32;
840 av_log(avctx
, AV_LOG_VERBOSE
, "Input %ux%u -> Surface %ux%u -> CTU %ux%u.\n",
841 avctx
->width
, avctx
->height
, ctx
->surface_width
,
842 ctx
->surface_height
, priv
->ctu_width
, priv
->ctu_height
);
844 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
845 priv
->fixed_qp_p
= opt
->qp
;
846 if (avctx
->i_quant_factor
> 0.0)
847 priv
->fixed_qp_idr
= (int)((priv
->fixed_qp_p
* avctx
->i_quant_factor
+
848 avctx
->i_quant_offset
) + 0.5);
850 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
851 if (avctx
->b_quant_factor
> 0.0)
852 priv
->fixed_qp_b
= (int)((priv
->fixed_qp_p
* avctx
->b_quant_factor
+
853 avctx
->b_quant_offset
) + 0.5);
855 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
857 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
858 "%d / %d / %d for IDR- / P- / B-frames.\n",
859 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
861 } else if (ctx
->va_rc_mode
== VA_RC_CBR
||
862 ctx
->va_rc_mode
== VA_RC_VBR
) {
863 // These still need to be set for pic_init_qp/slice_qp_delta.
864 priv
->fixed_qp_idr
= 30;
865 priv
->fixed_qp_p
= 30;
866 priv
->fixed_qp_b
= 30;
868 av_log(avctx
, AV_LOG_DEBUG
, "Using %s-bitrate = %d bps.\n",
869 ctx
->va_rc_mode
== VA_RC_CBR
? "constant" : "variable",
873 av_assert0(0 && "Invalid RC mode.");
879 static const VAAPIEncodeType vaapi_encode_type_h265
= {
880 .priv_data_size
= sizeof(VAAPIEncodeH265Context
),
882 .configure
= &vaapi_encode_h265_configure
,
884 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferHEVC
),
885 .init_sequence_params
= &vaapi_encode_h265_init_sequence_params
,
887 .picture_params_size
= sizeof(VAEncPictureParameterBufferHEVC
),
888 .init_picture_params
= &vaapi_encode_h265_init_picture_params
,
890 .slice_params_size
= sizeof(VAEncSliceParameterBufferHEVC
),
891 .init_slice_params
= &vaapi_encode_h265_init_slice_params
,
893 .sequence_header_type
= VAEncPackedHeaderSequence
,
894 .write_sequence_header
= &vaapi_encode_h265_write_sequence_header
,
896 .slice_header_type
= VAEncPackedHeaderHEVC_Slice
,
897 .write_slice_header
= &vaapi_encode_h265_write_slice_header
,
900 static av_cold
int vaapi_encode_h265_init(AVCodecContext
*avctx
)
902 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
903 VAAPIEncodeH265Options
*opt
=
904 (VAAPIEncodeH265Options
*)ctx
->codec_options_data
;
906 ctx
->codec
= &vaapi_encode_type_h265
;
908 if (avctx
->profile
== FF_PROFILE_UNKNOWN
)
909 avctx
->profile
= opt
->profile
;
910 if (avctx
->level
== FF_LEVEL_UNKNOWN
)
911 avctx
->level
= opt
->level
;
913 switch (avctx
->profile
) {
914 case FF_PROFILE_HEVC_MAIN
:
915 case FF_PROFILE_UNKNOWN
:
916 ctx
->va_profile
= VAProfileHEVCMain
;
917 ctx
->va_rt_format
= VA_RT_FORMAT_YUV420
;
919 case FF_PROFILE_HEVC_MAIN_10
:
920 #ifdef VA_RT_FORMAT_YUV420_10BPP
921 ctx
->va_profile
= VAProfileHEVCMain10
;
922 ctx
->va_rt_format
= VA_RT_FORMAT_YUV420_10BPP
;
925 av_log(avctx
, AV_LOG_ERROR
, "10-bit encoding is not "
926 "supported with this VAAPI version.\n");
927 return AVERROR(ENOSYS
);
930 av_log(avctx
, AV_LOG_ERROR
, "Unknown H.265 profile %d.\n",
932 return AVERROR(EINVAL
);
934 ctx
->va_entrypoint
= VAEntrypointEncSlice
;
936 if (avctx
->bit_rate
> 0) {
937 if (avctx
->rc_max_rate
== avctx
->bit_rate
)
938 ctx
->va_rc_mode
= VA_RC_CBR
;
940 ctx
->va_rc_mode
= VA_RC_VBR
;
942 ctx
->va_rc_mode
= VA_RC_CQP
;
944 ctx
->va_packed_headers
=
945 VA_ENC_PACKED_HEADER_SEQUENCE
| // VPS, SPS and PPS.
946 VA_ENC_PACKED_HEADER_SLICE
; // Slice headers.
948 ctx
->surface_width
= FFALIGN(avctx
->width
, 16);
949 ctx
->surface_height
= FFALIGN(avctx
->height
, 16);
951 return ff_vaapi_encode_init(avctx
);
954 static av_cold
int vaapi_encode_h265_close(AVCodecContext
*avctx
)
956 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
957 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
960 ff_cbs_close(&priv
->cbc
);
962 return ff_vaapi_encode_close(avctx
);
965 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
966 offsetof(VAAPIEncodeH265Options, x))
967 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
968 static const AVOption vaapi_encode_h265_options
[] = {
969 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
970 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 25 }, 0, 52, FLAGS
},
972 { "aud", "Include AUD",
973 OFFSET(aud
), AV_OPT_TYPE_INT
, { .i64
= 0 }, 0, 1, FLAGS
},
975 { "profile", "Set profile (general_profile_idc)",
976 OFFSET(profile
), AV_OPT_TYPE_INT
,
977 { .i64
= FF_PROFILE_HEVC_MAIN
}, 0x00, 0xff, FLAGS
, "profile" },
979 #define PROFILE(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
980 { .i64 = value }, 0, 0, FLAGS, "profile"
981 { PROFILE("main", FF_PROFILE_HEVC_MAIN
) },
982 { PROFILE("main10", FF_PROFILE_HEVC_MAIN_10
) },
985 { "level", "Set level (general_level_idc)",
986 OFFSET(level
), AV_OPT_TYPE_INT
,
987 { .i64
= 153 }, 0x00, 0xff, FLAGS
, "level" },
989 #define LEVEL(name, value) name, NULL, 0, AV_OPT_TYPE_CONST, \
990 { .i64 = value }, 0, 0, FLAGS, "level"
993 { LEVEL("2.1", 63) },
995 { LEVEL("3.1", 93) },
997 { LEVEL("4.1", 123) },
999 { LEVEL("5.1", 153) },
1000 { LEVEL("5.2", 156) },
1001 { LEVEL("6", 180) },
1002 { LEVEL("6.1", 183) },
1003 { LEVEL("6.2", 186) },
1009 static const AVCodecDefault vaapi_encode_h265_defaults
[] = {
1013 { "i_qfactor", "1.0" },
1014 { "i_qoffset", "0.0" },
1015 { "b_qfactor", "1.2" },
1016 { "b_qoffset", "0.0" },
1020 static const AVClass vaapi_encode_h265_class
= {
1021 .class_name
= "h265_vaapi",
1022 .item_name
= av_default_item_name
,
1023 .option
= vaapi_encode_h265_options
,
1024 .version
= LIBAVUTIL_VERSION_INT
,
1027 AVCodec ff_hevc_vaapi_encoder
= {
1028 .name
= "hevc_vaapi",
1029 .long_name
= NULL_IF_CONFIG_SMALL("H.265/HEVC (VAAPI)"),
1030 .type
= AVMEDIA_TYPE_VIDEO
,
1031 .id
= AV_CODEC_ID_HEVC
,
1032 .priv_data_size
= (sizeof(VAAPIEncodeContext
) +
1033 sizeof(VAAPIEncodeH265Options
)),
1034 .init
= &vaapi_encode_h265_init
,
1035 .encode2
= &ff_vaapi_encode2
,
1036 .close
= &vaapi_encode_h265_close
,
1037 .priv_class
= &vaapi_encode_h265_class
,
1038 .capabilities
= AV_CODEC_CAP_DELAY
| AV_CODEC_CAP_HARDWARE
,
1039 .defaults
= vaapi_encode_h265_defaults
,
1040 .pix_fmts
= (const enum AVPixelFormat
[]) {
1044 .wrapper_name
= "vaapi",