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