2 * gstvaapiencoder_h265.c - H.265 encoder
4 * Copyright (C) 2015 Intel Corporation
5 * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public License
9 * as published by the Free Software Foundation; either version 2.1
10 * of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 * Boston, MA 02110-1301 USA
25 #include <gst/base/gstbitwriter.h>
26 #include <gst/codecparsers/gsth265parser.h>
27 #include "gstvaapicompat.h"
28 #include "gstvaapiencoder_priv.h"
29 #include "gstvaapiencoder_h265.h"
30 #include "gstvaapiutils_h265.h"
31 #include "gstvaapiutils_h265_priv.h"
32 #include "gstvaapiutils_h26x_priv.h"
33 #include "gstvaapicodedbufferproxy_priv.h"
34 #include "gstvaapisurface.h"
37 #include "gstvaapidebug.h"
39 /* Supported set of VA rate controls, within this implementation */
40 #define SUPPORTED_RATECONTROLS \
41 (GST_VAAPI_RATECONTROL_MASK (CQP) | \
42 GST_VAAPI_RATECONTROL_MASK (CBR) | \
43 GST_VAAPI_RATECONTROL_MASK (VBR))
45 /* Supported set of tuning options, within this implementation */
46 #define SUPPORTED_TUNE_OPTIONS \
47 (GST_VAAPI_ENCODER_TUNE_MASK (NONE))
49 /* Supported set of VA packed headers, within this implementation */
50 #define SUPPORTED_PACKED_HEADERS \
51 (VA_ENC_PACKED_HEADER_SEQUENCE | \
52 VA_ENC_PACKED_HEADER_PICTURE | \
53 VA_ENC_PACKED_HEADER_SLICE)
57 GstVaapiSurfaceProxy *pic;
59 } GstVaapiEncoderH265Ref;
63 GST_VAAPI_ENC_H265_REORD_NONE = 0,
64 GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES = 1,
65 GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES = 2
66 } GstVaapiEncH265ReorderState;
68 typedef struct _GstVaapiH265RefPool
72 guint max_reflist0_count;
73 guint max_reflist1_count;
74 } GstVaapiH265RefPool;
76 typedef struct _GstVaapiH265ReorderPool
78 GQueue reorder_frame_list;
81 guint cur_present_index;
82 } GstVaapiH265ReorderPool;
84 /* ------------------------------------------------------------------------- */
85 /* --- H.265 Encoder --- */
86 /* ------------------------------------------------------------------------- */
88 struct _GstVaapiEncoderH265
90 GstVaapiEncoder parent_instance;
92 GstVaapiProfile profile;
93 GstVaapiTierH265 tier;
94 GstVaapiLevelH265 level;
96 guint8 max_profile_idc;
97 guint8 hw_max_profile_idc;
104 guint32 ctu_width; /* CTU == Coding Tree Unit */
108 GstClockTime cts_offset;
109 gboolean config_changed;
111 /* maximum required size of the decoded picture buffer */
112 guint32 max_dec_pic_buffering;
113 /* maximum allowed number of pictures that can precede any picture in
114 * the CVS in decoding order and follow that picture in output order */
115 guint32 max_num_reorder_pics;
118 guint32 max_pic_order_cnt;
119 guint32 log2_max_pic_order_cnt;
121 guint num_ref_frames;
127 guint bitrate_bits; // bitrate (bits)
128 guint cpb_length; // length of CPB buffer (ms)
129 guint cpb_length_bits; // length of CPB buffer (bits)
132 guint conformance_window_flag:1;
133 guint32 conf_win_left_offset;
134 guint32 conf_win_right_offset;
135 guint32 conf_win_top_offset;
136 guint32 conf_win_bottom_offset;
138 GstVaapiH265RefPool ref_pool;
139 GstVaapiH265ReorderPool reorder_pool;
140 guint first_slice_segment_in_pic_flag:1;
141 guint sps_temporal_mvp_enabled_flag:1;
142 guint sample_adaptive_offset_enabled_flag:1;
145 static inline gboolean
146 _poc_greater_than (guint poc1, guint poc2, guint max_poc)
148 return (((poc1 - poc2) & (max_poc - 1)) < max_poc / 2);
151 /* Get slice_type value for H.265 specification */
153 h265_get_slice_type (GstVaapiPictureType type)
156 case GST_VAAPI_PICTURE_TYPE_I:
157 return GST_H265_I_SLICE;
158 case GST_VAAPI_PICTURE_TYPE_P:
159 return GST_H265_P_SLICE;
160 case GST_VAAPI_PICTURE_TYPE_B:
161 return GST_H265_B_SLICE;
168 /* Get log2_max_pic_order_cnt value for H.265 specification */
170 h265_get_log2_max_pic_order_cnt (guint num)
182 /* must be greater than 4 */
186 /* Write the NAL unit header */
188 bs_write_nal_header (GstBitWriter * bs, guint32 nal_unit_type)
190 guint8 nuh_layer_id = 0;
191 guint8 nuh_temporal_id_plus1 = 1;
193 WRITE_UINT32 (bs, 0, 1);
194 WRITE_UINT32 (bs, nal_unit_type, 6);
195 WRITE_UINT32 (bs, nuh_layer_id, 6);
196 WRITE_UINT32 (bs, nuh_temporal_id_plus1, 3);
203 GST_WARNING ("failed to write NAL unit header");
208 /* Write the NAL unit trailing bits */
210 bs_write_trailing_bits (GstBitWriter * bs)
212 if (!gst_bit_writer_put_bits_uint32 (bs, 1, 1))
214 gst_bit_writer_align_bytes_unchecked (bs, 0);
220 GST_WARNING ("failed to write NAL unit trailing bits");
225 /* Write profile_tier_level() */
227 bs_write_profile_tier_level (GstBitWriter * bs,
228 const VAEncSequenceParameterBufferHEVC * seq_param)
231 /* general_profile_space */
232 WRITE_UINT32 (bs, 0, 2);
233 /* general_tier_flag */
234 WRITE_UINT32 (bs, seq_param->general_tier_flag, 1);
235 /* general_profile_idc */
236 WRITE_UINT32 (bs, seq_param->general_profile_idc, 5);
237 /* general_profile_compatibility_flag[32] */
238 for (i = 0; i < 32; i++) {
239 if (i == 1 || i == 2)
240 WRITE_UINT32 (bs, 1, 1);
242 WRITE_UINT32 (bs, 0, 1);
244 /* general_progressive_source_flag */
245 WRITE_UINT32 (bs, 1, 1);
246 /* general_interlaced_source_flag */
247 WRITE_UINT32 (bs, 0, 1);
248 /* general_non_packed_constraint_flag */
249 WRITE_UINT32 (bs, 0, 1);
250 /* general_frame_only_constraint_flag */
251 WRITE_UINT32 (bs, 1, 1);
252 /* general_reserved_zero_44bits */
253 for (i = 0; i < 44; i++)
254 WRITE_UINT32 (bs, 0, 1);
255 /* general_level_idc */
256 WRITE_UINT32 (bs, seq_param->general_level_idc, 8);
263 GST_WARNING ("failed to write Profile Tier Level");
268 /* Write an VPS NAL unit */
270 bs_write_vps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder,
271 GstVaapiEncPicture * picture,
272 const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile)
274 guint32 video_parameter_set_id = 0;
275 guint32 vps_max_layers_minus1 = 0;
276 guint32 vps_max_sub_layers_minus1 = 0;
277 guint32 vps_temporal_id_nesting_flag = 1;
278 guint32 vps_sub_layer_ordering_info_present_flag = 0;
279 guint32 vps_max_latency_increase_plus1 = 0;
280 guint32 vps_max_layer_id = 0;
281 guint32 vps_num_layer_sets_minus1 = 0;
282 guint32 vps_timing_info_present_flag = 0;
283 guint32 vps_extension_flag = 0;
285 /* video_parameter_set_id */
286 WRITE_UINT32 (bs, video_parameter_set_id, 4);
287 /* vps_reserved_three_2bits */
288 WRITE_UINT32 (bs, 3, 2);
289 /* vps_max_layers_minus1 */
290 WRITE_UINT32 (bs, vps_max_layers_minus1, 6);
291 /* vps_max_sub_layers_minus1 */
292 WRITE_UINT32 (bs, vps_max_sub_layers_minus1, 3);
293 /* vps_temporal_id_nesting_flag */
294 WRITE_UINT32 (bs, vps_temporal_id_nesting_flag, 1);
295 /* vps_reserved_0xffff_16bits */
296 WRITE_UINT32 (bs, 0xffff, 16);
298 /* profile_tier_level */
299 bs_write_profile_tier_level (bs, seq_param);
301 /* vps_sub_layer_ordering_info_present_flag */
302 WRITE_UINT32 (bs, vps_sub_layer_ordering_info_present_flag, 1);
303 /* vps_max_dec_pic_buffering_minus1 */
304 WRITE_UE (bs, encoder->max_dec_pic_buffering - 1);
305 /* vps_max_num_reorder_pics */
306 WRITE_UE (bs, encoder->max_num_reorder_pics);
307 /* vps_max_latency_increase_plus1 */
308 WRITE_UE (bs, vps_max_latency_increase_plus1);
309 /* vps_max_layer_id */
310 WRITE_UINT32 (bs, vps_max_layer_id, 6);
311 /* vps_num_layer_sets_minus1 */
312 WRITE_UE (bs, vps_num_layer_sets_minus1);
313 /* vps_timing_info_present_flag */
314 WRITE_UINT32 (bs, vps_timing_info_present_flag, 1);
315 /* vps_extension_flag */
316 WRITE_UINT32 (bs, vps_extension_flag, 1);
323 GST_WARNING ("failed to write VPS NAL unit");
329 bs_write_vps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder,
330 GstVaapiEncPicture * picture,
331 const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile)
333 if (!bs_write_vps_data (bs, encoder, picture, seq_param, profile))
336 /* rbsp_trailing_bits */
337 bs_write_trailing_bits (bs);
342 /* Write an SPS NAL unit */
344 bs_write_sps_data (GstBitWriter * bs, GstVaapiEncoderH265 * encoder,
345 GstVaapiEncPicture * picture,
346 const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile,
347 const VAEncMiscParameterHRD * hrd_params)
349 guint32 video_parameter_set_id = 0;
350 guint32 max_sub_layers_minus1 = 0;
351 guint32 temporal_id_nesting_flag = 1;
352 guint32 seq_parameter_set_id = 0;
353 guint32 sps_sub_layer_ordering_info_present_flag = 0;
354 guint32 sps_max_latency_increase_plus1 = 0;
355 guint32 num_short_term_ref_pic_sets = 0;
356 guint32 long_term_ref_pics_present_flag = 0;
357 guint32 sps_extension_flag = 0;
358 guint32 nal_hrd_parameters_present_flag = 0;
359 guint maxNumSubLayers = 1, i;
361 /* video_parameter_set_id */
362 WRITE_UINT32 (bs, video_parameter_set_id, 4);
363 /* max_sub_layers_minus1 */
364 WRITE_UINT32 (bs, max_sub_layers_minus1, 3);
365 /* temporal_id_nesting_flag */
366 WRITE_UINT32 (bs, temporal_id_nesting_flag, 1);
368 /* profile_tier_level */
369 bs_write_profile_tier_level (bs, seq_param);
371 /* seq_parameter_set_id */
372 WRITE_UE (bs, seq_parameter_set_id);
373 /* chroma_format_idc = 1, 4:2:0 */
374 WRITE_UE (bs, seq_param->seq_fields.bits.chroma_format_idc);
375 /* pic_width_in_luma_samples */
376 WRITE_UE (bs, seq_param->pic_width_in_luma_samples);
377 /* pic_height_in_luma_samples */
378 WRITE_UE (bs, seq_param->pic_height_in_luma_samples);
380 /* conformance_window_flag */
381 WRITE_UINT32 (bs, encoder->conformance_window_flag, 1);
382 if (encoder->conformance_window_flag) {
383 WRITE_UE (bs, encoder->conf_win_left_offset);
384 WRITE_UE (bs, encoder->conf_win_right_offset);
385 WRITE_UE (bs, encoder->conf_win_top_offset);
386 WRITE_UE (bs, encoder->conf_win_bottom_offset);
389 /* bit_depth_luma_minus8 */
390 WRITE_UE (bs, seq_param->seq_fields.bits.bit_depth_luma_minus8);
391 /* bit_depth_chroma_minus8 */
392 WRITE_UE (bs, seq_param->seq_fields.bits.bit_depth_chroma_minus8);
393 /* log2_max_pic_order_cnt_lsb_minus4 */
394 WRITE_UE (bs, encoder->log2_max_pic_order_cnt - 4);
396 /* sps_sub_layer_ordering_info_present_flag */
397 WRITE_UINT32 (bs, sps_sub_layer_ordering_info_present_flag, 1);
398 /* sps_max_dec_pic_buffering_minus1 */
399 WRITE_UE (bs, encoder->max_dec_pic_buffering - 1);
400 /* sps_max_num_reorder_pics */
401 WRITE_UE (bs, encoder->max_num_reorder_pics);
402 /* sps_max_latency_increase_plus1 */
403 WRITE_UE (bs, sps_max_latency_increase_plus1);
405 /* log2_min_luma_coding_block_size_minus3 */
406 WRITE_UE (bs, seq_param->log2_min_luma_coding_block_size_minus3);
407 /* log2_diff_max_min_luma_coding_block_size */
408 WRITE_UE (bs, seq_param->log2_diff_max_min_luma_coding_block_size);
409 /* log2_min_transform_block_size_minus2 */
410 WRITE_UE (bs, seq_param->log2_min_transform_block_size_minus2);
411 /* log2_diff_max_min_transform_block_size */
412 WRITE_UE (bs, seq_param->log2_diff_max_min_transform_block_size);
413 /* max_transform_hierarchy_depth_inter */
414 WRITE_UE (bs, seq_param->max_transform_hierarchy_depth_inter);
415 /*max_transform_hierarchy_depth_intra */
416 WRITE_UE (bs, seq_param->max_transform_hierarchy_depth_intra);
418 /* scaling_list_enabled_flag */
419 WRITE_UINT32 (bs, seq_param->seq_fields.bits.scaling_list_enabled_flag, 1);
420 /* amp_enabled_flag */
421 WRITE_UINT32 (bs, seq_param->seq_fields.bits.amp_enabled_flag, 1);
422 /* sample_adaptive_offset_enabled_flag */
424 seq_param->seq_fields.bits.sample_adaptive_offset_enabled_flag, 1);
425 /* pcm_enabled_flag */
426 WRITE_UINT32 (bs, seq_param->seq_fields.bits.pcm_enabled_flag, 1);
428 /* num_short_term_ref_pic_sets */
429 WRITE_UE (bs, num_short_term_ref_pic_sets);
431 /* long_term_ref_pics_present_flag */
432 WRITE_UINT32 (bs, long_term_ref_pics_present_flag, 1);
434 /* sps_temporal_mvp_enabled_flag */
435 WRITE_UINT32 (bs, seq_param->seq_fields.bits.sps_temporal_mvp_enabled_flag,
437 /* strong_intra_smoothing_enabled_flag */
439 seq_param->seq_fields.bits.strong_intra_smoothing_enabled_flag, 1);
441 /* vui_parameters_present_flag */
442 WRITE_UINT32 (bs, seq_param->vui_parameters_present_flag, 1);
444 /*--------------- Write VUI Parameters--------------- */
445 if (seq_param->vui_parameters_present_flag) {
446 gboolean vui_hrd_parameters_present_flag;
447 /* aspect_ratio_info_present_flag */
449 seq_param->vui_fields.bits.aspect_ratio_info_present_flag, 1);
450 if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
451 WRITE_UINT32 (bs, seq_param->aspect_ratio_idc, 8);
452 if (seq_param->aspect_ratio_idc == 0xFF) {
453 WRITE_UINT32 (bs, seq_param->sar_width, 16);
454 WRITE_UINT32 (bs, seq_param->sar_height, 16);
457 /* overscan_info_present_flag */
458 WRITE_UINT32 (bs, 0, 1);
459 /* video_signal_type_present_flag */
460 WRITE_UINT32 (bs, 0, 1);
461 /* chroma_loc_info_present_flag */
462 WRITE_UINT32 (bs, 0, 1);
463 /* neutral_chroma_indication_flag */
464 WRITE_UINT32 (bs, seq_param->vui_fields.bits.neutral_chroma_indication_flag,
467 WRITE_UINT32 (bs, seq_param->vui_fields.bits.field_seq_flag, 1);
468 /* frame_field_info_present_flag */
469 WRITE_UINT32 (bs, 0, 1);
470 /* default_display_window_flag */
471 WRITE_UINT32 (bs, 0, 1);
473 /* timing_info_present_flag */
474 WRITE_UINT32 (bs, seq_param->vui_fields.bits.vui_timing_info_present_flag,
476 if (seq_param->vui_fields.bits.vui_timing_info_present_flag) {
477 /* vui_num_units_in_tick */
478 WRITE_UINT32 (bs, seq_param->vui_num_units_in_tick, 32);
480 WRITE_UINT32 (bs, seq_param->vui_time_scale, 32);
481 /* vui_poc_proportional_to_timing_flag */
482 WRITE_UINT32 (bs, 0, 1);
484 /* vui_hrd_parameters_present_flag */
485 vui_hrd_parameters_present_flag = seq_param->bits_per_second > 0;
486 WRITE_UINT32 (bs, vui_hrd_parameters_present_flag, 1);
488 if (vui_hrd_parameters_present_flag) {
489 nal_hrd_parameters_present_flag = 1;
490 /* nal_hrd_parameters_present_flag */
491 WRITE_UINT32 (bs, nal_hrd_parameters_present_flag, 1);
492 /* vcl_hrd_parameters_present_flag */
493 WRITE_UINT32 (bs, 0, 1);
495 if (nal_hrd_parameters_present_flag) {
496 /* sub_pic_hrd_params_present_flag */
497 WRITE_UINT32 (bs, 0, 1);
499 WRITE_UINT32 (bs, SX_BITRATE - 6, 4);
501 WRITE_UINT32 (bs, SX_CPB_SIZE - 4, 4);
502 /* initial_cpb_removal_delay_length_minus1 */
503 WRITE_UINT32 (bs, 23, 5);
504 /* au_cpb_removal_delay_length_minus1 */
505 WRITE_UINT32 (bs, 23, 5);
506 /* dpb_output_delay_length_minus1 */
507 WRITE_UINT32 (bs, 23, 5);
509 for (i = 0; i < maxNumSubLayers; i++) {
510 /* fixed_pic_rate_general_flag */
511 WRITE_UINT32 (bs, 0, 1);
512 /* fixed_pic_rate_within_cvs_flag */
513 WRITE_UINT32 (bs, 0, 1);
514 /* low_delay_hrd_flag */
515 WRITE_UINT32 (bs, 1, 1);
516 /* bit_rate_value_minus1 */
517 WRITE_UE (bs, (seq_param->bits_per_second >> SX_BITRATE) - 1);
518 /* cpb_size_value_minus1 */
519 WRITE_UE (bs, (hrd_params->buffer_size >> SX_CPB_SIZE) - 1);
521 WRITE_UINT32 (bs, 1, 1);
526 /* bitstream_restriction_flag */
527 WRITE_UINT32 (bs, seq_param->vui_fields.bits.bitstream_restriction_flag, 1);
529 /* sps_extension_flag */
530 WRITE_UINT32 (bs, sps_extension_flag, 1);
537 GST_WARNING ("failed to write SPS NAL unit");
543 bs_write_sps (GstBitWriter * bs, GstVaapiEncoderH265 * encoder,
544 GstVaapiEncPicture * picture,
545 const VAEncSequenceParameterBufferHEVC * seq_param, GstVaapiProfile profile,
546 const VAEncMiscParameterHRD * hrd_params)
548 if (!bs_write_sps_data (bs, encoder, picture, seq_param, profile, hrd_params))
551 /* rbsp_trailing_bits */
552 bs_write_trailing_bits (bs);
557 /* Write a PPS NAL unit */
559 bs_write_pps (GstBitWriter * bs,
560 const VAEncPictureParameterBufferHEVC * pic_param)
562 guint32 pic_parameter_set_id = 0;
563 guint32 seq_parameter_set_id = 0;
564 guint32 output_flag_present_flag = 0;
565 guint32 num_extra_slice_header_bits = 0;
566 guint32 cabac_init_present_flag = 0;
567 guint32 pps_slice_chroma_qp_offsets_present_flag = 0;
568 guint32 deblocking_filter_control_present_flag = 0;
569 guint32 lists_modification_present_flag = 0;
570 guint32 slice_segment_header_extension_present_flag = 0;
571 guint32 pps_extension_flag = 0;
573 /* pic_parameter_set_id */
574 WRITE_UE (bs, pic_parameter_set_id);
575 /* seq_parameter_set_id */
576 WRITE_UE (bs, seq_parameter_set_id);
577 /* dependent_slice_segments_enabled_flag */
579 pic_param->pic_fields.bits.dependent_slice_segments_enabled_flag, 1);
580 /* output_flag_present_flag */
581 WRITE_UINT32 (bs, output_flag_present_flag, 1);
582 /* num_extra_slice_header_bits */
583 WRITE_UINT32 (bs, num_extra_slice_header_bits, 3);
584 /* sign_data_hiding_enabled_flag */
585 WRITE_UINT32 (bs, pic_param->pic_fields.bits.sign_data_hiding_enabled_flag,
587 /* cabac_init_present_flag */
588 WRITE_UINT32 (bs, cabac_init_present_flag, 1);
589 /* num_ref_idx_l0_default_active_minus1 */
590 WRITE_UE (bs, pic_param->num_ref_idx_l0_default_active_minus1);
591 /* num_ref_idx_l1_default_active_minus1 */
592 WRITE_UE (bs, pic_param->num_ref_idx_l1_default_active_minus1);
593 /* pic_init_qp_minus26 */
594 WRITE_SE (bs, pic_param->pic_init_qp - 26);
595 /* constrained_intra_pred_flag */
596 WRITE_UINT32 (bs, pic_param->pic_fields.bits.constrained_intra_pred_flag, 1);
597 /* transform_skip_enabled_flag */
598 WRITE_UINT32 (bs, pic_param->pic_fields.bits.transform_skip_enabled_flag, 1);
599 /* cu_qp_delta_enabled_flag */
600 WRITE_UINT32 (bs, pic_param->pic_fields.bits.cu_qp_delta_enabled_flag, 1);
601 /* diff_cu_qp_delta_depth */
602 if (pic_param->pic_fields.bits.cu_qp_delta_enabled_flag)
603 WRITE_UE (bs, pic_param->diff_cu_qp_delta_depth);
605 /* pps_cb_qp_offset */
606 WRITE_SE (bs, pic_param->pps_cb_qp_offset);
607 /* pps_cr_qp_offset */
608 WRITE_SE (bs, pic_param->pps_cr_qp_offset);
609 /* pps_slice_chroma_qp_offsets_present_flag */
610 WRITE_UINT32 (bs, pps_slice_chroma_qp_offsets_present_flag, 1);
611 /* weighted_pred_flag */
612 WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_pred_flag, 1);
613 /* weighted_bipred_flag */
614 WRITE_UINT32 (bs, pic_param->pic_fields.bits.weighted_bipred_flag, 1);
615 /* transquant_bypass_enabled_flag */
616 WRITE_UINT32 (bs, pic_param->pic_fields.bits.transquant_bypass_enabled_flag,
618 /* tiles_enabled_flag */
619 WRITE_UINT32 (bs, pic_param->pic_fields.bits.tiles_enabled_flag, 1);
620 /* entropy_coding_sync_enabled_flag */
621 WRITE_UINT32 (bs, pic_param->pic_fields.bits.entropy_coding_sync_enabled_flag,
623 /* pps_loop_filter_across_slices_enabled_flag */
625 pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag, 1);
626 /* deblocking_filter_control_present_flag */
627 WRITE_UINT32 (bs, deblocking_filter_control_present_flag, 1);
628 /* pps_scaling_list_data_present_flag */
629 WRITE_UINT32 (bs, pic_param->pic_fields.bits.scaling_list_data_present_flag,
631 /* lists_modification_present_flag */
632 WRITE_UINT32 (bs, lists_modification_present_flag, 1);
633 /* log2_parallel_merge_level_minus2 */
634 WRITE_UE (bs, pic_param->log2_parallel_merge_level_minus2);
635 /* slice_segment_header_extension_present_flag */
636 WRITE_UINT32 (bs, slice_segment_header_extension_present_flag, 1);
637 /* pps_extension_flag */
638 WRITE_UINT32 (bs, pps_extension_flag, 1);
640 /* rbsp_trailing_bits */
641 bs_write_trailing_bits (bs);
648 GST_WARNING ("failed to write PPS NAL unit");
653 /* Write a Slice NAL unit */
655 bs_write_slice (GstBitWriter * bs,
656 const VAEncSliceParameterBufferHEVC * slice_param,
657 GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
658 guint8 nal_unit_type)
660 const VAEncPictureParameterBufferHEVC *const pic_param = picture->param;
662 guint8 no_output_of_prior_pics_flag = 0;
663 guint8 dependent_slice_segment_flag = 0;
664 guint8 short_term_ref_pic_set_sps_flag = 0;
665 guint8 slice_deblocking_filter_disabled_flag = 0;
666 guint8 num_ref_idx_active_override_flag =
667 slice_param->slice_fields.bits.num_ref_idx_active_override_flag;
669 /* first_slice_segment_in_pic_flag */
670 WRITE_UINT32 (bs, encoder->first_slice_segment_in_pic_flag, 1);
672 /* FIXME: For all IRAP pics */
673 /* no_output_of_prior_pics_flag */
674 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
675 WRITE_UINT32 (bs, no_output_of_prior_pics_flag, 1);
677 /* slice_pic_parameter_set_id */
678 WRITE_UE (bs, slice_param->slice_pic_parameter_set_id);
680 /* slice_segment_address , bits_size = Ceil(Log2(PicSizeInCtbsY)) */
681 if (!encoder->first_slice_segment_in_pic_flag) {
682 guint pic_size_ctb = encoder->ctu_width * encoder->ctu_height;
683 guint bits_size = (guint) ceil ((log2 (pic_size_ctb)));
684 WRITE_UINT32 (bs, slice_param->slice_segment_address, bits_size);
687 if (!dependent_slice_segment_flag) {
689 WRITE_UE (bs, slice_param->slice_type);
691 if (!pic_param->pic_fields.bits.idr_pic_flag) {
692 /* slice_pic_order_cnt_lsb */
693 WRITE_UINT32 (bs, picture->poc, encoder->log2_max_pic_order_cnt);
694 /* short_term_ref_pic_set_sps_flag */
695 WRITE_UINT32 (bs, short_term_ref_pic_set_sps_flag, 1);
697 /*---------- Write short_term_ref_pic_set(0) ----------- */
699 guint num_positive_pics = 0, num_negative_pics = 0;
700 guint delta_poc_s0_minus1 = 0, delta_poc_s1_minus1 = 0;
701 guint used_by_curr_pic_s0_flag = 0, used_by_curr_pic_s1_flag = 0;
702 guint reflist_0_count = 0, reflist_1_count = 0;
705 /* Get count of ref_pic_list */
706 if (picture->type == GST_VAAPI_PICTURE_TYPE_P
707 || picture->type == GST_VAAPI_PICTURE_TYPE_B) {
708 for (i = 0; i < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i) {
709 if (slice_param->ref_pic_list0[i].picture_id == VA_INVALID_SURFACE)
714 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
715 for (i = 0; i < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i) {
716 if (slice_param->ref_pic_list1[i].picture_id ==
724 if (picture->type == GST_VAAPI_PICTURE_TYPE_P) {
725 delta_poc_s0_minus1 =
726 picture->poc - slice_param->ref_pic_list0[0].pic_order_cnt - 1;
727 used_by_curr_pic_s0_flag = 1;
728 delta_poc_s1_minus1 = 0;
729 used_by_curr_pic_s1_flag = 0;
731 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
732 delta_poc_s0_minus1 =
733 picture->poc - slice_param->ref_pic_list0[0].pic_order_cnt - 1;
734 used_by_curr_pic_s0_flag = 1;
735 delta_poc_s1_minus1 =
736 slice_param->ref_pic_list1[0].pic_order_cnt - picture->poc - 1;
737 used_by_curr_pic_s1_flag = 1;
740 num_negative_pics = reflist_0_count;
741 num_positive_pics = reflist_1_count;
743 /* num_negative_pics */
744 WRITE_UE (bs, num_negative_pics);
745 /* num_positive_pics */
746 WRITE_UE (bs, num_positive_pics);
748 for (i = 0; i < num_negative_pics; i++) {
749 /* delta_poc_s0_minus1 */
751 WRITE_UE (bs, delta_poc_s0_minus1);
754 slice_param->ref_pic_list0[i - 1].pic_order_cnt -
755 slice_param->ref_pic_list0[i].pic_order_cnt - 1);
757 /* used_by_curr_pic_s0_flag */
758 WRITE_UINT32 (bs, used_by_curr_pic_s0_flag, 1);
760 for (i = 0; i < num_positive_pics; i++) {
761 /* delta_poc_s1_minus1 */
763 WRITE_UE (bs, delta_poc_s1_minus1);
766 slice_param->ref_pic_list1[i - 1].pic_order_cnt -
767 slice_param->ref_pic_list1[i].pic_order_cnt - 1);
769 /* used_by_curr_pic_s1_flag */
770 WRITE_UINT32 (bs, used_by_curr_pic_s1_flag, 1);
774 /* slice_temporal_mvp_enabled_flag */
775 if (encoder->sps_temporal_mvp_enabled_flag)
777 slice_param->slice_fields.bits.slice_temporal_mvp_enabled_flag, 1);
780 if (encoder->sample_adaptive_offset_enabled_flag) {
781 WRITE_UINT32 (bs, slice_param->slice_fields.bits.slice_sao_luma_flag, 1);
782 WRITE_UINT32 (bs, slice_param->slice_fields.bits.slice_sao_chroma_flag,
786 if (slice_param->slice_type == GST_H265_P_SLICE ||
787 slice_param->slice_type == GST_H265_B_SLICE) {
788 /* num_ref_idx_active_override_flag */
789 WRITE_UINT32 (bs, num_ref_idx_active_override_flag, 1);
790 if (num_ref_idx_active_override_flag) {
791 WRITE_UE (bs, slice_param->num_ref_idx_l0_active_minus1);
792 if (slice_param->slice_type == GST_H265_B_SLICE)
793 WRITE_UE (bs, slice_param->num_ref_idx_l1_active_minus1);
796 /* mvd_l1_zero_flag */
797 if (slice_param->slice_type == GST_H265_B_SLICE)
798 WRITE_UINT32 (bs, slice_param->slice_fields.bits.mvd_l1_zero_flag, 1);
800 /* cabac_init_present_flag == FALSE */
801 /* cabac_init_flag = FALSE */
803 /* collocated_from_l0_flag */
804 if (slice_param->slice_fields.bits.slice_temporal_mvp_enabled_flag) {
805 if (slice_param->slice_type == GST_H265_B_SLICE)
807 slice_param->slice_fields.bits.collocated_from_l0_flag, 1);
809 /* five_minus_max_num_merge_cand */
810 WRITE_UE (bs, 5 - slice_param->max_num_merge_cand);
814 WRITE_SE (bs, slice_param->slice_qp_delta);
815 if (pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag &&
816 (slice_param->slice_fields.bits.slice_sao_luma_flag
817 || slice_param->slice_fields.bits.slice_sao_chroma_flag
818 || !slice_deblocking_filter_disabled_flag))
820 slice_param->slice_fields.bits.
821 slice_loop_filter_across_slices_enabled_flag, 1);
825 /* byte_alignment() */
827 /* alignment_bit_equal_to_one */
828 WRITE_UINT32 (bs, 1, 1);
829 while (GST_BIT_WRITER_BIT_SIZE (bs) % 8 != 0) {
830 /* alignment_bit_equal_to_zero */
831 WRITE_UINT32 (bs, 0, 1);
840 GST_WARNING ("failed to write Slice NAL unit");
846 _check_vps_sps_pps_status (GstVaapiEncoderH265 * encoder,
847 const guint8 * nal, guint32 size)
850 G_GNUC_UNUSED gsize ret; /* FIXME */
853 if (encoder->vps_data && encoder->sps_data && encoder->pps_data)
856 nal_type = (nal[0] & 0x7E) >> 1;
858 case GST_H265_NAL_VPS:
859 encoder->vps_data = gst_buffer_new_allocate (NULL, size, NULL);
860 ret = gst_buffer_fill (encoder->vps_data, 0, nal, size);
861 g_assert (ret == size);
863 case GST_H265_NAL_SPS:
864 encoder->sps_data = gst_buffer_new_allocate (NULL, size, NULL);
865 ret = gst_buffer_fill (encoder->sps_data, 0, nal, size);
866 g_assert (ret == size);
868 case GST_H265_NAL_PPS:
869 encoder->pps_data = gst_buffer_new_allocate (NULL, size, NULL);
870 ret = gst_buffer_fill (encoder->pps_data, 0, nal, size);
871 g_assert (ret == size);
878 /* Determines the largest supported profile by the underlying hardware */
880 ensure_hw_profile_limits (GstVaapiEncoderH265 * encoder)
882 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
884 guint i, profile_idc, max_profile_idc;
886 if (encoder->hw_max_profile_idc)
889 profiles = gst_vaapi_display_get_encode_profiles (display);
894 for (i = 0; i < profiles->len; i++) {
895 const GstVaapiProfile profile =
896 g_array_index (profiles, GstVaapiProfile, i);
897 profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile);
900 if (max_profile_idc < profile_idc)
901 max_profile_idc = profile_idc;
903 g_array_unref (profiles);
905 encoder->hw_max_profile_idc = max_profile_idc;
909 /* Derives the profile supported by the underlying hardware */
911 ensure_hw_profile (GstVaapiEncoderH265 * encoder)
913 GstVaapiDisplay *const display = GST_VAAPI_ENCODER_DISPLAY (encoder);
914 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_SLICE_ENCODE;
915 GstVaapiProfile profile, profiles[4];
916 guint i, num_profiles = 0;
918 profiles[num_profiles++] = encoder->profile;
919 switch (encoder->profile) {
920 case GST_VAAPI_PROFILE_H265_MAIN_STILL_PICTURE:
921 profiles[num_profiles++] = GST_VAAPI_PROFILE_H265_MAIN;
923 case GST_VAAPI_PROFILE_H265_MAIN:
924 profiles[num_profiles++] = GST_VAAPI_PROFILE_H265_MAIN10;
930 profile = GST_VAAPI_PROFILE_UNKNOWN;
931 for (i = 0; i < num_profiles; i++) {
932 if (gst_vaapi_display_has_encoder (display, profiles[i], entrypoint)) {
933 profile = profiles[i];
937 if (profile == GST_VAAPI_PROFILE_UNKNOWN)
938 goto error_unsupported_profile;
940 GST_VAAPI_ENCODER_CAST (encoder)->profile = profile;
944 error_unsupported_profile:
946 GST_ERROR ("unsupported HW profile %s",
947 gst_vaapi_profile_get_name (encoder->profile));
952 /* Check target decoder constraints */
954 ensure_profile_limits (GstVaapiEncoderH265 * encoder)
957 if (!encoder->max_profile_idc
958 || encoder->profile_idc <= encoder->max_profile_idc)
962 ("Needs to lower coding tools to meet target decoder constraints");
963 GST_WARNING ("Only supporting Main profile, reset profile to Main");
965 encoder->profile = GST_VAAPI_PROFILE_H265_MAIN;
966 encoder->profile_idc =
967 gst_vaapi_utils_h265_get_profile_idc (encoder->profile);
972 /* Derives the minimum profile from the active coding tools */
974 ensure_profile (GstVaapiEncoderH265 * encoder)
976 GstVaapiProfile profile;
977 const GstVideoFormat format =
978 GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder));
980 /* Always start from "Main" profile for maximum
982 profile = GST_VAAPI_PROFILE_H265_MAIN;
984 if (format == GST_VIDEO_FORMAT_P010_10LE)
985 profile = GST_VAAPI_PROFILE_H265_MAIN10;
987 encoder->profile = profile;
988 encoder->profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile);
992 /* Derives the minimum tier from the active coding tools */
994 ensure_tier (GstVaapiEncoderH265 * encoder)
997 encoder->tier = GST_VAAPI_TIER_H265_MAIN;
998 /* FIXME: Derive proper tier based on upstream caps or limits, coding
1004 /* Derives the level from the currently set limits */
1006 ensure_level (GstVaapiEncoderH265 * encoder)
1008 const GstVaapiH265LevelLimits *limits_table;
1009 guint i, num_limits, PicSizeInSamplesY;
1011 PicSizeInSamplesY = encoder->luma_width * encoder->luma_height;
1013 limits_table = gst_vaapi_utils_h265_get_level_limits_table (&num_limits);
1014 for (i = 0; i < num_limits; i++) {
1015 const GstVaapiH265LevelLimits *const limits = &limits_table[i];
1016 if (PicSizeInSamplesY <= limits->MaxLumaPs)
1018 /* FIXME: Add more constraint checking:tier (extracted from caps),
1019 * cpb size, bitrate, num_tile_columns and num_tile_rows */
1021 if (i == num_limits)
1022 goto error_unsupported_level;
1024 encoder->level = limits_table[i].level;
1025 encoder->level_idc = limits_table[i].level_idc;
1029 error_unsupported_level:
1031 GST_ERROR ("failed to find a suitable level matching codec config");
1036 /* Enable "high-compression" tuning options */
1038 ensure_tuning_high_compression (GstVaapiEncoderH265 * encoder)
1042 if (!ensure_hw_profile_limits (encoder))
1045 profile_idc = encoder->hw_max_profile_idc;
1046 if (encoder->max_profile_idc && encoder->max_profile_idc < profile_idc)
1047 profile_idc = encoder->max_profile_idc;
1049 /* Tuning options */
1050 if (!encoder->num_bframes)
1051 encoder->num_bframes = 3;
1056 /* Ensure tuning options */
1058 ensure_tuning (GstVaapiEncoderH265 * encoder)
1062 switch (GST_VAAPI_ENCODER_TUNE (encoder)) {
1063 case GST_VAAPI_ENCODER_TUNE_HIGH_COMPRESSION:
1064 success = ensure_tuning_high_compression (encoder);
1073 /* Handle new GOP starts */
1075 reset_gop_start (GstVaapiEncoderH265 * encoder)
1077 GstVaapiH265ReorderPool *const reorder_pool = &encoder->reorder_pool;
1079 reorder_pool->frame_index = 1;
1080 reorder_pool->cur_present_index = 0;
1084 /* Marks the supplied picture as a B-frame */
1086 set_b_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder)
1088 g_assert (pic && encoder);
1089 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1090 pic->type = GST_VAAPI_PICTURE_TYPE_B;
1093 /* Marks the supplied picture as a P-frame */
1095 set_p_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder)
1097 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1098 pic->type = GST_VAAPI_PICTURE_TYPE_P;
1101 /* Marks the supplied picture as an I-frame */
1103 set_i_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder)
1105 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1106 pic->type = GST_VAAPI_PICTURE_TYPE_I;
1108 g_assert (pic->frame);
1109 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
1112 /* Marks the supplied picture as an IDR frame */
1114 set_idr_frame (GstVaapiEncPicture * pic, GstVaapiEncoderH265 * encoder)
1116 g_return_if_fail (pic->type == GST_VAAPI_PICTURE_TYPE_NONE);
1117 pic->type = GST_VAAPI_PICTURE_TYPE_I;
1119 GST_VAAPI_ENC_PICTURE_FLAG_SET (pic, GST_VAAPI_ENC_PICTURE_FLAG_IDR);
1121 g_assert (pic->frame);
1122 GST_VIDEO_CODEC_FRAME_SET_SYNC_POINT (pic->frame);
1125 /* Marks the supplied picture a a key-frame */
1127 set_key_frame (GstVaapiEncPicture * picture,
1128 GstVaapiEncoderH265 * encoder, gboolean is_idr)
1131 reset_gop_start (encoder);
1132 set_idr_frame (picture, encoder);
1134 set_i_frame (picture, encoder);
1137 /* Fills in VA HRD parameters */
1139 fill_hrd_params (GstVaapiEncoderH265 * encoder, VAEncMiscParameterHRD * hrd)
1141 if (encoder->bitrate_bits > 0) {
1142 hrd->buffer_size = encoder->cpb_length_bits;
1143 hrd->initial_buffer_fullness = hrd->buffer_size / 2;
1145 hrd->buffer_size = 0;
1146 hrd->initial_buffer_fullness = 0;
1150 /* Adds the supplied video parameter set header (VPS) to the list of packed
1151 headers to pass down as-is to the encoder */
1153 add_packed_vps_header (GstVaapiEncoderH265 * encoder,
1154 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
1156 GstVaapiEncPackedHeader *packed_vps;
1158 VAEncPackedHeaderParameterBuffer packed_vps_param = { 0 };
1159 const VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param;
1160 GstVaapiProfile profile = encoder->profile;
1162 guint32 data_bit_size;
1165 gst_bit_writer_init (&bs, 128 * 8);
1166 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1167 bs_write_nal_header (&bs, GST_H265_NAL_VPS);
1169 bs_write_vps (&bs, encoder, picture, seq_param, profile);
1171 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1172 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1173 data = GST_BIT_WRITER_DATA (&bs);
1175 packed_vps_param.type = VAEncPackedHeaderSequence;
1176 packed_vps_param.bit_length = data_bit_size;
1177 packed_vps_param.has_emulation_bytes = 0;
1179 packed_vps = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1180 &packed_vps_param, sizeof (packed_vps_param),
1181 data, (data_bit_size + 7) / 8);
1182 g_assert (packed_vps);
1184 gst_vaapi_enc_picture_add_packed_header (picture, packed_vps);
1185 gst_vaapi_codec_object_replace (&packed_vps, NULL);
1187 /* store vps data */
1188 _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1189 gst_bit_writer_clear (&bs, TRUE);
1195 GST_WARNING ("failed to write VPS NAL unit");
1196 gst_bit_writer_clear (&bs, TRUE);
1201 /* Adds the supplied sequence header (SPS) to the list of packed
1202 headers to pass down as-is to the encoder */
1204 add_packed_sequence_header (GstVaapiEncoderH265 * encoder,
1205 GstVaapiEncPicture * picture, GstVaapiEncSequence * sequence)
1207 GstVaapiEncPackedHeader *packed_seq;
1209 VAEncPackedHeaderParameterBuffer packed_seq_param = { 0 };
1210 const VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param;
1211 GstVaapiProfile profile = encoder->profile;
1213 VAEncMiscParameterHRD hrd_params;
1214 guint32 data_bit_size;
1217 fill_hrd_params (encoder, &hrd_params);
1219 gst_bit_writer_init (&bs, 128 * 8);
1220 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1221 bs_write_nal_header (&bs, GST_H265_NAL_SPS);
1223 bs_write_sps (&bs, encoder, picture, seq_param, profile, &hrd_params);
1225 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1226 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1227 data = GST_BIT_WRITER_DATA (&bs);
1229 packed_seq_param.type = VAEncPackedHeaderSequence;
1230 packed_seq_param.bit_length = data_bit_size;
1231 packed_seq_param.has_emulation_bytes = 0;
1233 packed_seq = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1234 &packed_seq_param, sizeof (packed_seq_param),
1235 data, (data_bit_size + 7) / 8);
1236 g_assert (packed_seq);
1238 gst_vaapi_enc_picture_add_packed_header (picture, packed_seq);
1239 gst_vaapi_codec_object_replace (&packed_seq, NULL);
1241 /* store sps data */
1242 _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1243 gst_bit_writer_clear (&bs, TRUE);
1249 GST_WARNING ("failed to write SPS NAL unit");
1250 gst_bit_writer_clear (&bs, TRUE);
1255 /* Adds the supplied picture header (PPS) to the list of packed
1256 headers to pass down as-is to the encoder */
1258 add_packed_picture_header (GstVaapiEncoderH265 * encoder,
1259 GstVaapiEncPicture * picture)
1261 GstVaapiEncPackedHeader *packed_pic;
1263 VAEncPackedHeaderParameterBuffer packed_pic_param = { 0 };
1264 const VAEncPictureParameterBufferHEVC *const pic_param = picture->param;
1265 guint32 data_bit_size;
1268 gst_bit_writer_init (&bs, 128 * 8);
1269 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1270 bs_write_nal_header (&bs, GST_H265_NAL_PPS);
1271 bs_write_pps (&bs, pic_param);
1272 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
1273 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1274 data = GST_BIT_WRITER_DATA (&bs);
1276 packed_pic_param.type = VAEncPackedHeaderPicture;
1277 packed_pic_param.bit_length = data_bit_size;
1278 packed_pic_param.has_emulation_bytes = 0;
1280 packed_pic = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1281 &packed_pic_param, sizeof (packed_pic_param),
1282 data, (data_bit_size + 7) / 8);
1283 g_assert (packed_pic);
1285 gst_vaapi_enc_picture_add_packed_header (picture, packed_pic);
1286 gst_vaapi_codec_object_replace (&packed_pic, NULL);
1288 /* store pps data */
1289 _check_vps_sps_pps_status (encoder, data + 4, data_bit_size / 8 - 4);
1290 gst_bit_writer_clear (&bs, TRUE);
1296 GST_WARNING ("failed to write PPS NAL unit");
1297 gst_bit_writer_clear (&bs, TRUE);
1303 get_nal_unit_type (GstVaapiEncPicture * picture, guint8 * nal_unit_type)
1305 switch (picture->type) {
1306 case GST_VAAPI_PICTURE_TYPE_I:
1307 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
1308 *nal_unit_type = GST_H265_NAL_SLICE_IDR_W_RADL;
1310 *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_R;
1312 case GST_VAAPI_PICTURE_TYPE_P:
1313 *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_R;
1315 case GST_VAAPI_PICTURE_TYPE_B:
1316 *nal_unit_type = GST_H265_NAL_SLICE_TRAIL_N;
1324 /* Adds the supplied slice header to the list of packed
1325 headers to pass down as-is to the encoder */
1327 add_packed_slice_header (GstVaapiEncoderH265 * encoder,
1328 GstVaapiEncPicture * picture, GstVaapiEncSlice * slice)
1330 GstVaapiEncPackedHeader *packed_slice;
1332 VAEncPackedHeaderParameterBuffer packed_slice_param = { 0 };
1333 const VAEncSliceParameterBufferHEVC *const slice_param = slice->param;
1334 guint32 data_bit_size;
1336 guint8 nal_unit_type;
1338 gst_bit_writer_init (&bs, 128 * 8);
1339 WRITE_UINT32 (&bs, 0x00000001, 32); /* start code */
1341 if (!get_nal_unit_type (picture, &nal_unit_type))
1343 bs_write_nal_header (&bs, nal_unit_type);
1345 bs_write_slice (&bs, slice_param, encoder, picture, nal_unit_type);
1346 data_bit_size = GST_BIT_WRITER_BIT_SIZE (&bs);
1347 data = GST_BIT_WRITER_DATA (&bs);
1349 packed_slice_param.type = VAEncPackedHeaderSlice;
1350 packed_slice_param.bit_length = data_bit_size;
1351 packed_slice_param.has_emulation_bytes = 0;
1353 packed_slice = gst_vaapi_enc_packed_header_new (GST_VAAPI_ENCODER (encoder),
1354 &packed_slice_param, sizeof (packed_slice_param),
1355 data, (data_bit_size + 7) / 8);
1356 g_assert (packed_slice);
1358 gst_vaapi_enc_slice_add_packed_header (slice, packed_slice);
1359 gst_vaapi_codec_object_replace (&packed_slice, NULL);
1361 gst_bit_writer_clear (&bs, TRUE);
1367 GST_WARNING ("failed to write Slice NAL unit header");
1368 gst_bit_writer_clear (&bs, TRUE);
1373 /* Reference picture management */
1375 reference_pic_free (GstVaapiEncoderH265 * encoder, GstVaapiEncoderH265Ref * ref)
1380 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), ref->pic);
1381 g_slice_free (GstVaapiEncoderH265Ref, ref);
1384 static inline GstVaapiEncoderH265Ref *
1385 reference_pic_create (GstVaapiEncoderH265 * encoder,
1386 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1388 GstVaapiEncoderH265Ref *const ref = g_slice_new0 (GstVaapiEncoderH265Ref);
1391 ref->poc = picture->poc;
1396 reference_list_update (GstVaapiEncoderH265 * encoder,
1397 GstVaapiEncPicture * picture, GstVaapiSurfaceProxy * surface)
1399 GstVaapiEncoderH265Ref *ref;
1400 GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool;
1402 if (GST_VAAPI_PICTURE_TYPE_B == picture->type) {
1403 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder), surface);
1407 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture)) {
1408 while (!g_queue_is_empty (&ref_pool->ref_list))
1409 reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
1410 } else if (g_queue_get_length (&ref_pool->ref_list) >=
1411 ref_pool->max_ref_frames) {
1412 reference_pic_free (encoder, g_queue_pop_head (&ref_pool->ref_list));
1414 ref = reference_pic_create (encoder, picture, surface);
1415 g_queue_push_tail (&ref_pool->ref_list, ref);
1416 g_assert (g_queue_get_length (&ref_pool->ref_list) <=
1417 ref_pool->max_ref_frames);
1422 reference_list_init (GstVaapiEncoderH265 * encoder,
1423 GstVaapiEncPicture * picture,
1424 GstVaapiEncoderH265Ref ** reflist_0,
1425 guint * reflist_0_count,
1426 GstVaapiEncoderH265Ref ** reflist_1, guint * reflist_1_count)
1428 GstVaapiEncoderH265Ref *tmp;
1429 GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool;
1430 GList *iter, *list_0_start = NULL, *list_1_start = NULL;
1433 *reflist_0_count = 0;
1434 *reflist_1_count = 0;
1435 if (picture->type == GST_VAAPI_PICTURE_TYPE_I)
1438 iter = g_queue_peek_tail_link (&ref_pool->ref_list);
1439 for (; iter; iter = g_list_previous (iter)) {
1440 tmp = (GstVaapiEncoderH265Ref *) iter->data;
1441 g_assert (tmp && tmp->poc != picture->poc);
1442 if (_poc_greater_than (picture->poc, tmp->poc, encoder->max_pic_order_cnt)) {
1443 list_0_start = iter;
1444 list_1_start = g_list_next (iter);
1449 /* order reflist_0 */
1450 g_assert (list_0_start);
1451 iter = list_0_start;
1453 for (; iter; iter = g_list_previous (iter)) {
1454 reflist_0[count] = (GstVaapiEncoderH265Ref *) iter->data;
1457 *reflist_0_count = count;
1459 if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
1462 /* order reflist_1 */
1464 iter = list_1_start;
1465 for (; iter; iter = g_list_next (iter)) {
1466 reflist_1[count] = (GstVaapiEncoderH265Ref *) iter->data;
1469 *reflist_1_count = count;
1473 /* Fills in VA sequence parameter buffer */
1475 fill_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncSequence * sequence)
1477 VAEncSequenceParameterBufferHEVC *const seq_param = sequence->param;
1478 const GstVideoFormat format =
1479 GST_VIDEO_INFO_FORMAT (GST_VAAPI_ENCODER_VIDEO_INFO (encoder));
1480 guint bits_depth_luma_minus8 =
1481 GST_VIDEO_FORMAT_INFO_DEPTH (gst_video_format_get_info (format), 0);
1482 if (bits_depth_luma_minus8 < 8)
1484 bits_depth_luma_minus8 -= 8;
1486 memset (seq_param, 0, sizeof (VAEncSequenceParameterBufferHEVC));
1488 seq_param->general_profile_idc = encoder->profile_idc;
1489 seq_param->general_level_idc = encoder->level_idc;
1490 seq_param->general_tier_flag = 0; /* FIXME: use the tier flag
1491 * extracted from upstream
1492 * caps or calcuted one */
1494 seq_param->intra_period = GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder);
1495 seq_param->intra_idr_period = encoder->idr_period;
1496 seq_param->ip_period = seq_param->intra_period > 1 ?
1497 (1 + encoder->num_bframes) : 0;
1498 seq_param->bits_per_second = encoder->bitrate_bits;
1500 seq_param->pic_width_in_luma_samples = encoder->luma_width;
1501 seq_param->pic_height_in_luma_samples = encoder->luma_height;
1503 /*sequence field values */
1504 seq_param->seq_fields.value = 0;
1505 seq_param->seq_fields.bits.chroma_format_idc = 1;
1506 seq_param->seq_fields.bits.separate_colour_plane_flag = 0;
1507 seq_param->seq_fields.bits.bit_depth_luma_minus8 = bits_depth_luma_minus8;
1508 seq_param->seq_fields.bits.bit_depth_chroma_minus8 = bits_depth_luma_minus8;
1509 seq_param->seq_fields.bits.scaling_list_enabled_flag = FALSE;
1510 seq_param->seq_fields.bits.strong_intra_smoothing_enabled_flag = TRUE;
1511 seq_param->seq_fields.bits.amp_enabled_flag = TRUE;
1512 seq_param->seq_fields.bits.sample_adaptive_offset_enabled_flag =
1513 encoder->sample_adaptive_offset_enabled_flag = FALSE;
1514 seq_param->seq_fields.bits.pcm_enabled_flag = FALSE;
1515 seq_param->seq_fields.bits.pcm_loop_filter_disabled_flag = FALSE;
1516 seq_param->seq_fields.bits.sps_temporal_mvp_enabled_flag =
1517 encoder->sps_temporal_mvp_enabled_flag = TRUE;
1519 /* Based on 32x32 CTU */
1520 seq_param->log2_min_luma_coding_block_size_minus3 = 0;
1521 seq_param->log2_diff_max_min_luma_coding_block_size = 2;
1522 seq_param->log2_min_transform_block_size_minus2 = 0;
1523 seq_param->log2_diff_max_min_transform_block_size = 3;
1524 seq_param->max_transform_hierarchy_depth_inter = 3;
1525 seq_param->max_transform_hierarchy_depth_intra = 3;
1527 seq_param->pcm_sample_bit_depth_luma_minus1 = 0;
1528 seq_param->pcm_sample_bit_depth_chroma_minus1 = 0;
1529 seq_param->log2_min_pcm_luma_coding_block_size_minus3 = 0;
1530 seq_param->log2_max_pcm_luma_coding_block_size_minus3 = 0;
1532 /* VUI parameters are always set, at least for timing_info (framerate) */
1533 seq_param->vui_parameters_present_flag = TRUE;
1534 if (seq_param->vui_parameters_present_flag) {
1535 seq_param->vui_fields.bits.aspect_ratio_info_present_flag = TRUE;
1536 if (seq_param->vui_fields.bits.aspect_ratio_info_present_flag) {
1537 const GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
1538 seq_param->aspect_ratio_idc = 0xff;
1539 seq_param->sar_width = GST_VIDEO_INFO_PAR_N (vip);
1540 seq_param->sar_height = GST_VIDEO_INFO_PAR_D (vip);
1542 seq_param->vui_fields.bits.bitstream_restriction_flag = FALSE;
1543 seq_param->vui_fields.bits.vui_timing_info_present_flag = TRUE;
1544 if (seq_param->vui_fields.bits.vui_timing_info_present_flag) {
1545 seq_param->vui_num_units_in_tick = GST_VAAPI_ENCODER_FPS_D (encoder);
1546 seq_param->vui_time_scale = GST_VAAPI_ENCODER_FPS_N (encoder);
1552 /* Fills in VA picture parameter buffer */
1554 fill_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
1555 GstVaapiCodedBuffer * codedbuf, GstVaapiSurfaceProxy * surface)
1557 VAEncPictureParameterBufferHEVC *const pic_param = picture->param;
1558 GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool;
1559 GstVaapiEncoderH265Ref *ref_pic;
1562 guint8 nal_unit_type, no_output_of_prior_pics_flag = 0;
1564 memset (pic_param, 0, sizeof (VAEncPictureParameterBufferHEVC));
1566 pic_param->decoded_curr_pic.picture_id =
1567 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (surface);
1568 pic_param->decoded_curr_pic.pic_order_cnt = picture->poc;
1569 pic_param->decoded_curr_pic.flags = 0;
1572 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1573 for (reflist = g_queue_peek_head_link (&ref_pool->ref_list);
1574 reflist; reflist = g_list_next (reflist)) {
1575 ref_pic = reflist->data;
1576 g_assert (ref_pic && ref_pic->pic &&
1577 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic) != VA_INVALID_ID);
1579 pic_param->reference_frames[i].picture_id =
1580 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (ref_pic->pic);
1581 pic_param->reference_frames[i].pic_order_cnt = ref_pic->poc;
1584 g_assert (i <= 15 && i <= ref_pool->max_ref_frames);
1586 for (; i < 15; ++i) {
1587 pic_param->reference_frames[i].picture_id = VA_INVALID_SURFACE;
1588 pic_param->reference_frames[i].flags = 0;
1590 pic_param->coded_buf = GST_VAAPI_OBJECT_ID (codedbuf);
1592 /* slice_temporal_mvp_enable_flag == FALSE */
1593 pic_param->collocated_ref_pic_index = 0xFF;
1595 pic_param->last_picture = 0;
1596 pic_param->pic_init_qp = encoder->init_qp;
1597 pic_param->num_ref_idx_l0_default_active_minus1 =
1598 (ref_pool->max_reflist0_count ? (ref_pool->max_reflist0_count - 1) : 0);
1599 pic_param->num_ref_idx_l1_default_active_minus1 =
1600 (ref_pool->max_reflist1_count ? (ref_pool->max_reflist1_count - 1) : 0);
1602 if (!get_nal_unit_type (picture, &nal_unit_type))
1604 pic_param->nal_unit_type = nal_unit_type;
1606 /* set picture fields */
1607 pic_param->pic_fields.value = 0;
1608 pic_param->pic_fields.bits.idr_pic_flag =
1609 GST_VAAPI_ENC_PICTURE_IS_IDR (picture);
1610 pic_param->pic_fields.bits.coding_type = picture->type;
1611 if (picture->type != GST_VAAPI_PICTURE_TYPE_B)
1612 pic_param->pic_fields.bits.reference_pic_flag = TRUE;
1613 pic_param->pic_fields.bits.sign_data_hiding_enabled_flag = FALSE;
1614 pic_param->pic_fields.bits.transform_skip_enabled_flag = TRUE;
1615 /* it seems driver requires enablement of cu_qp_delta_enabled_flag
1616 * to modifiy QP values in CBR mode encoding */
1617 pic_param->pic_fields.bits.cu_qp_delta_enabled_flag =
1618 GST_VAAPI_ENCODER_RATE_CONTROL (encoder) != GST_VAAPI_RATECONTROL_CQP;
1620 pic_param->pic_fields.bits.pps_loop_filter_across_slices_enabled_flag = TRUE;
1622 if (GST_VAAPI_ENC_PICTURE_IS_IDR (picture))
1623 no_output_of_prior_pics_flag = 1;
1624 pic_param->pic_fields.bits.no_output_of_prior_pics_flag =
1625 no_output_of_prior_pics_flag;
1630 /* Adds slice headers to picture */
1632 add_slice_headers (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
1633 GstVaapiEncoderH265Ref ** reflist_0, guint reflist_0_count,
1634 GstVaapiEncoderH265Ref ** reflist_1, guint reflist_1_count)
1636 VAEncSliceParameterBufferHEVC *slice_param;
1637 GstVaapiEncSlice *slice;
1638 guint slice_of_ctus, slice_mod_ctus, cur_slice_ctus;
1640 guint ctu_width_round_factor;
1641 guint last_ctu_index;
1642 guint i_slice, i_ref;
1646 ctu_size = encoder->ctu_width * encoder->ctu_height;
1648 g_assert (encoder->num_slices && encoder->num_slices < ctu_size);
1649 slice_of_ctus = ctu_size / encoder->num_slices;
1650 slice_mod_ctus = ctu_size % encoder->num_slices;
1654 i_slice < encoder->num_slices && (last_ctu_index < ctu_size); ++i_slice) {
1655 cur_slice_ctus = slice_of_ctus;
1656 if (slice_mod_ctus) {
1661 /* Work-around for satisfying the VA-Intel driver.
1662 * The driver only support multi slice begin from row start address */
1663 ctu_width_round_factor =
1664 encoder->ctu_width - (cur_slice_ctus % encoder->ctu_width);
1665 cur_slice_ctus += ctu_width_round_factor;
1666 if ((last_ctu_index + cur_slice_ctus) > ctu_size)
1667 cur_slice_ctus = ctu_size - last_ctu_index;
1669 slice = GST_VAAPI_ENC_SLICE_NEW (HEVC, encoder);
1670 g_assert (slice && slice->param_id != VA_INVALID_ID);
1671 slice_param = slice->param;
1673 memset (slice_param, 0, sizeof (VAEncSliceParameterBufferHEVC));
1675 encoder->first_slice_segment_in_pic_flag = TRUE;
1676 slice_param->slice_segment_address = 0;
1678 encoder->first_slice_segment_in_pic_flag = FALSE;
1679 slice_param->slice_segment_address = last_ctu_index;
1681 slice_param->num_ctu_in_slice = cur_slice_ctus;
1682 slice_param->slice_type = h265_get_slice_type (picture->type);
1683 slice_param->slice_pic_parameter_set_id = 0;
1685 slice_param->slice_fields.bits.num_ref_idx_active_override_flag =
1686 reflist_0_count || reflist_1_count;
1687 if (picture->type != GST_VAAPI_PICTURE_TYPE_I && reflist_0_count > 0)
1688 slice_param->num_ref_idx_l0_active_minus1 = reflist_0_count - 1;
1690 slice_param->num_ref_idx_l0_active_minus1 = 0;
1691 if (picture->type == GST_VAAPI_PICTURE_TYPE_B && reflist_1_count > 0)
1692 slice_param->num_ref_idx_l1_active_minus1 = reflist_1_count - 1;
1694 slice_param->num_ref_idx_l1_active_minus1 = 0;
1697 if (picture->type != GST_VAAPI_PICTURE_TYPE_I) {
1698 for (; i_ref < reflist_0_count; ++i_ref) {
1699 slice_param->ref_pic_list0[i_ref].picture_id =
1700 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_0[i_ref]->pic);
1701 slice_param->ref_pic_list0[i_ref].pic_order_cnt = reflist_0[i_ref]->poc;
1704 for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list0); ++i_ref) {
1705 slice_param->ref_pic_list0[i_ref].picture_id = VA_INVALID_SURFACE;
1706 slice_param->ref_pic_list0[i_ref].flags = 0;
1710 if (picture->type == GST_VAAPI_PICTURE_TYPE_B) {
1711 for (; i_ref < reflist_1_count; ++i_ref) {
1712 slice_param->ref_pic_list1[i_ref].picture_id =
1713 GST_VAAPI_SURFACE_PROXY_SURFACE_ID (reflist_1[i_ref]->pic);
1714 slice_param->ref_pic_list1[i_ref].pic_order_cnt = reflist_1[i_ref]->poc;
1717 for (; i_ref < G_N_ELEMENTS (slice_param->ref_pic_list1); ++i_ref) {
1718 slice_param->ref_pic_list1[i_ref].picture_id = VA_INVALID_SURFACE;
1719 slice_param->ref_pic_list1[i_ref].flags = 0;
1722 slice_param->max_num_merge_cand = 5; /* MaxNumMergeCand */
1723 slice_param->slice_qp_delta = encoder->init_qp - encoder->min_qp;
1725 slice_param->slice_fields.bits.
1726 slice_loop_filter_across_slices_enabled_flag = TRUE;
1728 /* set calculation for next slice */
1729 last_ctu_index += cur_slice_ctus;
1731 if ((i_slice == encoder->num_slices - 1) || (last_ctu_index == ctu_size))
1732 slice_param->slice_fields.bits.last_slice_of_pic_flag = 1;
1734 if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
1735 VA_ENC_PACKED_HEADER_SLICE)
1736 && !add_packed_slice_header (encoder, picture, slice))
1737 goto error_create_packed_slice_hdr;
1739 gst_vaapi_enc_picture_add_slice (picture, slice);
1740 gst_vaapi_codec_object_replace (&slice, NULL);
1742 if (i_slice < encoder->num_slices)
1744 ("Using less number of slices than requested, Number of slices per pictures is %d",
1746 g_assert (last_ctu_index == ctu_size);
1750 error_create_packed_slice_hdr:
1752 GST_ERROR ("failed to create packed slice header buffer");
1753 gst_vaapi_codec_object_replace (&slice, NULL);
1758 /* Generates and submits SPS header accordingly into the bitstream */
1760 ensure_sequence (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture)
1762 GstVaapiEncSequence *sequence = NULL;
1764 /* submit an SPS header before every new I-frame, if codec config changed */
1765 if (!encoder->config_changed || picture->type != GST_VAAPI_PICTURE_TYPE_I)
1768 sequence = GST_VAAPI_ENC_SEQUENCE_NEW (HEVC, encoder);
1769 if (!sequence || !fill_sequence (encoder, sequence))
1770 goto error_create_seq_param;
1772 /* add packed vps and sps headers */
1773 if ((GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
1774 VA_ENC_PACKED_HEADER_SEQUENCE)
1775 && !(add_packed_vps_header (encoder, picture, sequence)
1776 && add_packed_sequence_header (encoder, picture, sequence))) {
1777 goto error_create_packed_seq_hdr;
1781 gst_vaapi_enc_picture_set_sequence (picture, sequence);
1782 gst_vaapi_codec_object_replace (&sequence, NULL);
1785 encoder->config_changed = FALSE;
1789 error_create_seq_param:
1791 GST_ERROR ("failed to create sequence parameter buffer (SPS)");
1792 gst_vaapi_codec_object_replace (&sequence, NULL);
1795 error_create_packed_seq_hdr:
1797 GST_ERROR ("failed to create packed sequence header buffer");
1798 gst_vaapi_codec_object_replace (&sequence, NULL);
1804 ensure_control_rate_params (GstVaapiEncoderH265 * encoder)
1806 if (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP)
1809 /* RateControl params */
1810 GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).bits_per_second =
1811 encoder->bitrate_bits;
1812 /* CPB (Coded picture buffer) length in milliseconds, which could be
1813 * provided as a property */
1814 GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).window_size = encoder->cpb_length;
1815 GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).initial_qp = encoder->init_qp;
1816 GST_VAAPI_ENCODER_VA_RATE_CONTROL (encoder).min_qp = encoder->min_qp;
1819 fill_hrd_params (encoder, &GST_VAAPI_ENCODER_VA_HRD (encoder));
1825 ensure_misc_params (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture)
1827 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1829 if (!gst_vaapi_encoder_ensure_param_control_rate (base_encoder, picture))
1831 if (!gst_vaapi_encoder_ensure_param_quality_level (base_encoder, picture))
1836 /* Generates and submits PPS header accordingly into the bitstream */
1838 ensure_picture (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture,
1839 GstVaapiCodedBufferProxy * codedbuf_proxy, GstVaapiSurfaceProxy * surface)
1841 GstVaapiCodedBuffer *const codedbuf =
1842 GST_VAAPI_CODED_BUFFER_PROXY_BUFFER (codedbuf_proxy);
1843 gboolean res = FALSE;
1845 res = fill_picture (encoder, picture, codedbuf, surface);
1850 if (picture->type == GST_VAAPI_PICTURE_TYPE_I &&
1851 (GST_VAAPI_ENCODER_PACKED_HEADERS (encoder) &
1852 VA_ENC_PACKED_HEADER_PICTURE)
1853 && !add_packed_picture_header (encoder, picture)) {
1854 GST_ERROR ("set picture packed header failed");
1861 /* Generates slice headers */
1863 ensure_slices (GstVaapiEncoderH265 * encoder, GstVaapiEncPicture * picture)
1865 GstVaapiEncoderH265Ref *reflist_0[15];
1866 GstVaapiEncoderH265Ref *reflist_1[15];
1867 GstVaapiH265RefPool *const ref_pool = &encoder->ref_pool;
1868 guint reflist_0_count = 0, reflist_1_count = 0;
1872 if (picture->type != GST_VAAPI_PICTURE_TYPE_I &&
1873 !reference_list_init (encoder, picture,
1874 reflist_0, &reflist_0_count, reflist_1, &reflist_1_count)) {
1875 GST_ERROR ("reference list reorder failed");
1879 g_assert (reflist_0_count + reflist_1_count <= ref_pool->max_ref_frames);
1880 if (reflist_0_count > ref_pool->max_reflist0_count)
1881 reflist_0_count = ref_pool->max_reflist0_count;
1882 if (reflist_1_count > ref_pool->max_reflist1_count)
1883 reflist_1_count = ref_pool->max_reflist1_count;
1885 if (!add_slice_headers (encoder, picture,
1886 reflist_0, reflist_0_count, reflist_1, reflist_1_count))
1892 /* Normalizes bitrate (and CPB size) for HRD conformance */
1894 ensure_bitrate_hrd (GstVaapiEncoderH265 * encoder)
1896 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1897 guint bitrate, cpb_size;
1899 if (!base_encoder->bitrate) {
1900 encoder->bitrate_bits = 0;
1904 /* Round down bitrate. This is a hard limit mandated by the user */
1905 g_assert (SX_BITRATE >= 6);
1906 bitrate = (base_encoder->bitrate * 1000) & ~((1U << SX_BITRATE) - 1);
1907 if (bitrate != encoder->bitrate_bits) {
1908 GST_DEBUG ("HRD bitrate: %u bits/sec", bitrate);
1909 encoder->bitrate_bits = bitrate;
1910 encoder->config_changed = TRUE;
1913 /* Round up CPB size. This is an HRD compliance detail */
1914 g_assert (SX_CPB_SIZE >= 4);
1915 cpb_size = gst_util_uint64_scale (bitrate, encoder->cpb_length, 1000) &
1916 ~((1U << SX_CPB_SIZE) - 1);
1917 if (cpb_size != encoder->cpb_length_bits) {
1918 GST_DEBUG ("HRD CPB size: %u bits", cpb_size);
1919 encoder->cpb_length_bits = cpb_size;
1920 encoder->config_changed = TRUE;
1924 /* Estimates a good enough bitrate if none was supplied */
1926 ensure_bitrate (GstVaapiEncoderH265 * encoder)
1928 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1930 switch (GST_VAAPI_ENCODER_RATE_CONTROL (encoder)) {
1931 case GST_VAAPI_RATECONTROL_CBR:
1932 case GST_VAAPI_RATECONTROL_VBR:
1933 if (!base_encoder->bitrate) {
1934 /* FIXME: Provide better estimation */
1935 /* Using a 1/6 compression ratio */
1936 /* 12 bits per pixel for YUV420 */
1939 factor = (guint64) encoder->luma_width * encoder->luma_height * 12 / 6;
1940 base_encoder->bitrate =
1941 gst_util_uint64_scale (factor, GST_VAAPI_ENCODER_FPS_N (encoder),
1942 GST_VAAPI_ENCODER_FPS_D (encoder)) / 1000;
1943 GST_INFO ("target bitrate computed to %u kbps", base_encoder->bitrate);
1947 base_encoder->bitrate = 0;
1950 ensure_bitrate_hrd (encoder);
1953 /* Constructs profile, tier and level information based on user-defined limits */
1954 static GstVaapiEncoderStatus
1955 ensure_profile_tier_level (GstVaapiEncoderH265 * encoder)
1957 const GstVaapiProfile profile = encoder->profile;
1958 const GstVaapiTierH265 tier = encoder->tier;
1959 const GstVaapiLevelH265 level = encoder->level;
1961 ensure_tuning (encoder);
1963 if (!ensure_profile (encoder) || !ensure_profile_limits (encoder))
1964 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1966 /* Check HW constraints */
1967 if (!ensure_hw_profile_limits (encoder))
1968 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1969 if (encoder->profile_idc > encoder->hw_max_profile_idc)
1970 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1973 if (!ensure_tier (encoder))
1974 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1976 /* Ensure bitrate if not set already and derive the right level to use */
1977 ensure_bitrate (encoder);
1979 if (!ensure_level (encoder))
1980 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
1982 if (encoder->profile != profile || encoder->level != level
1983 || encoder->tier != tier) {
1984 GST_DEBUG ("selected %s profile at tier %s and level %s",
1985 gst_vaapi_utils_h265_get_profile_string (encoder->profile),
1986 gst_vaapi_utils_h265_get_tier_string (encoder->tier),
1987 gst_vaapi_utils_h265_get_level_string (encoder->level));
1988 encoder->config_changed = TRUE;
1990 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
1994 reset_properties (GstVaapiEncoderH265 * encoder)
1996 GstVaapiEncoder *const base_encoder = GST_VAAPI_ENCODER_CAST (encoder);
1997 GstVaapiH265ReorderPool *reorder_pool;
1998 GstVaapiH265RefPool *ref_pool;
2001 if (encoder->idr_period < base_encoder->keyframe_period)
2002 encoder->idr_period = base_encoder->keyframe_period;
2003 if (encoder->idr_period > MAX_IDR_PERIOD)
2004 encoder->idr_period = MAX_IDR_PERIOD;
2006 if (encoder->min_qp > encoder->init_qp ||
2007 (GST_VAAPI_ENCODER_RATE_CONTROL (encoder) == GST_VAAPI_RATECONTROL_CQP &&
2008 encoder->min_qp < encoder->init_qp))
2009 encoder->min_qp = encoder->init_qp;
2011 ctu_size = encoder->ctu_width * encoder->ctu_height;
2012 g_assert (gst_vaapi_encoder_ensure_num_slices (base_encoder, encoder->profile,
2013 GST_VAAPI_ENTRYPOINT_SLICE_ENCODE, (ctu_size + 1) / 2,
2014 &encoder->num_slices));
2016 gst_vaapi_encoder_ensure_max_num_ref_frames (base_encoder, encoder->profile,
2017 GST_VAAPI_ENTRYPOINT_SLICE_ENCODE);
2019 if (base_encoder->max_num_ref_frames_1 < 1 && encoder->num_bframes > 0) {
2020 GST_WARNING ("Disabling b-frame since the driver doesn't support it");
2021 encoder->num_bframes = 0;
2024 if (encoder->num_ref_frames > base_encoder->max_num_ref_frames_0) {
2025 GST_INFO ("Lowering the number of reference frames to %d",
2026 base_encoder->max_num_ref_frames_0);
2027 encoder->num_ref_frames = base_encoder->max_num_ref_frames_0;
2030 if (encoder->num_bframes > (base_encoder->keyframe_period + 1) / 2)
2031 encoder->num_bframes = (base_encoder->keyframe_period + 1) / 2;
2033 if (encoder->num_bframes > 0 && GST_VAAPI_ENCODER_FPS_N (encoder) > 0)
2034 encoder->cts_offset = gst_util_uint64_scale (GST_SECOND,
2035 GST_VAAPI_ENCODER_FPS_D (encoder), GST_VAAPI_ENCODER_FPS_N (encoder));
2037 encoder->cts_offset = 0;
2040 encoder->log2_max_pic_order_cnt =
2041 h265_get_log2_max_pic_order_cnt (encoder->idr_period);
2042 g_assert (encoder->log2_max_pic_order_cnt >= 4);
2043 encoder->max_pic_order_cnt = (1 << encoder->log2_max_pic_order_cnt);
2044 encoder->idr_num = 0;
2046 /* Only Supporting a maximum of two reference frames */
2047 if (encoder->num_bframes) {
2048 encoder->max_dec_pic_buffering = encoder->num_ref_frames + 2;
2049 encoder->max_num_reorder_pics = 1;
2051 encoder->max_dec_pic_buffering = encoder->num_ref_frames + 1;
2052 encoder->max_num_reorder_pics = 0;
2055 ref_pool = &encoder->ref_pool;
2056 ref_pool->max_reflist0_count = encoder->num_ref_frames;
2057 ref_pool->max_reflist1_count = encoder->num_bframes > 0;
2058 ref_pool->max_ref_frames = ref_pool->max_reflist0_count
2059 + ref_pool->max_reflist1_count;
2061 reorder_pool = &encoder->reorder_pool;
2062 reorder_pool->frame_index = 0;
2065 static GstVaapiEncoderStatus
2066 gst_vaapi_encoder_h265_encode (GstVaapiEncoder * base_encoder,
2067 GstVaapiEncPicture * picture, GstVaapiCodedBufferProxy * codedbuf)
2069 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2070 GstVaapiEncoderStatus ret = GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN;
2071 GstVaapiSurfaceProxy *reconstruct = NULL;
2073 reconstruct = gst_vaapi_encoder_create_surface (base_encoder);
2075 g_assert (GST_VAAPI_SURFACE_PROXY_SURFACE (reconstruct));
2077 if (!ensure_sequence (encoder, picture))
2079 if (!ensure_misc_params (encoder, picture))
2081 if (!ensure_picture (encoder, picture, codedbuf, reconstruct))
2083 if (!ensure_slices (encoder, picture))
2085 if (!gst_vaapi_enc_picture_encode (picture))
2088 if (!reference_list_update (encoder, picture, reconstruct))
2091 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2097 gst_vaapi_encoder_release_surface (GST_VAAPI_ENCODER (encoder),
2103 static GstVaapiEncoderStatus
2104 gst_vaapi_encoder_h265_flush (GstVaapiEncoder * base_encoder)
2106 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2107 GstVaapiH265ReorderPool *reorder_pool;
2108 GstVaapiEncPicture *pic;
2110 reorder_pool = &encoder->reorder_pool;
2111 reorder_pool->frame_index = 0;
2112 reorder_pool->cur_present_index = 0;
2114 while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2115 pic = (GstVaapiEncPicture *)
2116 g_queue_pop_head (&reorder_pool->reorder_frame_list);
2117 gst_vaapi_enc_picture_unref (pic);
2119 g_queue_clear (&reorder_pool->reorder_frame_list);
2121 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2124 /* Generate "codec-data" buffer */
2125 static GstVaapiEncoderStatus
2126 gst_vaapi_encoder_h265_get_codec_data (GstVaapiEncoder * base_encoder,
2127 GstBuffer ** out_buffer_ptr)
2129 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2130 const guint32 configuration_version = 0x01;
2131 const guint32 nal_length_size = 4;
2132 GstMapInfo vps_info, sps_info, pps_info;
2135 guint min_spatial_segmentation_idc = 0;
2136 guint num_arrays = 3;
2138 if (!encoder->vps_data || !encoder->sps_data || !encoder->pps_data)
2139 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
2140 if (gst_buffer_get_size (encoder->sps_data) < 4)
2141 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_HEADER;
2143 if (!gst_buffer_map (encoder->vps_data, &vps_info, GST_MAP_READ))
2144 goto error_map_vps_buffer;
2146 if (!gst_buffer_map (encoder->sps_data, &sps_info, GST_MAP_READ))
2147 goto error_map_sps_buffer;
2149 if (!gst_buffer_map (encoder->pps_data, &pps_info, GST_MAP_READ))
2150 goto error_map_pps_buffer;
2153 gst_bit_writer_init (&bs,
2154 (vps_info.size + sps_info.size + pps_info.size + 64) * 8);
2155 WRITE_UINT32 (&bs, configuration_version, 8);
2156 WRITE_UINT32 (&bs, sps_info.data[4], 8); /* profile_space | tier_flag | profile_idc */
2157 WRITE_UINT32 (&bs, sps_info.data[5], 32); /* profile_compatibility_flag [0-31] */
2158 /* progressive_source_flag | interlaced_source_flag | non_packed_constraint_flag |
2159 * frame_only_constraint_flag | reserved_zero_bits[0-27] */
2160 WRITE_UINT32 (&bs, sps_info.data[9], 32);
2161 WRITE_UINT32 (&bs, sps_info.data[13], 16); /* reserved_zero_bits [28-43] */
2162 WRITE_UINT32 (&bs, sps_info.data[15], 8); /* level_idc */
2163 WRITE_UINT32 (&bs, 0x0f, 4); /* 1111 */
2164 WRITE_UINT32 (&bs, min_spatial_segmentation_idc, 12); /* min_spatial_segmentation_idc */
2165 WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */
2166 WRITE_UINT32 (&bs, 0x00, 2); /* parallelismType */
2167 WRITE_UINT32 (&bs, 0x3f, 6); /* 111111 */
2168 WRITE_UINT32 (&bs, 0x01, 2); /* chroma_format_idc */
2169 WRITE_UINT32 (&bs, 0x1f, 5); /* 11111 */
2170 WRITE_UINT32 (&bs, 0x01, 3); /* bit_depth_luma_minus8 */
2171 WRITE_UINT32 (&bs, 0x1f, 5); /* 11111 */
2172 WRITE_UINT32 (&bs, 0x01, 3); /* bit_depth_chroma_minus8 */
2173 WRITE_UINT32 (&bs, 0x00, 16); /* avgFramerate */
2174 WRITE_UINT32 (&bs, 0x00, 2); /* constatnFramerate */
2175 WRITE_UINT32 (&bs, 0x00, 3); /* numTemporalLayers */
2176 WRITE_UINT32 (&bs, 0x00, 1); /* temporalIdNested */
2177 WRITE_UINT32 (&bs, nal_length_size - 1, 2); /* lengthSizeMinusOne */
2178 WRITE_UINT32 (&bs, 0x00, 8); /* numOfArrays */
2180 WRITE_UINT32 (&bs, num_arrays, 8); /* numOfArrays */
2183 WRITE_UINT32 (&bs, 0x00, 1); /* array_completeness */
2184 WRITE_UINT32 (&bs, 0x00, 1); /* reserved zero */
2185 WRITE_UINT32 (&bs, GST_H265_NAL_VPS, 6); /* Nal_unit_type */
2186 WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, VPS count = 1 */
2187 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
2188 /* Write Nal unit length and data of VPS */
2189 if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, vps_info.data, vps_info.size))
2190 goto nal_to_byte_stream_error;
2193 WRITE_UINT32 (&bs, 0x00, 1); /* array_completeness */
2194 WRITE_UINT32 (&bs, 0x00, 1); /* reserved zero */
2195 WRITE_UINT32 (&bs, GST_H265_NAL_SPS, 6); /* Nal_unit_type */
2196 WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, SPS count = 1 */
2197 g_assert (GST_BIT_WRITER_BIT_SIZE (&bs) % 8 == 0);
2198 /* Write Nal unit length and data of SPS */
2199 if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, sps_info.data, sps_info.size))
2200 goto nal_to_byte_stream_error;
2203 WRITE_UINT32 (&bs, 0x00, 1); /* array_completeness */
2204 WRITE_UINT32 (&bs, 0x00, 1); /* reserved zero */
2205 WRITE_UINT32 (&bs, GST_H265_NAL_PPS, 6); /* Nal_unit_type */
2206 WRITE_UINT32 (&bs, 0x01, 16); /* numNalus, PPS count = 1 */
2207 /* Write Nal unit length and data of PPS */
2208 if (!gst_vaapi_utils_h26x_write_nal_unit (&bs, pps_info.data, pps_info.size))
2209 goto nal_to_byte_stream_error;
2211 gst_buffer_unmap (encoder->pps_data, &pps_info);
2212 gst_buffer_unmap (encoder->sps_data, &sps_info);
2213 gst_buffer_unmap (encoder->vps_data, &vps_info);
2215 buffer = gst_buffer_new_wrapped (GST_BIT_WRITER_DATA (&bs),
2216 GST_BIT_WRITER_BIT_SIZE (&bs) / 8);
2218 goto error_alloc_buffer;
2219 *out_buffer_ptr = buffer;
2221 gst_bit_writer_clear (&bs, FALSE);
2222 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2227 GST_ERROR ("failed to write codec-data");
2228 gst_buffer_unmap (encoder->vps_data, &vps_info);
2229 gst_buffer_unmap (encoder->sps_data, &sps_info);
2230 gst_buffer_unmap (encoder->pps_data, &pps_info);
2231 gst_bit_writer_clear (&bs, TRUE);
2232 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
2234 nal_to_byte_stream_error:
2236 GST_ERROR ("failed to write nal unit");
2237 gst_buffer_unmap (encoder->vps_data, &vps_info);
2238 gst_buffer_unmap (encoder->sps_data, &sps_info);
2239 gst_buffer_unmap (encoder->pps_data, &pps_info);
2240 gst_bit_writer_clear (&bs, TRUE);
2241 return GST_VAAPI_ENCODER_STATUS_ERROR_OPERATION_FAILED;
2243 error_map_vps_buffer:
2245 GST_ERROR ("failed to map VPS packed header");
2246 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2248 error_map_sps_buffer:
2250 GST_ERROR ("failed to map SPS packed header");
2251 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2253 error_map_pps_buffer:
2255 GST_ERROR ("failed to map PPS packed header");
2256 gst_buffer_unmap (encoder->sps_data, &sps_info);
2257 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2261 GST_ERROR ("failed to allocate codec-data buffer");
2262 gst_bit_writer_clear (&bs, TRUE);
2263 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2268 /* The re-ordering algorithm is similar to what we implemented for
2269 * h264 encoder. But We could have a better algorithm for hevc encoder
2270 * by having B-frames as reference pictures */
2271 static GstVaapiEncoderStatus
2272 gst_vaapi_encoder_h265_reordering (GstVaapiEncoder * base_encoder,
2273 GstVideoCodecFrame * frame, GstVaapiEncPicture ** output)
2275 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2276 GstVaapiH265ReorderPool *reorder_pool = NULL;
2277 GstVaapiEncPicture *picture;
2278 gboolean is_idr = FALSE;
2282 reorder_pool = &encoder->reorder_pool;
2285 if (reorder_pool->reorder_state != GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES)
2286 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
2288 /* reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES
2289 dump B frames from queue, sometime, there may also have P frame or I frame */
2290 g_assert (encoder->num_bframes > 0);
2291 g_return_val_if_fail (!g_queue_is_empty (&reorder_pool->reorder_frame_list),
2292 GST_VAAPI_ENCODER_STATUS_ERROR_UNKNOWN);
2293 picture = g_queue_pop_head (&reorder_pool->reorder_frame_list);
2295 if (g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2296 reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES;
2301 /* new frame coming */
2302 picture = GST_VAAPI_ENC_PICTURE_NEW (HEVC, encoder, frame);
2304 GST_WARNING ("create H265 picture failed, frame timestamp:%"
2305 GST_TIME_FORMAT, GST_TIME_ARGS (frame->pts));
2306 return GST_VAAPI_ENCODER_STATUS_ERROR_ALLOCATION_FAILED;
2308 ++reorder_pool->cur_present_index;
2309 picture->poc = ((reorder_pool->cur_present_index * 1) %
2310 encoder->max_pic_order_cnt);
2312 is_idr = (reorder_pool->frame_index == 0 ||
2313 reorder_pool->frame_index >= encoder->idr_period);
2315 /* check key frames */
2316 if (is_idr || GST_VIDEO_CODEC_FRAME_IS_FORCE_KEYFRAME (frame) ||
2317 (reorder_pool->frame_index %
2318 GST_VAAPI_ENCODER_KEYFRAME_PERIOD (encoder)) == 0) {
2319 ++reorder_pool->frame_index;
2321 /* b frame enabled, check queue of reorder_frame_list */
2322 if (encoder->num_bframes
2323 && !g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2324 GstVaapiEncPicture *p_pic;
2326 p_pic = g_queue_pop_tail (&reorder_pool->reorder_frame_list);
2327 set_p_frame (p_pic, encoder);
2328 g_queue_foreach (&reorder_pool->reorder_frame_list,
2329 (GFunc) set_b_frame, encoder);
2330 set_key_frame (picture, encoder, is_idr);
2331 g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
2333 reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES;
2334 } else { /* no b frames in queue */
2335 set_key_frame (picture, encoder, is_idr);
2336 g_assert (g_queue_is_empty (&reorder_pool->reorder_frame_list));
2337 if (encoder->num_bframes)
2338 reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES;
2343 /* new p/b frames coming */
2344 ++reorder_pool->frame_index;
2345 if (reorder_pool->reorder_state == GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES &&
2346 g_queue_get_length (&reorder_pool->reorder_frame_list) <
2347 encoder->num_bframes) {
2348 g_queue_push_tail (&reorder_pool->reorder_frame_list, picture);
2349 return GST_VAAPI_ENCODER_STATUS_NO_SURFACE;
2352 set_p_frame (picture, encoder);
2354 if (reorder_pool->reorder_state == GST_VAAPI_ENC_H265_REORD_WAIT_FRAMES) {
2355 g_queue_foreach (&reorder_pool->reorder_frame_list, (GFunc) set_b_frame,
2357 reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_DUMP_FRAMES;
2358 g_assert (!g_queue_is_empty (&reorder_pool->reorder_frame_list));
2363 frame = picture->frame;
2364 if (GST_CLOCK_TIME_IS_VALID (frame->pts))
2365 frame->pts += encoder->cts_offset;
2368 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2371 static GstVaapiEncoderStatus
2372 set_context_info (GstVaapiEncoder * base_encoder)
2374 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2375 GstVideoInfo *const vip = GST_VAAPI_ENCODER_VIDEO_INFO (encoder);
2376 const guint DEFAULT_SURFACES_COUNT = 3;
2378 /* FIXME: Using only a rough approximation for bitstream headers.
2379 * Not taken into account: ScalingList, RefPicListModification,
2380 * PredWeightTable */
2381 /* Maximum sizes for common headers (in bits) */
2384 MAX_PROFILE_TIER_LEVEL_SIZE = 684,
2385 MAX_VPS_HDR_SIZE = 13781,
2386 MAX_SPS_HDR_SIZE = 615,
2387 MAX_SHORT_TERM_REFPICSET_SIZE = 55,
2388 MAX_VUI_PARAMS_SIZE = 267,
2389 MAX_HRD_PARAMS_SIZE = 8196,
2390 MAX_PPS_HDR_SIZE = 274,
2391 MAX_SLICE_HDR_SIZE = 33660
2394 /* Account for VPS header */
2395 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_VPS_HDR_SIZE +
2396 MAX_PROFILE_TIER_LEVEL_SIZE + MAX_HRD_PARAMS_SIZE) / 8;
2398 /* Account for SPS header */
2399 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_SPS_HDR_SIZE +
2400 MAX_PROFILE_TIER_LEVEL_SIZE + 64 * MAX_SHORT_TERM_REFPICSET_SIZE +
2401 MAX_VUI_PARAMS_SIZE + MAX_HRD_PARAMS_SIZE) / 8;
2403 /* Account for PPS header */
2404 base_encoder->codedbuf_size += 4 + GST_ROUND_UP_8 (MAX_PPS_HDR_SIZE) / 8;
2406 /* Account for slice header */
2407 base_encoder->codedbuf_size += encoder->num_slices * (4 +
2408 GST_ROUND_UP_8 (MAX_SLICE_HDR_SIZE + MAX_SHORT_TERM_REFPICSET_SIZE) / 8);
2410 if (!ensure_hw_profile (encoder))
2411 return GST_VAAPI_ENCODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
2413 base_encoder->num_ref_frames = (encoder->num_ref_frames
2414 + (encoder->num_bframes > 0 ? 1 : 0) + DEFAULT_SURFACES_COUNT);
2416 /* Only YUV 4:2:0 formats are supported for now. */
2417 base_encoder->codedbuf_size += GST_ROUND_UP_32 (vip->width) *
2418 GST_ROUND_UP_32 (vip->height) * 3 / 2;
2420 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2423 static GstVaapiEncoderStatus
2424 gst_vaapi_encoder_h265_reconfigure (GstVaapiEncoder * base_encoder)
2426 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2427 GstVaapiEncoderStatus status;
2428 guint luma_width, luma_height;
2430 luma_width = GST_VAAPI_ENCODER_WIDTH (encoder);
2431 luma_height = GST_VAAPI_ENCODER_HEIGHT (encoder);
2433 if (luma_width != encoder->luma_width || luma_height != encoder->luma_height) {
2434 GST_DEBUG ("resolution: %d %d", GST_VAAPI_ENCODER_WIDTH (encoder),
2435 GST_VAAPI_ENCODER_HEIGHT (encoder));
2436 encoder->luma_width = GST_ROUND_UP_32 (luma_width);
2437 encoder->luma_height = GST_ROUND_UP_32 (luma_height);
2438 encoder->ctu_width = (encoder->luma_width + 31) / 32;
2439 encoder->ctu_height = (encoder->luma_height + 31) / 32;
2440 encoder->config_changed = TRUE;
2442 /* Frame Cropping */
2443 if ((GST_VAAPI_ENCODER_WIDTH (encoder) & 31) ||
2444 (GST_VAAPI_ENCODER_HEIGHT (encoder) & 31)) {
2445 static const guint SubWidthC[] = { 1, 2, 2, 1 };
2446 static const guint SubHeightC[] = { 1, 2, 1, 1 };
2447 encoder->conformance_window_flag = 1;
2448 encoder->conf_win_left_offset = 0;
2449 encoder->conf_win_right_offset =
2450 (encoder->luma_width -
2451 GST_VAAPI_ENCODER_WIDTH (encoder)) / SubWidthC[1];
2452 encoder->conf_win_top_offset = 0;
2453 encoder->conf_win_bottom_offset =
2454 (encoder->luma_height -
2455 GST_VAAPI_ENCODER_HEIGHT (encoder)) / SubHeightC[1];
2459 status = ensure_profile_tier_level (encoder);
2460 if (status != GST_VAAPI_ENCODER_STATUS_SUCCESS)
2463 reset_properties (encoder);
2464 ensure_control_rate_params (encoder);
2465 return set_context_info (base_encoder);
2469 gst_vaapi_encoder_h265_init (GstVaapiEncoder * base_encoder)
2471 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2472 GstVaapiH265ReorderPool *reorder_pool;
2473 GstVaapiH265RefPool *ref_pool;
2475 encoder->conformance_window_flag = 0;
2476 encoder->num_slices = 1;
2478 /* re-ordering list initialize */
2479 reorder_pool = &encoder->reorder_pool;
2480 g_queue_init (&reorder_pool->reorder_frame_list);
2481 reorder_pool->reorder_state = GST_VAAPI_ENC_H265_REORD_NONE;
2482 reorder_pool->frame_index = 0;
2483 reorder_pool->cur_present_index = 0;
2485 /* reference list info initialize */
2486 ref_pool = &encoder->ref_pool;
2487 g_queue_init (&ref_pool->ref_list);
2488 ref_pool->max_ref_frames = 0;
2489 ref_pool->max_reflist0_count = 1;
2490 ref_pool->max_reflist1_count = 1;
2496 gst_vaapi_encoder_h265_finalize (GstVaapiEncoder * base_encoder)
2498 /*free private buffers */
2499 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2500 GstVaapiEncPicture *pic;
2501 GstVaapiEncoderH265Ref *ref;
2502 GstVaapiH265RefPool *ref_pool;
2503 GstVaapiH265ReorderPool *reorder_pool;
2505 gst_buffer_replace (&encoder->vps_data, NULL);
2506 gst_buffer_replace (&encoder->sps_data, NULL);
2507 gst_buffer_replace (&encoder->pps_data, NULL);
2509 /* reference list info de-init */
2510 ref_pool = &encoder->ref_pool;
2511 while (!g_queue_is_empty (&ref_pool->ref_list)) {
2512 ref = (GstVaapiEncoderH265Ref *) g_queue_pop_head (&ref_pool->ref_list);
2513 reference_pic_free (encoder, ref);
2515 g_queue_clear (&ref_pool->ref_list);
2517 /* re-ordering list initialize */
2518 reorder_pool = &encoder->reorder_pool;
2519 while (!g_queue_is_empty (&reorder_pool->reorder_frame_list)) {
2520 pic = (GstVaapiEncPicture *)
2521 g_queue_pop_head (&reorder_pool->reorder_frame_list);
2522 gst_vaapi_enc_picture_unref (pic);
2524 g_queue_clear (&reorder_pool->reorder_frame_list);
2527 static GstVaapiEncoderStatus
2528 gst_vaapi_encoder_h265_set_property (GstVaapiEncoder * base_encoder,
2529 gint prop_id, const GValue * value)
2531 GstVaapiEncoderH265 *const encoder = GST_VAAPI_ENCODER_H265 (base_encoder);
2534 case GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES:
2535 encoder->num_bframes = g_value_get_uint (value);
2537 case GST_VAAPI_ENCODER_H265_PROP_INIT_QP:
2538 encoder->init_qp = g_value_get_uint (value);
2540 case GST_VAAPI_ENCODER_H265_PROP_MIN_QP:
2541 encoder->min_qp = g_value_get_uint (value);
2543 case GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES:
2544 encoder->num_slices = g_value_get_uint (value);
2546 case GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH:
2547 encoder->cpb_length = g_value_get_uint (value);
2549 case GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES:
2550 encoder->num_ref_frames = g_value_get_uint (value);
2553 return GST_VAAPI_ENCODER_STATUS_ERROR_INVALID_PARAMETER;
2555 return GST_VAAPI_ENCODER_STATUS_SUCCESS;
2558 GST_VAAPI_ENCODER_DEFINE_CLASS_DATA (H265);
2560 static inline const GstVaapiEncoderClass *
2561 gst_vaapi_encoder_h265_class (void)
2563 static const GstVaapiEncoderClass GstVaapiEncoderH265Class = {
2564 GST_VAAPI_ENCODER_CLASS_INIT (H265, h265),
2565 .set_property = gst_vaapi_encoder_h265_set_property,
2566 .get_codec_data = gst_vaapi_encoder_h265_get_codec_data
2568 return &GstVaapiEncoderH265Class;
2572 * gst_vaapi_encoder_h265_new:
2573 * @display: a #GstVaapiDisplay
2575 * Creates a new #GstVaapiEncoder for H.265 encoding. Note that the
2576 * only supported output stream format is "byte-stream" format.
2578 * Return value: the newly allocated #GstVaapiEncoder object
2581 gst_vaapi_encoder_h265_new (GstVaapiDisplay * display)
2583 return gst_vaapi_encoder_new (gst_vaapi_encoder_h265_class (), display);
2587 * gst_vaapi_encoder_h265_get_default_properties:
2589 * Determines the set of common and H.265 specific encoder properties.
2590 * The caller owns an extra reference to the resulting array of
2591 * #GstVaapiEncoderPropInfo elements, so it shall be released with
2592 * g_ptr_array_unref() after usage.
2594 * Return value: the set of encoder properties for #GstVaapiEncoderH265,
2595 * or %NULL if an error occurred.
2598 gst_vaapi_encoder_h265_get_default_properties (void)
2600 const GstVaapiEncoderClass *const klass = gst_vaapi_encoder_h265_class ();
2603 props = gst_vaapi_encoder_properties_get_default (klass);
2608 * GstVaapiEncoderH265:max-bframes:
2610 * The number of B-frames between I and P.
2612 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2613 GST_VAAPI_ENCODER_H265_PROP_MAX_BFRAMES,
2614 g_param_spec_uint ("max-bframes",
2615 "Max B-Frames", "Number of B-frames between I and P", 0, 10, 0,
2616 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2619 * GstVaapiEncoderH265:refs:
2621 * The number of reference frames.
2622 * If B frame is encoded, it will add 1 reference frame more.
2624 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2625 GST_VAAPI_ENCODER_H265_PROP_NUM_REF_FRAMES,
2626 g_param_spec_uint ("refs",
2627 "Number of Reference Frames", "Number of reference frames", 1, 3, 1,
2628 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2631 * GstVaapiEncoderH265:init-qp:
2633 * The initial quantizer value.
2635 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2636 GST_VAAPI_ENCODER_H265_PROP_INIT_QP,
2637 g_param_spec_uint ("init-qp",
2638 "Initial QP", "Initial quantizer value", 1, 51, 26,
2639 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2642 * GstVaapiEncoderH265:min-qp:
2644 * The minimum quantizer value.
2646 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2647 GST_VAAPI_ENCODER_H265_PROP_MIN_QP,
2648 g_param_spec_uint ("min-qp",
2649 "Minimum QP", "Minimum quantizer value", 1, 51, 1,
2650 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2652 /* FIXME: there seems to be issues with multi-slice encoding */
2654 * GstVaapiEncoderH265:num-slices:
2656 * The number of slices per frame.
2658 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2659 GST_VAAPI_ENCODER_H265_PROP_NUM_SLICES,
2660 g_param_spec_uint ("num-slices",
2662 "Number of slices per frame",
2663 1, 200, 1, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2666 * GstVaapiEncoderH265:cpb-length:
2668 * The size of the CPB buffer in milliseconds.
2670 GST_VAAPI_ENCODER_PROPERTIES_APPEND (props,
2671 GST_VAAPI_ENCODER_H265_PROP_CPB_LENGTH,
2672 g_param_spec_uint ("cpb-length",
2673 "CPB Length", "Length of the CPB buffer in milliseconds",
2674 1, 10000, DEFAULT_CPB_LENGTH,
2675 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
2681 * gst_vaapi_encoder_h265_set_max_profile:
2682 * @encoder: a #GstVaapiEncoderH265
2683 * @profile: an H.265 #GstVaapiProfile
2685 * Notifies the @encoder to use coding tools from the supplied
2688 * This means that if the minimal profile derived to
2689 * support the specified coding tools is greater than this @profile,
2690 * then an error is returned when the @encoder is configured.
2692 * Return value: %TRUE on success
2695 gst_vaapi_encoder_h265_set_max_profile (GstVaapiEncoderH265 * encoder,
2696 GstVaapiProfile profile)
2700 g_return_val_if_fail (encoder != NULL, FALSE);
2701 g_return_val_if_fail (profile != GST_VAAPI_PROFILE_UNKNOWN, FALSE);
2703 if (gst_vaapi_profile_get_codec (profile) != GST_VAAPI_CODEC_H265)
2706 profile_idc = gst_vaapi_utils_h265_get_profile_idc (profile);
2710 encoder->max_profile_idc = profile_idc;
2715 * gst_vaapi_encoder_h265_get_profile_tier_level:
2716 * @encoder: a #GstVaapiEncoderH265
2717 * @out_profile_ptr: return location for the #GstVaapiProfile
2718 * @out_level_ptr: return location for the #GstVaapiLevelH265
2719 * @out_tier_ptr: return location for the #GstVaapiTierH265
2721 * Queries the H.265 @encoder for the active profile and level. That
2722 * information is only constructed and valid after the encoder is
2723 * configured, i.e. after the gst_vaapi_encoder_set_codec_state()
2724 * function is called.
2726 * Return value: %TRUE on success
2729 gst_vaapi_encoder_h265_get_profile_tier_level (GstVaapiEncoderH265 * encoder,
2730 GstVaapiProfile * out_profile_ptr, GstVaapiTierH265 * out_tier_ptr,
2731 GstVaapiLevelH265 * out_level_ptr)
2733 g_return_val_if_fail (encoder != NULL, FALSE);
2735 if (!encoder->profile || !encoder->tier || !encoder->level)
2738 if (out_profile_ptr)
2739 *out_profile_ptr = encoder->profile;
2741 *out_level_ptr = encoder->level;
2743 *out_tier_ptr = encoder->tier;