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
;
50 int64_t last_idr_frame
;
56 CodedBitstreamContext cbc
;
57 CodedBitstreamFragment current_access_unit
;
58 } VAAPIEncodeH265Context
;
60 typedef struct VAAPIEncodeH265Options
{
62 } VAAPIEncodeH265Options
;
65 static int vaapi_encode_h265_write_access_unit(AVCodecContext
*avctx
,
66 char *data
, size_t *data_len
,
67 CodedBitstreamFragment
*au
)
69 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
70 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
73 err
= ff_cbs_write_fragment_data(&priv
->cbc
, au
);
75 av_log(avctx
, AV_LOG_ERROR
, "Failed to write packed header.\n");
79 if (*data_len
< 8 * au
->data_size
- au
->data_bit_padding
) {
80 av_log(avctx
, AV_LOG_ERROR
, "Access unit too large: "
81 "%zu < %zu.\n", *data_len
,
82 8 * au
->data_size
- au
->data_bit_padding
);
83 return AVERROR(ENOSPC
);
86 memcpy(data
, au
->data
, au
->data_size
);
87 *data_len
= 8 * au
->data_size
- au
->data_bit_padding
;
92 static int vaapi_encode_h265_add_nal(AVCodecContext
*avctx
,
93 CodedBitstreamFragment
*au
,
96 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
97 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
98 H265RawNALUnitHeader
*header
= nal_unit
;
101 err
= ff_cbs_insert_unit_content(&priv
->cbc
, au
, -1,
102 header
->nal_unit_type
, nal_unit
);
104 av_log(avctx
, AV_LOG_ERROR
, "Failed to add NAL unit: "
105 "type = %d.\n", header
->nal_unit_type
);
112 static int vaapi_encode_h265_write_sequence_header(AVCodecContext
*avctx
,
113 char *data
, size_t *data_len
)
115 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
116 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
117 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
120 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->vps
);
124 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->sps
);
128 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->pps
);
132 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
134 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
138 static int vaapi_encode_h265_write_slice_header(AVCodecContext
*avctx
,
139 VAAPIEncodePicture
*pic
,
140 VAAPIEncodeSlice
*slice
,
141 char *data
, size_t *data_len
)
143 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
144 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
145 CodedBitstreamFragment
*au
= &priv
->current_access_unit
;
148 err
= vaapi_encode_h265_add_nal(avctx
, au
, &priv
->slice
);
152 err
= vaapi_encode_h265_write_access_unit(avctx
, data
, data_len
, au
);
154 ff_cbs_fragment_uninit(&priv
->cbc
, au
);
158 static int vaapi_encode_h265_init_sequence_params(AVCodecContext
*avctx
)
160 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
161 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
162 H265RawVPS
*vps
= &priv
->vps
;
163 H265RawSPS
*sps
= &priv
->sps
;
164 H265RawPPS
*pps
= &priv
->pps
;
165 H265RawVUI
*vui
= &sps
->vui
;
166 VAEncSequenceParameterBufferHEVC
*vseq
= ctx
->codec_sequence_params
;
167 VAEncPictureParameterBufferHEVC
*vpic
= ctx
->codec_picture_params
;
170 memset(&priv
->current_access_unit
, 0,
171 sizeof(priv
->current_access_unit
));
173 memset(vps
, 0, sizeof(*vps
));
174 memset(sps
, 0, sizeof(*sps
));
175 memset(pps
, 0, sizeof(*pps
));
180 vps
->nal_unit_header
= (H265RawNALUnitHeader
) {
181 .nal_unit_type
= HEVC_NAL_VPS
,
183 .nuh_temporal_id_plus1
= 1,
186 vps
->vps_video_parameter_set_id
= 0;
188 vps
->vps_base_layer_internal_flag
= 1;
189 vps
->vps_base_layer_available_flag
= 1;
190 vps
->vps_max_layers_minus1
= 0;
191 vps
->vps_max_sub_layers_minus1
= 0;
192 vps
->vps_temporal_id_nesting_flag
= 1;
194 vps
->profile_tier_level
= (H265RawProfileTierLevel
) {
195 .general_profile_space
= 0,
196 .general_profile_idc
= avctx
->profile
,
197 .general_tier_flag
= 0,
199 .general_progressive_source_flag
= 1,
200 .general_interlaced_source_flag
= 0,
201 .general_non_packed_constraint_flag
= 1,
202 .general_frame_only_constraint_flag
= 1,
204 .general_level_idc
= avctx
->level
,
206 vps
->profile_tier_level
.general_profile_compatibility_flag
[avctx
->profile
& 31] = 1;
208 vps
->vps_sub_layer_ordering_info_present_flag
= 0;
209 vps
->vps_max_dec_pic_buffering_minus1
[0] = (ctx
->b_per_p
> 0) + 1;
210 vps
->vps_max_num_reorder_pics
[0] = (ctx
->b_per_p
> 0);
211 vps
->vps_max_latency_increase_plus1
[0] = 0;
213 vps
->vps_max_layer_id
= 0;
214 vps
->vps_num_layer_sets_minus1
= 0;
215 vps
->layer_id_included_flag
[0][0] = 1;
217 vps
->vps_timing_info_present_flag
= 1;
218 if (avctx
->framerate
.num
> 0 && avctx
->framerate
.den
> 0) {
219 vps
->vps_num_units_in_tick
= avctx
->framerate
.den
;
220 vps
->vps_time_scale
= avctx
->framerate
.num
;
221 vps
->vps_poc_proportional_to_timing_flag
= 1;
222 vps
->vps_num_ticks_poc_diff_one_minus1
= 0;
224 vps
->vps_num_units_in_tick
= avctx
->time_base
.num
;
225 vps
->vps_time_scale
= avctx
->time_base
.den
;
226 vps
->vps_poc_proportional_to_timing_flag
= 0;
228 vps
->vps_num_hrd_parameters
= 0;
233 sps
->nal_unit_header
= (H265RawNALUnitHeader
) {
234 .nal_unit_type
= HEVC_NAL_SPS
,
236 .nuh_temporal_id_plus1
= 1,
239 sps
->sps_video_parameter_set_id
= vps
->vps_video_parameter_set_id
;
241 sps
->sps_max_sub_layers_minus1
= vps
->vps_max_sub_layers_minus1
;
242 sps
->sps_temporal_id_nesting_flag
= vps
->vps_temporal_id_nesting_flag
;
244 sps
->profile_tier_level
= vps
->profile_tier_level
;
246 sps
->sps_seq_parameter_set_id
= 0;
248 sps
->chroma_format_idc
= 1; // YUV 4:2:0.
249 sps
->separate_colour_plane_flag
= 0;
251 sps
->pic_width_in_luma_samples
= ctx
->surface_width
;
252 sps
->pic_height_in_luma_samples
= ctx
->surface_height
;
254 if (avctx
->width
!= ctx
->surface_width
||
255 avctx
->height
!= ctx
->surface_height
) {
256 sps
->conformance_window_flag
= 1;
257 sps
->conf_win_left_offset
= 0;
258 sps
->conf_win_right_offset
=
259 (ctx
->surface_width
- avctx
->width
) / 2;
260 sps
->conf_win_top_offset
= 0;
261 sps
->conf_win_bottom_offset
=
262 (ctx
->surface_height
- avctx
->height
) / 2;
264 sps
->conformance_window_flag
= 0;
267 sps
->bit_depth_luma_minus8
=
268 avctx
->profile
== FF_PROFILE_HEVC_MAIN_10 ?
2 : 0;
269 sps
->bit_depth_chroma_minus8
= sps
->bit_depth_luma_minus8
;
271 sps
->log2_max_pic_order_cnt_lsb_minus4
= 8;
273 sps
->sps_sub_layer_ordering_info_present_flag
=
274 vps
->vps_sub_layer_ordering_info_present_flag
;
275 for (i
= 0; i
<= sps
->sps_max_sub_layers_minus1
; i
++) {
276 sps
->sps_max_dec_pic_buffering_minus1
[i
] =
277 vps
->vps_max_dec_pic_buffering_minus1
[i
];
278 sps
->sps_max_num_reorder_pics
[i
] =
279 vps
->vps_max_num_reorder_pics
[i
];
280 sps
->sps_max_latency_increase_plus1
[i
] =
281 vps
->vps_max_latency_increase_plus1
[i
];
284 // These have to come from the capabilities of the encoder. We have no
285 // way to query them, so just hardcode parameters which work on the Intel
287 // CTB size from 8x8 to 32x32.
288 sps
->log2_min_luma_coding_block_size_minus3
= 0;
289 sps
->log2_diff_max_min_luma_coding_block_size
= 2;
290 // Transform size from 4x4 to 32x32.
291 sps
->log2_min_luma_transform_block_size_minus2
= 0;
292 sps
->log2_diff_max_min_luma_transform_block_size
= 3;
293 // Full transform hierarchy allowed (2-5).
294 sps
->max_transform_hierarchy_depth_inter
= 3;
295 sps
->max_transform_hierarchy_depth_intra
= 3;
297 sps
->amp_enabled_flag
= 1;
298 // SAO and temporal MVP do not work.
299 sps
->sample_adaptive_offset_enabled_flag
= 0;
300 sps
->sps_temporal_mvp_enabled_flag
= 0;
302 sps
->pcm_enabled_flag
= 0;
304 // STRPSs should ideally be here rather than defined individually in
305 // each slice, but the structure isn't completely fixed so for now
307 sps
->num_short_term_ref_pic_sets
= 0;
308 sps
->long_term_ref_pics_present_flag
= 0;
310 sps
->vui_parameters_present_flag
= 1;
312 if (avctx
->sample_aspect_ratio
.num
!= 0 &&
313 avctx
->sample_aspect_ratio
.den
!= 0) {
314 static const AVRational sar_idc
[] = {
316 { 1, 1 }, { 12, 11 }, { 10, 11 }, { 16, 11 },
317 { 40, 33 }, { 24, 11 }, { 20, 11 }, { 32, 11 },
318 { 80, 33 }, { 18, 11 }, { 15, 11 }, { 64, 33 },
319 { 160, 99 }, { 4, 3 }, { 3, 2 }, { 2, 1 },
322 for (i
= 0; i
< FF_ARRAY_ELEMS(sar_idc
); i
++) {
323 if (avctx
->sample_aspect_ratio
.num
== sar_idc
[i
].num
&&
324 avctx
->sample_aspect_ratio
.den
== sar_idc
[i
].den
) {
325 vui
->aspect_ratio_idc
= i
;
329 if (i
>= FF_ARRAY_ELEMS(sar_idc
)) {
330 vui
->aspect_ratio_idc
= 255;
331 vui
->sar_width
= avctx
->sample_aspect_ratio
.num
;
332 vui
->sar_height
= avctx
->sample_aspect_ratio
.den
;
334 vui
->aspect_ratio_info_present_flag
= 1;
337 if (avctx
->color_range
!= AVCOL_RANGE_UNSPECIFIED
||
338 avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
339 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
340 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
341 vui
->video_signal_type_present_flag
= 1;
342 vui
->video_format
= 5; // Unspecified.
343 vui
->video_full_range_flag
=
344 avctx
->color_range
== AVCOL_RANGE_JPEG
;
346 if (avctx
->color_primaries
!= AVCOL_PRI_UNSPECIFIED
||
347 avctx
->color_trc
!= AVCOL_TRC_UNSPECIFIED
||
348 avctx
->colorspace
!= AVCOL_SPC_UNSPECIFIED
) {
349 vui
->colour_description_present_flag
= 1;
350 vui
->colour_primaries
= avctx
->color_primaries
;
351 vui
->transfer_characteristics
= avctx
->color_trc
;
352 vui
->matrix_coefficients
= avctx
->colorspace
;
355 vui
->video_format
= 5;
356 vui
->video_full_range_flag
= 0;
357 vui
->colour_primaries
= avctx
->color_primaries
;
358 vui
->transfer_characteristics
= avctx
->color_trc
;
359 vui
->matrix_coefficients
= avctx
->colorspace
;
362 if (avctx
->chroma_sample_location
!= AVCHROMA_LOC_UNSPECIFIED
) {
363 vui
->chroma_loc_info_present_flag
= 1;
364 vui
->chroma_sample_loc_type_top_field
=
365 vui
->chroma_sample_loc_type_bottom_field
=
366 avctx
->chroma_sample_location
- 1;
369 vui
->vui_timing_info_present_flag
= 1;
370 vui
->vui_num_units_in_tick
= vps
->vps_num_units_in_tick
;
371 vui
->vui_time_scale
= vps
->vps_time_scale
;
372 vui
->vui_poc_proportional_to_timing_flag
= vps
->vps_poc_proportional_to_timing_flag
;
373 vui
->vui_num_ticks_poc_diff_one_minus1
= vps
->vps_num_ticks_poc_diff_one_minus1
;
374 vui
->vui_hrd_parameters_present_flag
= 0;
376 vui
->bitstream_restriction_flag
= 1;
377 vui
->motion_vectors_over_pic_boundaries_flag
= 1;
378 vui
->restricted_ref_pic_lists_flag
= 1;
379 vui
->max_bytes_per_pic_denom
= 0;
380 vui
->max_bits_per_min_cu_denom
= 0;
381 vui
->log2_max_mv_length_horizontal
= 15;
382 vui
->log2_max_mv_length_vertical
= 15;
387 pps
->nal_unit_header
= (H265RawNALUnitHeader
) {
388 .nal_unit_type
= HEVC_NAL_PPS
,
390 .nuh_temporal_id_plus1
= 1,
393 pps
->pps_pic_parameter_set_id
= 0;
394 pps
->pps_seq_parameter_set_id
= sps
->sps_seq_parameter_set_id
;
396 pps
->num_ref_idx_l0_default_active_minus1
= 0;
397 pps
->num_ref_idx_l1_default_active_minus1
= 0;
399 pps
->init_qp_minus26
= priv
->fixed_qp_idr
- 26;
401 pps
->cu_qp_delta_enabled_flag
= (ctx
->va_rc_mode
!= VA_RC_CQP
);
402 pps
->diff_cu_qp_delta_depth
= 0;
404 pps
->pps_loop_filter_across_slices_enabled_flag
= 1;
407 // Fill VAAPI parameter buffers.
409 *vseq
= (VAEncSequenceParameterBufferHEVC
) {
410 .general_profile_idc
= vps
->profile_tier_level
.general_profile_idc
,
411 .general_level_idc
= vps
->profile_tier_level
.general_level_idc
,
412 .general_tier_flag
= vps
->profile_tier_level
.general_tier_flag
,
414 .intra_period
= avctx
->gop_size
,
415 .intra_idr_period
= avctx
->gop_size
,
416 .ip_period
= ctx
->b_per_p
+ 1,
417 .bits_per_second
= avctx
->bit_rate
,
419 .pic_width_in_luma_samples
= sps
->pic_width_in_luma_samples
,
420 .pic_height_in_luma_samples
= sps
->pic_height_in_luma_samples
,
423 .chroma_format_idc
= sps
->chroma_format_idc
,
424 .separate_colour_plane_flag
= sps
->separate_colour_plane_flag
,
425 .bit_depth_luma_minus8
= sps
->bit_depth_luma_minus8
,
426 .bit_depth_chroma_minus8
= sps
->bit_depth_chroma_minus8
,
427 .scaling_list_enabled_flag
= sps
->scaling_list_enabled_flag
,
428 .strong_intra_smoothing_enabled_flag
=
429 sps
->strong_intra_smoothing_enabled_flag
,
430 .amp_enabled_flag
= sps
->amp_enabled_flag
,
431 .sample_adaptive_offset_enabled_flag
=
432 sps
->sample_adaptive_offset_enabled_flag
,
433 .pcm_enabled_flag
= sps
->pcm_enabled_flag
,
434 .pcm_loop_filter_disabled_flag
= sps
->pcm_loop_filter_disabled_flag
,
435 .sps_temporal_mvp_enabled_flag
= sps
->sps_temporal_mvp_enabled_flag
,
438 .log2_min_luma_coding_block_size_minus3
=
439 sps
->log2_min_luma_coding_block_size_minus3
,
440 .log2_diff_max_min_luma_coding_block_size
=
441 sps
->log2_diff_max_min_luma_coding_block_size
,
442 .log2_min_transform_block_size_minus2
=
443 sps
->log2_min_luma_transform_block_size_minus2
,
444 .log2_diff_max_min_transform_block_size
=
445 sps
->log2_diff_max_min_luma_transform_block_size
,
446 .max_transform_hierarchy_depth_inter
=
447 sps
->max_transform_hierarchy_depth_inter
,
448 .max_transform_hierarchy_depth_intra
=
449 sps
->max_transform_hierarchy_depth_intra
,
451 .pcm_sample_bit_depth_luma_minus1
=
452 sps
->pcm_sample_bit_depth_luma_minus1
,
453 .pcm_sample_bit_depth_chroma_minus1
=
454 sps
->pcm_sample_bit_depth_chroma_minus1
,
455 .log2_min_pcm_luma_coding_block_size_minus3
=
456 sps
->log2_min_pcm_luma_coding_block_size_minus3
,
457 .log2_max_pcm_luma_coding_block_size_minus3
=
458 sps
->log2_min_pcm_luma_coding_block_size_minus3
+
459 sps
->log2_diff_max_min_pcm_luma_coding_block_size
,
461 .vui_parameters_present_flag
= 0,
464 *vpic
= (VAEncPictureParameterBufferHEVC
) {
465 .decoded_curr_pic
= {
466 .picture_id
= VA_INVALID_ID
,
467 .flags
= VA_PICTURE_HEVC_INVALID
,
470 .coded_buf
= VA_INVALID_ID
,
472 .collocated_ref_pic_index
= 0xff,
476 .pic_init_qp
= pps
->init_qp_minus26
+ 26,
477 .diff_cu_qp_delta_depth
= pps
->diff_cu_qp_delta_depth
,
478 .pps_cb_qp_offset
= pps
->pps_cb_qp_offset
,
479 .pps_cr_qp_offset
= pps
->pps_cr_qp_offset
,
481 .num_tile_columns_minus1
= pps
->num_tile_columns_minus1
,
482 .num_tile_rows_minus1
= pps
->num_tile_rows_minus1
,
484 .log2_parallel_merge_level_minus2
= pps
->log2_parallel_merge_level_minus2
,
485 .ctu_max_bitsize_allowed
= 0,
487 .num_ref_idx_l0_default_active_minus1
=
488 pps
->num_ref_idx_l0_default_active_minus1
,
489 .num_ref_idx_l1_default_active_minus1
=
490 pps
->num_ref_idx_l1_default_active_minus1
,
492 .slice_pic_parameter_set_id
= pps
->pps_pic_parameter_set_id
,
495 .sign_data_hiding_enabled_flag
= pps
->sign_data_hiding_enabled_flag
,
496 .constrained_intra_pred_flag
= pps
->constrained_intra_pred_flag
,
497 .transform_skip_enabled_flag
= pps
->transform_skip_enabled_flag
,
498 .cu_qp_delta_enabled_flag
= pps
->cu_qp_delta_enabled_flag
,
499 .weighted_pred_flag
= pps
->weighted_pred_flag
,
500 .weighted_bipred_flag
= pps
->weighted_bipred_flag
,
501 .transquant_bypass_enabled_flag
= pps
->transquant_bypass_enabled_flag
,
502 .tiles_enabled_flag
= pps
->tiles_enabled_flag
,
503 .entropy_coding_sync_enabled_flag
= pps
->entropy_coding_sync_enabled_flag
,
504 .loop_filter_across_tiles_enabled_flag
=
505 pps
->loop_filter_across_tiles_enabled_flag
,
506 .scaling_list_data_present_flag
= (sps
->sps_scaling_list_data_present_flag
|
507 pps
->pps_scaling_list_data_present_flag
),
508 .screen_content_flag
= 0,
509 .enable_gpu_weighted_prediction
= 0,
510 .no_output_of_prior_pics_flag
= 0,
517 static int vaapi_encode_h265_init_picture_params(AVCodecContext
*avctx
,
518 VAAPIEncodePicture
*pic
)
520 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
521 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
522 VAEncPictureParameterBufferHEVC
*vpic
= pic
->codec_picture_params
;
525 if (pic
->type
== PICTURE_TYPE_IDR
) {
526 av_assert0(pic
->display_order
== pic
->encode_order
);
528 priv
->last_idr_frame
= pic
->display_order
;
530 priv
->slice_nal_unit
= HEVC_NAL_IDR_W_RADL
;
531 priv
->slice_type
= HEVC_SLICE_I
;
533 av_assert0(pic
->encode_order
> priv
->last_idr_frame
);
535 if (pic
->type
== PICTURE_TYPE_I
) {
536 priv
->slice_nal_unit
= HEVC_NAL_CRA_NUT
;
537 priv
->slice_type
= HEVC_SLICE_I
;
538 } else if (pic
->type
== PICTURE_TYPE_P
) {
539 av_assert0(pic
->refs
[0]);
540 priv
->slice_nal_unit
= HEVC_NAL_TRAIL_R
;
541 priv
->slice_type
= HEVC_SLICE_P
;
543 av_assert0(pic
->refs
[0] && pic
->refs
[1]);
544 if (pic
->refs
[1]->type
== PICTURE_TYPE_I
)
545 priv
->slice_nal_unit
= HEVC_NAL_RASL_N
;
547 priv
->slice_nal_unit
= HEVC_NAL_TRAIL_N
;
548 priv
->slice_type
= HEVC_SLICE_B
;
551 priv
->pic_order_cnt
= pic
->display_order
- priv
->last_idr_frame
;
553 vpic
->decoded_curr_pic
= (VAPictureHEVC
) {
554 .picture_id
= pic
->recon_surface
,
555 .pic_order_cnt
= priv
->pic_order_cnt
,
559 for (i
= 0; i
< pic
->nb_refs
; i
++) {
560 VAAPIEncodePicture
*ref
= pic
->refs
[i
];
561 av_assert0(ref
&& ref
->encode_order
< pic
->encode_order
);
563 vpic
->reference_frames
[i
] = (VAPictureHEVC
) {
564 .picture_id
= ref
->recon_surface
,
565 .pic_order_cnt
= ref
->display_order
- priv
->last_idr_frame
,
566 .flags
= (ref
->display_order
< pic
->display_order ?
567 VA_PICTURE_HEVC_RPS_ST_CURR_BEFORE
: 0) |
568 (ref
->display_order
> pic
->display_order ?
569 VA_PICTURE_HEVC_RPS_ST_CURR_AFTER
: 0),
572 for (; i
< FF_ARRAY_ELEMS(vpic
->reference_frames
); i
++) {
573 vpic
->reference_frames
[i
] = (VAPictureHEVC
) {
574 .picture_id
= VA_INVALID_ID
,
575 .flags
= VA_PICTURE_HEVC_INVALID
,
579 vpic
->coded_buf
= pic
->output_buffer
;
581 vpic
->nal_unit_type
= priv
->slice_nal_unit
;
584 case PICTURE_TYPE_IDR
:
585 vpic
->pic_fields
.bits
.idr_pic_flag
= 1;
586 vpic
->pic_fields
.bits
.coding_type
= 1;
587 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
590 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
591 vpic
->pic_fields
.bits
.coding_type
= 1;
592 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
595 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
596 vpic
->pic_fields
.bits
.coding_type
= 2;
597 vpic
->pic_fields
.bits
.reference_pic_flag
= 1;
600 vpic
->pic_fields
.bits
.idr_pic_flag
= 0;
601 vpic
->pic_fields
.bits
.coding_type
= 3;
602 vpic
->pic_fields
.bits
.reference_pic_flag
= 0;
605 av_assert0(0 && "invalid picture type");
613 static int vaapi_encode_h265_init_slice_params(AVCodecContext
*avctx
,
614 VAAPIEncodePicture
*pic
,
615 VAAPIEncodeSlice
*slice
)
617 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
618 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
619 const H265RawSPS
*sps
= &priv
->sps
;
620 const H265RawPPS
*pps
= &priv
->pps
;
621 H265RawSliceHeader
*sh
= &priv
->slice
.header
;
622 VAEncPictureParameterBufferHEVC
*vpic
= pic
->codec_picture_params
;
623 VAEncSliceParameterBufferHEVC
*vslice
= slice
->codec_slice_params
;
626 sh
->nal_unit_header
= (H265RawNALUnitHeader
) {
627 .nal_unit_type
= priv
->slice_nal_unit
,
629 .nuh_temporal_id_plus1
= 1,
632 sh
->slice_pic_parameter_set_id
= pps
->pps_pic_parameter_set_id
;
634 // Currently we only support one slice per frame.
635 sh
->first_slice_segment_in_pic_flag
= 1;
636 sh
->slice_segment_address
= 0;
638 sh
->slice_type
= priv
->slice_type
;
640 sh
->slice_pic_order_cnt_lsb
= priv
->pic_order_cnt
&
641 (1 << (sps
->log2_max_pic_order_cnt_lsb_minus4
+ 4)) - 1;
643 if (pic
->type
!= PICTURE_TYPE_IDR
) {
644 H265RawSTRefPicSet
*rps
;
645 VAAPIEncodePicture
*st
;
648 sh
->short_term_ref_pic_set_sps_flag
= 0;
650 rps
= &sh
->short_term_ref_pic_set
;
651 memset(rps
, 0, sizeof(*rps
));
653 for (st
= ctx
->pic_start
; st
; st
= st
->next
) {
654 if (st
->encode_order
>= pic
->encode_order
) {
659 for (i
= 0; i
< pic
->nb_refs
; i
++) {
660 if (pic
->refs
[i
] == st
)
664 // Usually each picture always uses all of the others in the
665 // DPB as references. The one case we have to treat here is
666 // a non-IDR IRAP picture, which may need to hold unused
667 // references across itself to be used for the decoding of
668 // following RASL pictures. This looks for such an RASL
669 // picture, and keeps the reference if there is one.
670 VAAPIEncodePicture
*rp
;
671 for (rp
= ctx
->pic_start
; rp
; rp
= rp
->next
) {
672 if (rp
->encode_order
< pic
->encode_order
)
674 if (rp
->type
!= PICTURE_TYPE_B
)
676 if (rp
->refs
[0] == st
&& rp
->refs
[1] == pic
)
682 // This only works for one instance of each (delta_poc_sN_minus1
683 // is relative to the previous frame in the list, not relative to
684 // the current frame directly).
685 if (st
->display_order
< pic
->display_order
) {
686 rps
->delta_poc_s0_minus1
[rps
->num_negative_pics
] =
687 pic
->display_order
- st
->display_order
- 1;
688 rps
->used_by_curr_pic_s0_flag
[rps
->num_negative_pics
] = used
;
689 ++rps
->num_negative_pics
;
691 rps
->delta_poc_s1_minus1
[rps
->num_positive_pics
] =
692 st
->display_order
- pic
->display_order
- 1;
693 rps
->used_by_curr_pic_s1_flag
[rps
->num_positive_pics
] = used
;
694 ++rps
->num_positive_pics
;
698 sh
->num_long_term_sps
= 0;
699 sh
->num_long_term_pics
= 0;
701 sh
->slice_temporal_mvp_enabled_flag
=
702 sps
->sps_temporal_mvp_enabled_flag
;
703 if (sh
->slice_temporal_mvp_enabled_flag
) {
704 sh
->collocated_from_l0_flag
= sh
->slice_type
== HEVC_SLICE_B
;
705 sh
->collocated_ref_idx
= 0;
708 sh
->num_ref_idx_active_override_flag
= 0;
709 sh
->num_ref_idx_l0_active_minus1
= pps
->num_ref_idx_l0_default_active_minus1
;
710 sh
->num_ref_idx_l1_active_minus1
= pps
->num_ref_idx_l1_default_active_minus1
;
713 sh
->slice_sao_luma_flag
= sh
->slice_sao_chroma_flag
=
714 sps
->sample_adaptive_offset_enabled_flag
;
716 if (pic
->type
== PICTURE_TYPE_B
)
717 sh
->slice_qp_delta
= priv
->fixed_qp_b
- (pps
->init_qp_minus26
+ 26);
718 else if (pic
->type
== PICTURE_TYPE_P
)
719 sh
->slice_qp_delta
= priv
->fixed_qp_p
- (pps
->init_qp_minus26
+ 26);
721 sh
->slice_qp_delta
= priv
->fixed_qp_idr
- (pps
->init_qp_minus26
+ 26);
724 *vslice
= (VAEncSliceParameterBufferHEVC
) {
725 .slice_segment_address
= sh
->slice_segment_address
,
726 .num_ctu_in_slice
= priv
->ctu_width
* priv
->ctu_height
,
728 .slice_type
= sh
->slice_type
,
729 .slice_pic_parameter_set_id
= sh
->slice_pic_parameter_set_id
,
731 .num_ref_idx_l0_active_minus1
= sh
->num_ref_idx_l0_active_minus1
,
732 .num_ref_idx_l1_active_minus1
= sh
->num_ref_idx_l1_active_minus1
,
733 .ref_pic_list0
[0] = vpic
->reference_frames
[0],
734 .ref_pic_list1
[0] = vpic
->reference_frames
[1],
736 .luma_log2_weight_denom
= sh
->luma_log2_weight_denom
,
737 .delta_chroma_log2_weight_denom
= sh
->delta_chroma_log2_weight_denom
,
739 .max_num_merge_cand
= 5 - sh
->five_minus_max_num_merge_cand
,
741 .slice_qp_delta
= sh
->slice_qp_delta
,
742 .slice_cb_qp_offset
= sh
->slice_cb_qp_offset
,
743 .slice_cr_qp_offset
= sh
->slice_cr_qp_offset
,
745 .slice_beta_offset_div2
= sh
->slice_beta_offset_div2
,
746 .slice_tc_offset_div2
= sh
->slice_tc_offset_div2
,
748 .slice_fields
.bits
= {
749 .last_slice_of_pic_flag
= 1,
750 .dependent_slice_segment_flag
= sh
->dependent_slice_segment_flag
,
751 .colour_plane_id
= sh
->colour_plane_id
,
752 .slice_temporal_mvp_enabled_flag
=
753 sh
->slice_temporal_mvp_enabled_flag
,
754 .slice_sao_luma_flag
= sh
->slice_sao_luma_flag
,
755 .slice_sao_chroma_flag
= sh
->slice_sao_chroma_flag
,
756 .num_ref_idx_active_override_flag
=
757 sh
->num_ref_idx_active_override_flag
,
758 .mvd_l1_zero_flag
= sh
->mvd_l1_zero_flag
,
759 .cabac_init_flag
= sh
->cabac_init_flag
,
760 .slice_deblocking_filter_disabled_flag
=
761 sh
->slice_deblocking_filter_disabled_flag
,
762 .slice_loop_filter_across_slices_enabled_flag
=
763 sh
->slice_loop_filter_across_slices_enabled_flag
,
764 .collocated_from_l0_flag
= sh
->collocated_from_l0_flag
,
772 static av_cold
int vaapi_encode_h265_configure(AVCodecContext
*avctx
)
774 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
775 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
776 VAAPIEncodeH265Options
*opt
= ctx
->codec_options
;
779 err
= ff_cbs_init(&priv
->cbc
, AV_CODEC_ID_HEVC
, avctx
);
783 priv
->ctu_width
= FFALIGN(ctx
->surface_width
, 32) / 32;
784 priv
->ctu_height
= FFALIGN(ctx
->surface_height
, 32) / 32;
786 av_log(avctx
, AV_LOG_VERBOSE
, "Input %ux%u -> Surface %ux%u -> CTU %ux%u.\n",
787 avctx
->width
, avctx
->height
, ctx
->surface_width
,
788 ctx
->surface_height
, priv
->ctu_width
, priv
->ctu_height
);
790 if (ctx
->va_rc_mode
== VA_RC_CQP
) {
791 priv
->fixed_qp_p
= opt
->qp
;
792 if (avctx
->i_quant_factor
> 0.0)
793 priv
->fixed_qp_idr
= (int)((priv
->fixed_qp_p
* avctx
->i_quant_factor
+
794 avctx
->i_quant_offset
) + 0.5);
796 priv
->fixed_qp_idr
= priv
->fixed_qp_p
;
797 if (avctx
->b_quant_factor
> 0.0)
798 priv
->fixed_qp_b
= (int)((priv
->fixed_qp_p
* avctx
->b_quant_factor
+
799 avctx
->b_quant_offset
) + 0.5);
801 priv
->fixed_qp_b
= priv
->fixed_qp_p
;
803 av_log(avctx
, AV_LOG_DEBUG
, "Using fixed QP = "
804 "%d / %d / %d for IDR- / P- / B-frames.\n",
805 priv
->fixed_qp_idr
, priv
->fixed_qp_p
, priv
->fixed_qp_b
);
807 } else if (ctx
->va_rc_mode
== VA_RC_CBR
) {
808 // These still need to be set for pic_init_qp/slice_qp_delta.
809 priv
->fixed_qp_idr
= 30;
810 priv
->fixed_qp_p
= 30;
811 priv
->fixed_qp_b
= 30;
813 av_log(avctx
, AV_LOG_DEBUG
, "Using constant-bitrate = %d bps.\n",
817 av_assert0(0 && "Invalid RC mode.");
823 static const VAAPIEncodeType vaapi_encode_type_h265
= {
824 .priv_data_size
= sizeof(VAAPIEncodeH265Context
),
826 .configure
= &vaapi_encode_h265_configure
,
828 .sequence_params_size
= sizeof(VAEncSequenceParameterBufferHEVC
),
829 .init_sequence_params
= &vaapi_encode_h265_init_sequence_params
,
831 .picture_params_size
= sizeof(VAEncPictureParameterBufferHEVC
),
832 .init_picture_params
= &vaapi_encode_h265_init_picture_params
,
834 .slice_params_size
= sizeof(VAEncSliceParameterBufferHEVC
),
835 .init_slice_params
= &vaapi_encode_h265_init_slice_params
,
837 .sequence_header_type
= VAEncPackedHeaderSequence
,
838 .write_sequence_header
= &vaapi_encode_h265_write_sequence_header
,
840 .slice_header_type
= VAEncPackedHeaderHEVC_Slice
,
841 .write_slice_header
= &vaapi_encode_h265_write_slice_header
,
844 static av_cold
int vaapi_encode_h265_init(AVCodecContext
*avctx
)
846 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
848 ctx
->codec
= &vaapi_encode_type_h265
;
850 switch (avctx
->profile
) {
851 case FF_PROFILE_HEVC_MAIN
:
852 case FF_PROFILE_UNKNOWN
:
853 ctx
->va_profile
= VAProfileHEVCMain
;
854 ctx
->va_rt_format
= VA_RT_FORMAT_YUV420
;
856 case FF_PROFILE_HEVC_MAIN_10
:
857 #ifdef VA_RT_FORMAT_YUV420_10BPP
858 ctx
->va_profile
= VAProfileHEVCMain10
;
859 ctx
->va_rt_format
= VA_RT_FORMAT_YUV420_10BPP
;
862 av_log(avctx
, AV_LOG_ERROR
, "10-bit encoding is not "
863 "supported with this VAAPI version.\n");
864 return AVERROR(ENOSYS
);
867 av_log(avctx
, AV_LOG_ERROR
, "Unknown H.265 profile %d.\n",
869 return AVERROR(EINVAL
);
871 ctx
->va_entrypoint
= VAEntrypointEncSlice
;
873 if (avctx
->bit_rate
> 0)
874 ctx
->va_rc_mode
= VA_RC_CBR
;
876 ctx
->va_rc_mode
= VA_RC_CQP
;
878 ctx
->va_packed_headers
=
879 VA_ENC_PACKED_HEADER_SEQUENCE
| // VPS, SPS and PPS.
880 VA_ENC_PACKED_HEADER_SLICE
; // Slice headers.
882 ctx
->surface_width
= FFALIGN(avctx
->width
, 16);
883 ctx
->surface_height
= FFALIGN(avctx
->height
, 16);
885 return ff_vaapi_encode_init(avctx
);
888 static av_cold
int vaapi_encode_h265_close(AVCodecContext
*avctx
)
890 VAAPIEncodeContext
*ctx
= avctx
->priv_data
;
891 VAAPIEncodeH265Context
*priv
= ctx
->priv_data
;
894 ff_cbs_close(&priv
->cbc
);
896 return ff_vaapi_encode_close(avctx
);
899 #define OFFSET(x) (offsetof(VAAPIEncodeContext, codec_options_data) + \
900 offsetof(VAAPIEncodeH265Options, x))
901 #define FLAGS (AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
902 static const AVOption vaapi_encode_h265_options
[] = {
903 { "qp", "Constant QP (for P-frames; scaled by qfactor/qoffset for I/B)",
904 OFFSET(qp
), AV_OPT_TYPE_INT
, { .i64
= 25 }, 0, 52, FLAGS
},
908 static const AVCodecDefault vaapi_encode_h265_defaults
[] = {
914 { "i_qfactor", "1.0" },
915 { "i_qoffset", "0.0" },
916 { "b_qfactor", "1.2" },
917 { "b_qoffset", "0.0" },
921 static const AVClass vaapi_encode_h265_class
= {
922 .class_name
= "h265_vaapi",
923 .item_name
= av_default_item_name
,
924 .option
= vaapi_encode_h265_options
,
925 .version
= LIBAVUTIL_VERSION_INT
,
928 AVCodec ff_hevc_vaapi_encoder
= {
929 .name
= "hevc_vaapi",
930 .long_name
= NULL_IF_CONFIG_SMALL("H.265/HEVC (VAAPI)"),
931 .type
= AVMEDIA_TYPE_VIDEO
,
932 .id
= AV_CODEC_ID_HEVC
,
933 .priv_data_size
= (sizeof(VAAPIEncodeContext
) +
934 sizeof(VAAPIEncodeH265Options
)),
935 .init
= &vaapi_encode_h265_init
,
936 .encode2
= &ff_vaapi_encode2
,
937 .close
= &vaapi_encode_h265_close
,
938 .priv_class
= &vaapi_encode_h265_class
,
939 .capabilities
= AV_CODEC_CAP_DELAY
,
940 .defaults
= vaapi_encode_h265_defaults
,
941 .pix_fmts
= (const enum AVPixelFormat
[]) {