1 /*
2 * Copyright (c) 2020, Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included
12 * in all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 */
22 //!
23 //! \file     encode_hevc_header_packer.h
24 //! \brief    Defines the common interface for hevc packer
25 //!
26 #ifndef __ENCODE_HEVC_HEADER_PACKER_H__
27 #define __ENCODE_HEVC_HEADER_PACKER_H__
28 
29 #include "bitstream_writer.h"
30 #include "codec_def_common_encode.h"
31 #include "codec_def_encode.h"
32 #include "codec_def_encode_hevc.h"
33 #include <exception>
34 #include <array>
35 #include <numeric>
36 #include <algorithm>
37 
38 enum NALU_TYPE
39 {
40     TRAIL_N = 0,
41     TRAIL_R,
42     TSA_N,
43     TSA_R,
44     STSA_N,
45     STSA_R,
46     RADL_N,
47     RADL_R,
48     RASL_N,
49     RASL_R,
50     RSV_VCL_N10,
51     RSV_VCL_R11,
52     RSV_VCL_N12,
53     RSV_VCL_R13,
54     RSV_VCL_N14,
55     RSV_VCL_R15,
56     BLA_W_LP,
57     BLA_W_RADL,
58     BLA_N_LP,
59     IDR_W_RADL,
60     IDR_N_LP,
61     CRA_NUT,
62     RSV_IRAP_VCL22,
63     RSV_IRAP_VCL23,
64     RSV_VCL24,
65     RSV_VCL25,
66     RSV_VCL26,
67     RSV_VCL27,
68     RSV_VCL28,
69     RSV_VCL29,
70     RSV_VCL30,
71     RSV_VCL31,
72     VPS_NUT,
73     SPS_NUT,
74     PPS_NUT,
75     AUD_NUT,
76     EOS_NUT,
77     EOB_NUT,
78     FD_NUT,
79     PREFIX_SEI_NUT,
80     SUFFIX_SEI_NUT,
81     RSV_NVCL41,
82     RSV_NVCL42,
83     RSV_NVCL43,
84     RSV_NVCL44,
85     RSV_NVCL45,
86     RSV_NVCL46,
87     RSV_NVCL47,
88     UNSPEC48,
89     UNSPEC49,
90     UNSPEC50,
91     UNSPEC51,
92     UNSPEC52,
93     UNSPEC53,
94     UNSPEC54,
95     UNSPEC55,
96     UNSPEC56,
97     UNSPEC57,
98     UNSPEC58,
99     UNSPEC59,
100     UNSPEC60,
101     UNSPEC61,
102     UNSPEC62,
103     UNSPEC63,
104     num_NALU_TYPE
105 };
106 
107 enum ePackInfo
108 {
109     PACK_QPDOffset = 0,
110     PACK_SAOOffset,
111     PACK_VUIOffset,
112     PACK_PWTOffset,
113     PACK_PWTLength,
114     NUM_PACK_INFO
115 };
116 
117 struct STRPS
118 {
119     mfxU8 inter_ref_pic_set_prediction_flag : 1;
120     mfxU8 delta_idx_minus1 : 6;
121     mfxU8 delta_rps_sign : 1;
122 
123     mfxU8 num_negative_pics : 4;
124     mfxU8 num_positive_pics : 4;
125 
126     mfxU16 abs_delta_rps_minus1;
127     mfxU16 WeightInGop;
128 
129     struct Pic
130     {
131         mfxU8  used_by_curr_pic_flag : 1;
132         mfxU8  use_delta_flag : 1;
133         mfxI16 DeltaPocSX;
134 
135         union
136         {
137             struct
138             {
139                 mfxU16 delta_poc_s0_minus1 : 15;
140                 mfxU16 used_by_curr_pic_s0_flag : 1;
141             };
142             struct
143             {
144                 mfxU16 delta_poc_s1_minus1 : 15;
145                 mfxU16 used_by_curr_pic_s1_flag : 1;
146             };
147             struct
148             {
149                 mfxU16 delta_poc_sx_minus1 : 15;
150                 mfxU16 used_by_curr_pic_sx_flag : 1;
151             };
152         };
153     } pic[16];
154 };
155 
156 struct HRDInfo
157 {
158     mfxU16 nal_hrd_parameters_present_flag : 1;
159     mfxU16 vcl_hrd_parameters_present_flag : 1;
160     mfxU16 sub_pic_hrd_params_present_flag : 1;
161     mfxU16 du_cpb_removal_delay_increment_length_minus1 : 5;
162     mfxU16 sub_pic_cpb_params_in_pic_timing_sei_flag : 1;
163     mfxU16 dpb_output_delay_du_length_minus1 : 5;
164 
165     mfxU16 tick_divisor_minus2 : 8;
166     mfxU16 bit_rate_scale : 4;
167     mfxU16 cpb_size_scale : 4;
168 
169     mfxU8  cpb_size_du_scale : 4;
170     mfxU16 initial_cpb_removal_delay_length_minus1 : 5;
171     mfxU16 au_cpb_removal_delay_length_minus1 : 5;
172     mfxU16 dpb_output_delay_length_minus1 : 5;
173 
174     struct SubLayer
175     {
176         mfxU8 fixed_pic_rate_general_flag : 1;
177         mfxU8 fixed_pic_rate_within_cvs_flag : 1;
178         mfxU8 low_delay_hrd_flag : 1;
179 
180         mfxU16 elemental_duration_in_tc_minus1 : 11;
181         mfxU16 cpb_cnt_minus1 : 5;
182 
183         struct CPB
184         {
185             mfxU32 bit_rate_value_minus1;
186             mfxU32 cpb_size_value_minus1;
187             mfxU32 cpb_size_du_value_minus1;
188             mfxU32 bit_rate_du_value_minus1;
189             mfxU8  cbr_flag;
190         } cpb[32];
191     } sl[8];
192 };
193 
194 struct VUI
195 {
196     mfxU8  aspect_ratio_info_present_flag : 1;
197     mfxU8  aspect_ratio_idc;
198     mfxU16 sar_width;
199     mfxU16 sar_height;
200 
201     mfxU8 overscan_info_present_flag : 1;
202     mfxU8 overscan_appropriate_flag : 1;
203     mfxU8 video_signal_type_present_flag : 1;
204     mfxU8 video_format : 3;
205     mfxU8 video_full_range_flag : 1;
206     mfxU8 colour_description_present_flag : 1;
207     mfxU8 colour_primaries;
208     mfxU8 transfer_characteristics;
209     mfxU8 matrix_coeffs;
210 
211     mfxU8 chroma_loc_info_present_flag : 1;
212     mfxU8 chroma_sample_loc_type_top_field : 3;
213     mfxU8 chroma_sample_loc_type_bottom_field : 3;
214 
215     mfxU8 neutral_chroma_indication_flag : 1;
216     mfxU8 field_seq_flag : 1;
217     mfxU8 frame_field_info_present_flag : 1;
218     mfxU8 default_display_window_flag : 1;
219 
220     mfxU32 def_disp_win_left_offset;
221     mfxU32 def_disp_win_right_offset;
222     mfxU32 def_disp_win_top_offset;
223     mfxU32 def_disp_win_bottom_offset;
224 
225     mfxU8 timing_info_present_flag : 1;
226     mfxU8 hrd_parameters_present_flag : 1;
227     mfxU8 poc_proportional_to_timing_flag : 1;
228 
229     mfxU8 bitstream_restriction_flag : 1;
230     mfxU8 tiles_fixed_structure_flag : 1;
231     mfxU8 motion_vectors_over_pic_boundaries_flag : 1;
232     mfxU8 restricted_ref_pic_lists_flag : 1;
233 
234     mfxU32 num_units_in_tick;
235     mfxU32 time_scale;
236     mfxU32 num_ticks_poc_diff_one_minus1;
237 
238     mfxU32 min_spatial_segmentation_idc : 12;
239     mfxU32 max_bytes_per_pic_denom : 5;
240     mfxU32 max_bits_per_min_cu_denom : 5;
241     mfxU16 log2_max_mv_length_horizontal : 5;
242     mfxU16 log2_max_mv_length_vertical : 4;
243 
244     HRDInfo hrd;
245 };
246 
247 struct ScalingList
248 {
249     mfxU8 scalingLists0[6][16];
250     mfxU8 scalingLists1[6][64];
251     mfxU8 scalingLists2[6][64];
252     mfxU8 scalingLists3[2][64];
253     mfxU8 scalingListDCCoefSizeID2[6];
254     mfxU8 scalingListDCCoefSizeID3[2];
255 };
256 
257 struct HevcSPS
258 {
259     mfxU8 video_parameter_set_id : 4;
260     mfxU8 max_sub_layers_minus1 : 3;
261     mfxU8 temporal_id_nesting_flag : 1;
262 
263     mfxU8 seq_parameter_set_id : 4;
264     mfxU8 chroma_format_idc : 2;
265     mfxU8 separate_colour_plane_flag : 1;
266     mfxU8 conformance_window_flag : 1;
267 
268     mfxU32 pic_width_in_luma_samples;
269     mfxU32 pic_height_in_luma_samples;
270 
271     mfxU32 conf_win_left_offset;
272     mfxU32 conf_win_right_offset;
273     mfxU32 conf_win_top_offset;
274     mfxU32 conf_win_bottom_offset;
275 
276     mfxU8 bit_depth_luma_minus8 : 3;
277     mfxU8 bit_depth_chroma_minus8 : 3;
278     mfxU8 log2_max_pic_order_cnt_lsb_minus4 : 4;
279     //mfxU8  sub_layer_ordering_info_present_flag : 1;
280 
281     mfxU32 log2_min_luma_coding_block_size_minus3;
282     mfxU32 log2_diff_max_min_luma_coding_block_size;
283     mfxU32 log2_min_transform_block_size_minus2;
284     mfxU32 log2_diff_max_min_transform_block_size;
285     mfxU32 max_transform_hierarchy_depth_inter;
286     mfxU32 max_transform_hierarchy_depth_intra;
287 
288     mfxU8 scaling_list_enabled_flag : 1;
289     mfxU8 scaling_list_data_present_flag : 1;
290 
291     mfxU8 amp_enabled_flag : 1;
292     mfxU8 sample_adaptive_offset_enabled_flag : 1;
293 
294     mfxU8  pcm_enabled_flag : 1;
295     mfxU8  pcm_loop_filter_disabled_flag : 1;
296     mfxU8  pcm_sample_bit_depth_luma_minus1 : 4;
297     mfxU8  pcm_sample_bit_depth_chroma_minus1 : 4;
298     mfxU32 log2_min_pcm_luma_coding_block_size_minus3;
299     mfxU32 log2_diff_max_min_pcm_luma_coding_block_size;
300 
301     mfxU8 long_term_ref_pics_present_flag : 1;
302     mfxU8 num_long_term_ref_pics_sps : 6;
303 
304     mfxU16 lt_ref_pic_poc_lsb_sps[32];
305     mfxU8  used_by_curr_pic_lt_sps_flag[32];
306 
307     mfxU8 temporal_mvp_enabled_flag : 1;
308     mfxU8 strong_intra_smoothing_enabled_flag : 1;
309     mfxU8 vui_parameters_present_flag : 1;
310     mfxU8 extension_flag : 1;
311     mfxU8 extension_data_flag : 1;
312 
313     mfxU8 range_extension_flag : 1;
314     mfxU8 transform_skip_rotation_enabled_flag : 1;
315     mfxU8 transform_skip_context_enabled_flag : 1;
316     mfxU8 implicit_rdpcm_enabled_flag : 1;
317     mfxU8 explicit_rdpcm_enabled_flag : 1;
318     mfxU8 extended_precision_processing_flag : 1;
319     mfxU8 intra_smoothing_disabled_flag : 1;
320     mfxU8 high_precision_offsets_enabled_flag : 1;
321     mfxU8 persistent_rice_adaptation_enabled_flag : 1;
322     mfxU8 cabac_bypass_alignment_enabled_flag : 1;
323 
324     mfxU8 ExtensionFlags;
325     mfxU8 num_short_term_ref_pic_sets;
326     STRPS strps[65];
327 
328     ScalingList scl;
329     VUI         vui;
330 };
331 
332 struct HevcPPS
333 {
334     mfxU16 pic_parameter_set_id : 6;
335     mfxU16 seq_parameter_set_id : 4;
336     mfxU16 dependent_slice_segments_enabled_flag : 1;
337     mfxU16 output_flag_present_flag : 1;
338     mfxU16 num_extra_slice_header_bits : 3;
339     mfxU16 sign_data_hiding_enabled_flag : 1;
340     mfxU16 cabac_init_present_flag : 1;
341     mfxU16 num_ref_idx_l0_default_active_minus1 : 4;
342     mfxU16 num_ref_idx_l1_default_active_minus1 : 4;
343     mfxU16 constrained_intra_pred_flag : 1;
344     mfxU16 transform_skip_enabled_flag : 1;
345     mfxU16 cu_qp_delta_enabled_flag : 1;
346     mfxU16 slice_segment_header_extension_present_flag : 1;
347 
348     mfxU32 diff_cu_qp_delta_depth;
349     mfxI32 init_qp_minus26;
350     mfxI16 cb_qp_offset : 6;
351     mfxI16 cr_qp_offset : 6;
352 
353     mfxU8 slice_chroma_qp_offsets_present_flag : 1;
354     mfxU8 weighted_pred_flag : 1;
355     mfxU8 weighted_bipred_flag : 1;
356     mfxU8 transquant_bypass_enabled_flag : 1;
357     mfxU8 tiles_enabled_flag : 1;
358     mfxU8 entropy_coding_sync_enabled_flag : 1;
359     mfxU8 uniform_spacing_flag : 1;
360     mfxU8 loop_filter_across_tiles_enabled_flag : 1;
361 
362     mfxU16 num_tile_columns_minus1;
363     mfxU16 num_tile_rows_minus1;
364 
365     mfxU16 column_width[MAX_NUM_TILE_COLUMNS - 1];
366     mfxU16 row_height[MAX_NUM_TILE_ROWS - 1];
367 
368     mfxU8 loop_filter_across_slices_enabled_flag : 1;
369     mfxU8 deblocking_filter_control_present_flag : 1;
370     mfxU8 deblocking_filter_override_enabled_flag : 1;
371     mfxU8 deblocking_filter_disabled_flag : 1;
372     mfxU8 scaling_list_data_present_flag : 1;
373     mfxU8 lists_modification_present_flag : 1;
374     mfxU8 extension_flag : 1;
375     mfxU8 extension_data_flag : 1;
376 
377     mfxI8 beta_offset_div2 : 4;
378     mfxI8 tc_offset_div2 : 4;
379 
380     //ScalingListData* sld;
381 
382     mfxU16 log2_parallel_merge_level_minus2;
383 
384     mfxU32 range_extension_flag : 1;
385     mfxU32 cross_component_prediction_enabled_flag : 1;
386     mfxU32 chroma_qp_offset_list_enabled_flag : 1;
387     mfxU32 log2_sao_offset_scale_luma : 3;
388     mfxU32 log2_sao_offset_scale_chroma : 3;
389     mfxU32 chroma_qp_offset_list_len_minus1 : 3;
390     mfxU32 diff_cu_chroma_qp_offset_depth : 5;
391     mfxU32 log2_max_transform_skip_block_size_minus2 : 5;
392     mfxU32 : 10;
393     mfxI8 cb_qp_offset_list[6];
394     mfxI8 cr_qp_offset_list[6];
395 
396     mfxU8 ExtensionFlags;
397 };
398 
399 struct HevcSlice
400 {
401     mfxU8 no_output_of_prior_pics_flag : 1;
402     mfxU8 pic_parameter_set_id : 6;
403     mfxU8 dependent_slice_segment_flag : 1;
404 
405     mfxU32 segment_address;
406 
407     mfxU8 reserved_flags;
408     mfxU8 type : 2;
409     mfxU8 colour_plane_id : 2;
410     mfxU8 short_term_ref_pic_set_idx;
411 
412     mfxU8 pic_output_flag : 1;
413     mfxU8 short_term_ref_pic_set_sps_flag : 1;
414     mfxU8 num_long_term_sps : 6;
415 
416     mfxU8 first_slice_segment_in_pic_flag : 1;
417     mfxU8 temporal_mvp_enabled_flag : 1;
418     mfxU8 sao_luma_flag : 1;
419     mfxU8 sao_chroma_flag : 1;
420     mfxU8 num_ref_idx_active_override_flag : 1;
421     mfxU8 mvd_l1_zero_flag : 1;
422     mfxU8 cabac_init_flag : 1;
423     mfxU8 collocated_from_l0_flag : 1;
424 
425     mfxU8 collocated_ref_idx : 4;
426     mfxU8 five_minus_max_num_merge_cand : 3;
427 
428     mfxU8 num_ref_idx_l0_active_minus1 : 4;
429     mfxU8 num_ref_idx_l1_active_minus1 : 4;
430 
431     mfxU32 pic_order_cnt_lsb;
432     mfxU16 num_long_term_pics;
433 
434     mfxI8  slice_qp_delta;
435     mfxI16 slice_cb_qp_offset : 6;
436     mfxI16 slice_cr_qp_offset : 6;
437 
438     mfxU8 deblocking_filter_override_flag : 1;
439     mfxU8 deblocking_filter_disabled_flag : 1;
440     mfxU8 loop_filter_across_slices_enabled_flag : 1;
441     mfxU8 offset_len_minus1 : 5;
442 
443     mfxI8 beta_offset_div2 : 4;
444     mfxI8 tc_offset_div2 : 4;
445 
446     mfxU32 num_entry_point_offsets;
447 
448     STRPS strps;
449 
450     struct LongTerm
451     {
452         mfxU8  lt_idx_sps : 5;
453         mfxU8  used_by_curr_pic_lt_flag : 1;
454         mfxU8  delta_poc_msb_present_flag : 1;
455         mfxU32 poc_lsb_lt;
456         mfxU32 delta_poc_msb_cycle_lt;
457     } lt[MAX_NUM_LONG_TERM_PICS];
458 
459     mfxU8 ref_pic_list_modification_flag_lx[2];
460     mfxU8 list_entry_lx[2][16];
461 
462     mfxU16 luma_log2_weight_denom : 3;
463     mfxU16 chroma_log2_weight_denom : 3;
464     mfxI16 pwt[2][16][3][2];  //[list][list entry][Y, Cb, Cr][weight, offset]
465 };
466 
467 struct HevcNALU
468 {
469     mfxU16 long_start_code;
470     mfxU16 nal_unit_type;
471     mfxU16 nuh_layer_id;
472     mfxU16 nuh_temporal_id_plus1;
473 };
474 
475 typedef HevcSPS   SPS;
476 typedef HevcPPS   PPS;
477 typedef HevcSlice Slice;
478 typedef HevcNALU  NALU;
479 
480 using STRPSPic = STRPS::Pic;
481 
482 class HevcHeaderPacker
483 {
484 public:
485     BSBuffer *              m_bsBuffer      = nullptr;
486     HevcNALU                m_naluParams    = {};
487     HevcSPS                 m_spsParams     = {};
488     HevcPPS                 m_ppsParams     = {};
489     HevcSlice               m_sliceParams   = {};
490     uint8_t                 nalType         = 0;
491     std::array<mfxU8, 1024> m_rbsp          = {};
492     bool                    m_bDssEnabled   = false;
493 
494 public:
495     HevcHeaderPacker();
496     MOS_STATUS SliceHeaderPacker(EncoderParams *encodeParams);
497     MOS_STATUS GetNaluParams(uint8_t nal_unit_type_in, unsigned short layer_id_in, unsigned short temporal_id, mfxU16 long_start_code);
498     MOS_STATUS GetPPSParams(PCODEC_HEVC_ENCODE_PICTURE_PARAMS hevcPicParams);
499     MOS_STATUS GetSPSParams(PCODEC_HEVC_ENCODE_SEQUENCE_PARAMS hevcSeqParams);
500     MOS_STATUS GetSliceParams(const CODEC_HEVC_ENCODE_SLICE_PARAMS hevcSliceParams);
501     MOS_STATUS LoadSliceHeaderParams(CodecEncodeHevcSliceHeaderParams* pSH);
502     void       PackSSH(
503               BitstreamWriter &bs,
504               HevcNALU const & nalu,
505               HevcSPS const &  sps,
506               HevcPPS const &  pps,
507               HevcSlice const &slice,
508               bool             dyn_slice_size);
509     void PackNALU(BitstreamWriter &bs, NALU const &h);
510     void PackSSHPartIdAddr(
511         BitstreamWriter &bs,
512         NALU const &     nalu,
513         SPS const &      sps,
514         PPS const &      pps,
515         Slice const &    slice);
516     template <class T>
clamp(const T & v,const T & lo,const T & hi)517     const T &clamp(const T &v, const T &lo, const T &hi)
518     {
519         return std::min<T>(hi, std::max<T>(v, lo));
520     }
521     template <class T>
CeilDiv(T x,T y)522     inline T CeilDiv(T x, T y)
523     {
524         return (x + y - 1) / y;
525     }
CeilLog2(mfxU32 x)526     inline mfxU32 CeilLog2(mfxU32 x)
527     {
528         mfxU32 l = 0;
529         while (x > (1U << l))
530             ++l;
531         return l;
532     }
533     void PackSSHPartIndependent(
534         BitstreamWriter &bs,
535         NALU const &     nalu,
536         SPS const &      sps,
537         PPS const &      pps,
538         Slice const &    slice);
539 
540     void PackSSHPartNonIDR(
541         BitstreamWriter &bs,
542         SPS const &      sps,
543         Slice const &    slice);
544 
545     void PackSTRPS(BitstreamWriter &bs, const STRPS *sets, mfxU32 num, mfxU32 idx);
546 
547     void PackSSHPartPB(
548         BitstreamWriter &bs,
549         SPS const &      sps,
550         PPS const &      pps,
551         Slice const &    slice);
552 
553     bool PackSSHPWT(
554         BitstreamWriter &bs, const SPS &sps, const PPS &pps, const Slice &slice);
555 
PutUE(BitstreamWriter & bs,mfxU32 b)556     static bool PutUE(BitstreamWriter &bs, mfxU32 b)
557     {
558         bs.PutUE(b);
559         return true;
560     };
PutSE(BitstreamWriter & bs,mfxI32 b)561     static bool PutSE(BitstreamWriter &bs, mfxI32 b)
562     {
563         bs.PutSE(b);
564         return true;
565     };
PutBit(BitstreamWriter & bs,mfxU32 b)566     static bool PutBit(BitstreamWriter &bs, mfxU32 b)
567     {
568         bs.PutBit(!!b);
569         return true;
570     };
PutBits(BitstreamWriter & bs,mfxU32 n,mfxU32 b)571     static bool PutBits(BitstreamWriter &bs, mfxU32 n, mfxU32 b)
572     {
573         if (n)
574             bs.PutBits(n, b);
575         return !!n;
576     };
ThrowAssert(bool bThrow,const char * msg)577     inline void ThrowAssert(bool bThrow, const char *msg)
578     {
579         if (bThrow)
580             throw std::logic_error(msg);
581     }
582 
583 MEDIA_CLASS_DEFINE_END(HevcHeaderPacker)
584 };
585 
586 #endif