github.com/cnotch/ipchub@v1.1.0/av/codec/hevc/sps.go (about)

     1  // Copyright (c) 2019,CAOHONGJU All rights reserved.
     2  // Use of this source code is governed by a MIT-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package hevc
     6  
     7  import (
     8  	"encoding/base64"
     9  	"errors"
    10  	"fmt"
    11  	"runtime/debug"
    12  
    13  	"github.com/cnotch/ipchub/utils"
    14  	"github.com/cnotch/ipchub/utils/bits"
    15  )
    16  
    17  type H265RawScalingList struct {
    18  	Scaling_list_pred_mode_flag       [4][6]uint8
    19  	Scaling_list_pred_matrix_id_delta [4][6]uint8
    20  	Scaling_list_dc_coef_minus8       [4][6]int16
    21  	Scaling_list_delta_coeff          [4][6][64]int8
    22  }
    23  
    24  func (sl *H265RawScalingList) decode(r *bits.Reader) error {
    25  	for sizeId := 0; sizeId < 4; sizeId++ {
    26  		step := 1 // (sizeId == 3 ? 3 : 1)
    27  		if sizeId == 3 {
    28  			step = 3
    29  		}
    30  		for matrixId := 0; matrixId < 6; matrixId += step {
    31  			sl.Scaling_list_pred_mode_flag[sizeId][matrixId] = r.ReadBit()
    32  			if sl.Scaling_list_pred_mode_flag[sizeId][matrixId] == 0 {
    33  				sl.Scaling_list_pred_matrix_id_delta[sizeId][matrixId] = r.ReadUe8()
    34  			} else {
    35  				n := 1 << (4 + (sizeId << 1))
    36  				if n > 64 {
    37  					n = 64
    38  				}
    39  				if sizeId > 1 {
    40  					sl.Scaling_list_dc_coef_minus8[sizeId-2][matrixId] = r.ReadSe16()
    41  				}
    42  				for i := 0; i < n; i++ {
    43  					sl.Scaling_list_delta_coeff[sizeId][matrixId][i] = r.ReadSe8()
    44  				}
    45  			}
    46  		}
    47  	}
    48  	return nil
    49  }
    50  
    51  type H265RawVUI struct {
    52  	Aspect_ratio_info_present_flag uint8
    53  	Aspect_ratio_idc               uint8
    54  	Sar_width                      uint16
    55  	Sar_height                     uint16
    56  
    57  	Overscan_info_present_flag uint8
    58  	Overscan_appropriate_flag  uint8
    59  
    60  	Video_signal_type_present_flag  uint8
    61  	Video_format                    uint8
    62  	Video_full_range_flag           uint8
    63  	Colour_description_present_flag uint8
    64  	Colour_primaries                uint8
    65  	Transfer_characteristics        uint8
    66  	Matrix_coefficients             uint8
    67  
    68  	Chroma_loc_info_present_flag        uint8
    69  	Chroma_sample_loc_type_top_field    uint8
    70  	Chroma_sample_loc_type_bottom_field uint8
    71  
    72  	Neutral_chroma_indication_flag uint8
    73  	Field_seq_flag                 uint8
    74  	Frame_field_info_present_flag  uint8
    75  
    76  	Default_display_window_flag uint8
    77  	Def_disp_win_left_offset    uint16
    78  	Def_disp_win_right_offset   uint16
    79  	Def_disp_win_top_offset     uint16
    80  	Def_disp_win_bottom_offset  uint16
    81  
    82  	Vui_timing_info_present_flag        uint8
    83  	Vui_num_units_in_tick               uint32
    84  	Vui_time_scale                      uint32
    85  	Vui_poc_proportional_to_timing_flag uint8
    86  	Vui_num_ticks_poc_diff_one_minus1   uint32
    87  	Vui_hrd_parameters_present_flag     uint8
    88  	Hrd_parameters                      H265RawHRDParameters
    89  
    90  	Bitstream_restriction_flag              uint8
    91  	Tiles_fixed_structure_flag              uint8
    92  	Motion_vectors_over_pic_boundaries_flag uint8
    93  	Restricted_ref_pic_lists_flag           uint8
    94  	Min_spatial_segmentation_idc            uint16
    95  	Max_bytes_per_pic_denom                 uint8
    96  	Max_bits_per_min_cu_denom               uint8
    97  	Log2_max_mv_length_horizontal           uint8
    98  	Log2_max_mv_length_vertical             uint8
    99  }
   100  
   101  func (vui *H265RawVUI) setDefault(sps *H265RawSPS) {
   102  	vui.Aspect_ratio_idc = 0
   103  
   104  	vui.Video_format = 5
   105  	vui.Video_full_range_flag = 0
   106  	vui.Colour_primaries = 2
   107  	vui.Transfer_characteristics = 2
   108  	vui.Matrix_coefficients = 2
   109  
   110  	vui.Chroma_sample_loc_type_top_field = 0
   111  	vui.Chroma_sample_loc_type_bottom_field = 0
   112  
   113  	vui.Tiles_fixed_structure_flag = 0
   114  	vui.Motion_vectors_over_pic_boundaries_flag = 1
   115  	vui.Min_spatial_segmentation_idc = 0
   116  	vui.Max_bytes_per_pic_denom = 2
   117  	vui.Max_bits_per_min_cu_denom = 1
   118  	vui.Log2_max_mv_length_horizontal = 15
   119  	vui.Log2_max_mv_length_vertical = 15
   120  }
   121  
   122  func (vui *H265RawVUI) decode(r *bits.Reader, sps *H265RawSPS) error {
   123  	vui.Aspect_ratio_info_present_flag = r.ReadBit()
   124  	if vui.Aspect_ratio_info_present_flag == 1 {
   125  		vui.Aspect_ratio_idc = r.ReadUint8(8)
   126  		if vui.Aspect_ratio_idc == 255 {
   127  			vui.Sar_width = r.ReadUint16(16)
   128  			vui.Sar_height = r.ReadUint16(16)
   129  		}
   130  	} else {
   131  		vui.Aspect_ratio_idc = 0
   132  	}
   133  
   134  	vui.Overscan_info_present_flag = r.ReadBit()
   135  	if vui.Overscan_info_present_flag == 1 {
   136  		vui.Overscan_appropriate_flag = r.ReadBit()
   137  	}
   138  
   139  	vui.Video_signal_type_present_flag = r.ReadBit()
   140  	if vui.Video_signal_type_present_flag == 1 {
   141  		vui.Video_format = r.ReadUint8(3)
   142  		vui.Video_full_range_flag = r.ReadBit()
   143  		vui.Colour_description_present_flag = r.ReadBit()
   144  		if vui.Colour_description_present_flag == 1 {
   145  			vui.Colour_primaries = r.ReadUint8(8)
   146  			vui.Transfer_characteristics = r.ReadUint8(8)
   147  			vui.Matrix_coefficients = r.ReadUint8(8)
   148  		} else {
   149  			vui.Colour_primaries = 2
   150  			vui.Transfer_characteristics = 2
   151  			vui.Matrix_coefficients = 2
   152  		}
   153  	} else {
   154  		vui.Video_format = 5
   155  		vui.Video_full_range_flag = 0
   156  		vui.Colour_primaries = 2
   157  		vui.Transfer_characteristics = 2
   158  		vui.Matrix_coefficients = 2
   159  	}
   160  
   161  	vui.Chroma_loc_info_present_flag = r.ReadBit()
   162  	if vui.Chroma_loc_info_present_flag == 1 {
   163  		vui.Chroma_sample_loc_type_top_field = r.ReadUe8()
   164  		vui.Chroma_sample_loc_type_bottom_field = r.ReadUe8()
   165  	} else {
   166  		vui.Chroma_sample_loc_type_top_field = 0
   167  		vui.Chroma_sample_loc_type_bottom_field = 0
   168  	}
   169  
   170  	vui.Neutral_chroma_indication_flag = r.ReadBit()
   171  	vui.Field_seq_flag = r.ReadBit()
   172  	vui.Frame_field_info_present_flag = r.ReadBit()
   173  
   174  	vui.Default_display_window_flag = r.ReadBit()
   175  	if vui.Default_display_window_flag == 1 {
   176  		vui.Def_disp_win_left_offset = r.ReadUe16()
   177  		vui.Def_disp_win_right_offset = r.ReadUe16()
   178  		vui.Def_disp_win_top_offset = r.ReadUe16()
   179  		vui.Def_disp_win_bottom_offset = r.ReadUe16()
   180  	}
   181  
   182  	vui.Vui_timing_info_present_flag = r.ReadBit()
   183  	if vui.Vui_timing_info_present_flag == 1 {
   184  		vui.Vui_num_units_in_tick = r.ReadUint32(32)
   185  		vui.Vui_time_scale = r.ReadUint32(32)
   186  		vui.Vui_poc_proportional_to_timing_flag = r.ReadBit()
   187  		if vui.Vui_poc_proportional_to_timing_flag == 1 {
   188  			vui.Vui_num_ticks_poc_diff_one_minus1 = r.ReadUe()
   189  		}
   190  
   191  		vui.Vui_hrd_parameters_present_flag = r.ReadBit()
   192  		if vui.Vui_hrd_parameters_present_flag == 1 {
   193  			if err := vui.Hrd_parameters.decode(r, true, int(sps.Sps_max_sub_layers_minus1)); err != nil {
   194  				return err
   195  			}
   196  		}
   197  	}
   198  
   199  	vui.Bitstream_restriction_flag = r.ReadBit()
   200  	if vui.Bitstream_restriction_flag == 1 {
   201  		vui.Tiles_fixed_structure_flag = r.ReadBit()
   202  		vui.Motion_vectors_over_pic_boundaries_flag = r.ReadBit()
   203  		vui.Restricted_ref_pic_lists_flag = r.ReadBit()
   204  		vui.Min_spatial_segmentation_idc = r.ReadUe16()
   205  		vui.Max_bytes_per_pic_denom = r.ReadUe8()
   206  		vui.Max_bits_per_min_cu_denom = r.ReadUe8()
   207  		vui.Log2_max_mv_length_horizontal = r.ReadUe8()
   208  		vui.Log2_max_mv_length_vertical = r.ReadUe8()
   209  	} else {
   210  		vui.Tiles_fixed_structure_flag = 0
   211  		vui.Motion_vectors_over_pic_boundaries_flag = 1
   212  		vui.Min_spatial_segmentation_idc = 0
   213  		vui.Max_bytes_per_pic_denom = 2
   214  		vui.Max_bits_per_min_cu_denom = 1
   215  		vui.Log2_max_mv_length_horizontal = 15
   216  		vui.Log2_max_mv_length_vertical = 15
   217  	}
   218  
   219  	return nil
   220  }
   221  
   222  type H265RawSTRefPicSet struct {
   223  	Inter_ref_pic_set_prediction_flag uint8
   224  
   225  	Delta_idx_minus1     uint8
   226  	Delta_rps_sign       uint8
   227  	Abs_delta_rps_minus1 uint16
   228  
   229  	Used_by_curr_pic_flag [HEVC_MAX_REFS]uint8
   230  	Use_delta_flag        [HEVC_MAX_REFS]uint8
   231  
   232  	Num_negative_pics        uint8
   233  	Num_positive_pics        uint8
   234  	Delta_poc_s0_minus1      [HEVC_MAX_REFS]uint16
   235  	Used_by_curr_pic_s0_flag [HEVC_MAX_REFS]uint8
   236  	Delta_poc_s1_minus1      [HEVC_MAX_REFS]uint16
   237  	Used_by_curr_pic_s1_flag [HEVC_MAX_REFS]uint8
   238  }
   239  
   240  func (ps *H265RawSTRefPicSet) decode(r *bits.Reader, st_rps_idx uint8, sps *H265RawSPS) error {
   241  	if st_rps_idx != 0 {
   242  		ps.Inter_ref_pic_set_prediction_flag = r.ReadBit()
   243  	} else {
   244  		ps.Inter_ref_pic_set_prediction_flag = 0
   245  	}
   246  
   247  	if ps.Inter_ref_pic_set_prediction_flag == 1 {
   248  		var ref_rps_idx, num_delta_pocs, num_ref_pics uint8
   249  		var ref *H265RawSTRefPicSet
   250  		var delta_rps, d_poc int
   251  		var ref_delta_poc_s0, ref_delta_poc_s1, delta_poc_s0, delta_poc_s1 [HEVC_MAX_REFS]int
   252  		var used_by_curr_pic_s0, used_by_curr_pic_s1 [HEVC_MAX_REFS]uint8
   253  
   254  		if st_rps_idx == sps.Num_short_term_ref_pic_sets {
   255  			ps.Delta_idx_minus1 = r.ReadUe8()
   256  		} else {
   257  			ps.Delta_idx_minus1 = 0
   258  		}
   259  
   260  		ref_rps_idx = st_rps_idx - (ps.Delta_idx_minus1 + 1)
   261  		ref = &sps.St_ref_pic_set[ref_rps_idx]
   262  		num_delta_pocs = ref.Num_negative_pics + ref.Num_positive_pics
   263  		// av_assert0(num_delta_pocs < HEVC_MAX_DPB_SIZE);
   264  
   265  		ps.Delta_rps_sign = r.ReadBit()
   266  		ps.Abs_delta_rps_minus1 = r.ReadUe16()
   267  		delta_rps = int((1 - 2*ps.Delta_rps_sign)) * int(ps.Abs_delta_rps_minus1+1)
   268  
   269  		num_ref_pics = 0
   270  		for j := 0; j <= int(num_delta_pocs); j++ {
   271  			ps.Used_by_curr_pic_flag[j] = r.ReadBit()
   272  			if ps.Used_by_curr_pic_flag[j] == 0 {
   273  				ps.Use_delta_flag[j] = r.ReadBit()
   274  			} else {
   275  				ps.Use_delta_flag[j] = 1
   276  			}
   277  			if ps.Use_delta_flag[j] == 1 {
   278  				num_ref_pics++
   279  			}
   280  		}
   281  		if num_ref_pics >= HEVC_MAX_DPB_SIZE {
   282  			return errors.New("Invalid stream: short-term ref pic set %d contains too many pictures.\n")
   283  		}
   284  
   285  		// Since the stored form of an RPS here is actually the delta-step
   286  		// form used when inter_ref_pic_set_prediction_flag is not set, we
   287  		// need to reconstruct that here in order to be able to refer to
   288  		// the RPS later (which is required for parsing, because we don't
   289  		// even know what syntax elements appear without it).  Therefore,
   290  		// this code takes the delta-step form of the reference set, turns
   291  		// it into the delta-array form, applies the prediction process of
   292  		// 7.4.8, converts the result back to the delta-step form, and
   293  		// stores that as the current set for future use.  Note that the
   294  		// inferences here mean that writers using prediction will need
   295  		// to fill in the delta-step values correctly as well - since the
   296  		// whole RPS prediction process is somewhat overly sophisticated,
   297  		// this hopefully forms a useful check for them to ensure their
   298  		// predicted form actually matches what was intended rather than
   299  		// an onerous additional requirement.
   300  
   301  		d_poc = 0
   302  		for i := 0; i < int(ref.Num_negative_pics); i++ {
   303  			d_poc -= int(ref.Delta_poc_s0_minus1[i] + 1)
   304  			ref_delta_poc_s0[i] = d_poc
   305  		}
   306  		d_poc = 0
   307  		for i := 0; i < int(ref.Num_positive_pics); i++ {
   308  			d_poc += int(ref.Delta_poc_s1_minus1[i] + 1)
   309  			ref_delta_poc_s1[i] = d_poc
   310  		}
   311  
   312  		i := 0
   313  		for j := ref.Num_positive_pics - 1; j >= 0; j-- {
   314  			d_poc = ref_delta_poc_s1[j] + delta_rps
   315  			if d_poc < 0 && ps.Use_delta_flag[ref.Num_negative_pics+j] == 1 {
   316  				delta_poc_s0[i] = d_poc
   317  				i++
   318  				used_by_curr_pic_s0[i] =
   319  					ps.Used_by_curr_pic_flag[ref.Num_negative_pics+j]
   320  			}
   321  		}
   322  		if delta_rps < 0 && ps.Use_delta_flag[num_delta_pocs] == 1 {
   323  			delta_poc_s0[i] = delta_rps
   324  			i++
   325  			used_by_curr_pic_s0[i] =
   326  				ps.Used_by_curr_pic_flag[num_delta_pocs]
   327  		}
   328  		for j := 0; j < int(ref.Num_negative_pics); j++ {
   329  			d_poc = ref_delta_poc_s0[j] + delta_rps
   330  			if d_poc < 0 && ps.Use_delta_flag[j] == 1 {
   331  				delta_poc_s0[i] = d_poc
   332  				i++
   333  				used_by_curr_pic_s0[i] = ps.Used_by_curr_pic_flag[j]
   334  			}
   335  		}
   336  
   337  		ps.Num_negative_pics = uint8(i)
   338  		for i := 0; i < int(ps.Num_negative_pics); i++ {
   339  			if i == 0 {
   340  				ps.Delta_poc_s0_minus1[i] =
   341  					uint16(-delta_poc_s0[i] - 1)
   342  			} else {
   343  				ps.Delta_poc_s0_minus1[i] =
   344  					uint16(-(delta_poc_s0[i] - delta_poc_s0[i-1]) - 1)
   345  			}
   346  			ps.Used_by_curr_pic_s0_flag[i] = used_by_curr_pic_s0[i]
   347  		}
   348  
   349  		i = 0
   350  		for j := ref.Num_negative_pics - 1; j >= 0; j-- {
   351  			d_poc = ref_delta_poc_s0[j] + delta_rps
   352  			if d_poc > 0 && ps.Use_delta_flag[j] == 1 {
   353  				delta_poc_s1[i] = d_poc
   354  				i++
   355  				used_by_curr_pic_s1[i] = ps.Used_by_curr_pic_flag[j]
   356  			}
   357  		}
   358  		if delta_rps > 0 && ps.Use_delta_flag[num_delta_pocs] == 1 {
   359  			delta_poc_s1[i] = delta_rps
   360  			i++
   361  			used_by_curr_pic_s1[i] =
   362  				ps.Used_by_curr_pic_flag[num_delta_pocs]
   363  		}
   364  		for j := 0; j < int(ref.Num_positive_pics); j++ {
   365  			d_poc = ref_delta_poc_s1[j] + delta_rps
   366  			if d_poc > 0 && ps.Use_delta_flag[int(ref.Num_negative_pics)+j] == 1 {
   367  				delta_poc_s1[i] = d_poc
   368  				i++
   369  				used_by_curr_pic_s1[i] =
   370  					ps.Used_by_curr_pic_flag[int(ref.Num_negative_pics)+j]
   371  			}
   372  		}
   373  
   374  		ps.Num_positive_pics = 1
   375  		for i := 0; i < int(ps.Num_positive_pics); i++ {
   376  			if i == 0 {
   377  				ps.Delta_poc_s1_minus1[i] =
   378  					uint16(delta_poc_s1[i] - 1)
   379  			} else {
   380  				ps.Delta_poc_s1_minus1[i] =
   381  					uint16(delta_poc_s1[i] - delta_poc_s1[i-1] - 1)
   382  			}
   383  
   384  			ps.Used_by_curr_pic_s1_flag[i] = used_by_curr_pic_s1[i]
   385  		}
   386  
   387  	} else {
   388  		ps.Num_negative_pics = r.ReadUe8()
   389  		ps.Num_positive_pics = r.ReadUe8()
   390  
   391  		for i := 0; i < int(ps.Num_negative_pics); i++ {
   392  			ps.Delta_poc_s0_minus1[i] = r.ReadUe16()
   393  			ps.Used_by_curr_pic_s0_flag[i] = r.ReadBit()
   394  		}
   395  
   396  		for i := 0; i < int(ps.Num_positive_pics); i++ {
   397  			ps.Delta_poc_s1_minus1[i] = r.ReadUe16()
   398  			ps.Used_by_curr_pic_s1_flag[i] = r.ReadBit()
   399  		}
   400  	}
   401  
   402  	return nil
   403  }
   404  
   405  type H265RawSPS struct {
   406  	Nal_unit_header H265RawNALUnitHeader
   407  
   408  	Sps_video_parameter_set_id uint8
   409  
   410  	Sps_max_sub_layers_minus1    uint8
   411  	Sps_temporal_id_nesting_flag uint8
   412  
   413  	Profile_tier_level H265RawProfileTierLevel
   414  
   415  	Sps_seq_parameter_set_id uint8
   416  
   417  	Chroma_format_idc          uint8
   418  	Separate_colour_plane_flag uint8
   419  
   420  	Pic_width_in_luma_samples  uint16
   421  	Pic_height_in_luma_samples uint16
   422  
   423  	Conformance_window_flag uint8
   424  	Conf_win_left_offset    uint16
   425  	Conf_win_right_offset   uint16
   426  	Conf_win_top_offset     uint16
   427  	Conf_win_bottom_offset  uint16
   428  
   429  	Bit_depth_luma_minus8   uint8
   430  	Bit_depth_chroma_minus8 uint8
   431  
   432  	Log2_max_pic_order_cnt_lsb_minus4 uint8
   433  
   434  	Sps_sub_layer_ordering_info_present_flag uint8
   435  	Sps_max_dec_pic_buffering_minus1         [HEVC_MAX_SUB_LAYERS]uint8
   436  	Sps_max_num_reorder_pics                 [HEVC_MAX_SUB_LAYERS]uint8
   437  	Sps_max_latency_increase_plus1           [HEVC_MAX_SUB_LAYERS]uint32
   438  
   439  	Log2_min_luma_coding_block_size_minus3      uint8
   440  	Log2_diff_max_min_luma_coding_block_size    uint8
   441  	Log2_min_luma_transform_block_size_minus2   uint8
   442  	Log2_diff_max_min_luma_transform_block_size uint8
   443  	Max_transform_hierarchy_depth_inter         uint8
   444  	Max_transform_hierarchy_depth_intra         uint8
   445  
   446  	Scaling_list_enabled_flag          uint8
   447  	Sps_scaling_list_data_present_flag uint8
   448  	Scaling_list                       *H265RawScalingList
   449  
   450  	Amp_enabled_flag                    uint8
   451  	Sample_adaptive_offset_enabled_flag uint8
   452  
   453  	Pcm_enabled_flag                             uint8
   454  	Pcm_sample_bit_depth_luma_minus1             uint8
   455  	Pcm_sample_bit_depth_chroma_minus1           uint8
   456  	Log2_min_pcm_luma_coding_block_size_minus3   uint8
   457  	Log2_diff_max_min_pcm_luma_coding_block_size uint8
   458  	Pcm_loop_filter_disabled_flag                uint8
   459  
   460  	Num_short_term_ref_pic_sets uint8
   461  	St_ref_pic_set              []H265RawSTRefPicSet //[HEVC_MAX_SHORT_TERM_REF_PIC_SETS]H265RawSTRefPicSet
   462  
   463  	Long_term_ref_pics_present_flag uint8
   464  	Num_long_term_ref_pics_sps      uint8
   465  	Lt_ref_pic_poc_lsb_sps          [HEVC_MAX_LONG_TERM_REF_PICS]uint16
   466  	Used_by_curr_pic_lt_sps_flag    [HEVC_MAX_LONG_TERM_REF_PICS]uint8
   467  
   468  	Sps_temporal_mvp_enabled_flag       uint8
   469  	Strong_intra_smoothing_enabled_flag uint8
   470  
   471  	Vui_parameters_present_flag uint8
   472  	Vui                         H265RawVUI
   473  
   474  	Sps_extension_present_flag    uint8
   475  	Sps_range_extension_flag      uint8
   476  	Sps_multilayer_extension_flag uint8
   477  	Sps_3d_extension_flag         uint8
   478  	Sps_scc_extension_flag        uint8
   479  	Sps_extension_4bits           uint8
   480  
   481  	// extension_data H265RawExtensionData
   482  
   483  	// // Range extension.
   484  	// transform_skip_rotation_enabled_flag    uint8
   485  	// transform_skip_context_enabled_flag     uint8
   486  	// implicit_rdpcm_enabled_flag             uint8
   487  	// explicit_rdpcm_enabled_flag             uint8
   488  	// extended_precision_processing_flag      uint8
   489  	// intra_smoothing_disabled_flag           uint8
   490  	// high_precision_offsets_enabled_flag     uint8
   491  	// persistent_rice_adaptation_enabled_flag uint8
   492  	// cabac_bypass_alignment_enabled_flag     uint8
   493  
   494  	// // Screen content coding extension.
   495  	// sps_curr_pic_ref_enabled_flag                  uint8
   496  	// palette_mode_enabled_flag                      uint8
   497  	// palette_max_size                               uint8
   498  	// delta_palette_max_predictor_size               uint8
   499  	// sps_palette_predictor_initializer_present_flag uint8
   500  	// sps_num_palette_predictor_initializer_minus1   uint8
   501  	// sps_palette_predictor_initializers             [3][128]uint16
   502  
   503  	// motion_vector_resolution_control_idc  uint8
   504  	// intra_boundary_filtering_disable_flag uint8
   505  }
   506  
   507  // Width 视频宽度(像素)
   508  func (sps *H265RawSPS) Width() int {
   509  	return int(sps.Pic_width_in_luma_samples)
   510  }
   511  
   512  // Height 视频高度(像素)
   513  func (sps *H265RawSPS) Height() int {
   514  	return int(sps.Pic_height_in_luma_samples)
   515  }
   516  
   517  // FrameRate Video frame rate
   518  func (sps *H265RawSPS) FrameRate() float64 {
   519  	if sps.Vui.Vui_num_units_in_tick == 0 {
   520  		return 0.0
   521  	}
   522  	return float64(sps.Vui.Vui_time_scale) / float64(sps.Vui.Vui_num_units_in_tick)
   523  }
   524  
   525  // IsFixedFrameRate 是否固定帧率
   526  func (sps *H265RawSPS) IsFixedFrameRate() bool {
   527  	// TODO:
   528  	return sps.FrameRate() > 0
   529  }
   530  
   531  // DecodeString 从 base64 字串解码 sps NAL
   532  func (sps *H265RawSPS) DecodeString(b64 string) error {
   533  	data, err := base64.StdEncoding.DecodeString(b64)
   534  	if err != nil {
   535  		return err
   536  	}
   537  	return sps.Decode(data)
   538  }
   539  
   540  // Decode 从字节序列中解码 sps NAL
   541  func (sps *H265RawSPS) Decode(data []byte) (err error) {
   542  	defer func() {
   543  		if r := recover(); r != nil {
   544  			err = fmt.Errorf("RawSPS decode panic;r = %v \n %s", r, debug.Stack())
   545  		}
   546  	}()
   547  
   548  	spsWEB := utils.RemoveH264or5EmulationBytes(data)
   549  	if len(spsWEB) < 4 {
   550  		return errors.New("The data is not enough")
   551  	}
   552  
   553  	r := bits.NewReader(spsWEB)
   554  	if err = sps.Nal_unit_header.decode(r); err != nil {
   555  		return
   556  	}
   557  
   558  	if sps.Nal_unit_header.Nal_unit_type != NalSps {
   559  		return errors.New("not is sps NAL UNIT")
   560  	}
   561  
   562  	sps.Sps_video_parameter_set_id = r.ReadUint8(4)
   563  
   564  	sps.Sps_max_sub_layers_minus1 = r.ReadUint8(3)
   565  	sps.Sps_temporal_id_nesting_flag = r.ReadBit()
   566  	if err = sps.Profile_tier_level.decode(r, true, int(sps.Sps_max_sub_layers_minus1)); err != nil {
   567  		return
   568  	}
   569  
   570  	sps.Sps_seq_parameter_set_id = r.ReadUe8()
   571  
   572  	sps.Chroma_format_idc = r.ReadUe8()
   573  	if sps.Chroma_format_idc == 3 {
   574  		sps.Separate_colour_plane_flag = r.ReadBit()
   575  	}
   576  
   577  	sps.Pic_width_in_luma_samples = r.ReadUe16()
   578  	sps.Pic_height_in_luma_samples = r.ReadUe16()
   579  
   580  	sps.Conformance_window_flag = r.ReadBit()
   581  	if sps.Conformance_window_flag == 1 {
   582  		sps.Conf_win_left_offset = r.ReadUe16()
   583  		sps.Conf_win_right_offset = r.ReadUe16()
   584  		sps.Conf_win_top_offset = r.ReadUe16()
   585  		sps.Conf_win_bottom_offset = r.ReadUe16()
   586  	}
   587  
   588  	sps.Bit_depth_luma_minus8 = r.ReadUe8()
   589  	sps.Bit_depth_chroma_minus8 = r.ReadUe8()
   590  
   591  	sps.Log2_max_pic_order_cnt_lsb_minus4 = r.ReadUe8()
   592  
   593  	sps.Sps_sub_layer_ordering_info_present_flag = r.ReadBit()
   594  	loopStart := uint8(0)
   595  	if sps.Sps_sub_layer_ordering_info_present_flag == 1 {
   596  		loopStart = sps.Sps_max_sub_layers_minus1
   597  	}
   598  	for i := loopStart; i <= sps.Sps_max_sub_layers_minus1; i++ {
   599  		sps.Sps_max_dec_pic_buffering_minus1[i] = r.ReadUe8()
   600  		sps.Sps_max_num_reorder_pics[i] = r.ReadUe8()
   601  		sps.Sps_max_latency_increase_plus1[i] = r.ReadUe()
   602  	}
   603  
   604  	if sps.Sps_sub_layer_ordering_info_present_flag == 0 {
   605  		for i := uint8(0); i < sps.Sps_max_sub_layers_minus1; i++ {
   606  
   607  			sps.Sps_max_dec_pic_buffering_minus1[i] =
   608  				sps.Sps_max_dec_pic_buffering_minus1[sps.Sps_max_sub_layers_minus1]
   609  			sps.Sps_max_num_reorder_pics[i] =
   610  				sps.Sps_max_num_reorder_pics[sps.Sps_max_sub_layers_minus1]
   611  			sps.Sps_max_latency_increase_plus1[i] =
   612  				sps.Sps_max_latency_increase_plus1[sps.Sps_max_sub_layers_minus1]
   613  		}
   614  	}
   615  
   616  	sps.Log2_min_luma_coding_block_size_minus3 = r.ReadUe8()
   617  	min_cb_log2_size_y := sps.Log2_min_luma_coding_block_size_minus3 + 3
   618  
   619  	sps.Log2_diff_max_min_luma_coding_block_size = r.ReadUe8()
   620  	// ctb_log2_size_y := min_cb_log2_size_y +
   621  	// 	sps.log2_diff_max_min_luma_coding_block_size
   622  
   623  	min_cb_size_y := uint16(1) << min_cb_log2_size_y
   624  	if (sps.Pic_width_in_luma_samples%min_cb_size_y) > 0 ||
   625  		(sps.Pic_height_in_luma_samples%min_cb_size_y) > 0 {
   626  		return fmt.Errorf("Invalid dimensions: %v%v not divisible by MinCbSizeY = %v.\n",
   627  			sps.Pic_width_in_luma_samples,
   628  			sps.Pic_height_in_luma_samples,
   629  			min_cb_size_y)
   630  	}
   631  
   632  	sps.Log2_min_luma_transform_block_size_minus2 = r.ReadUe8()
   633  	// min_tb_log2_size_y := sps.log2_min_luma_transform_block_size_minus2 + 2
   634  
   635  	sps.Log2_diff_max_min_luma_transform_block_size = r.ReadUe8()
   636  
   637  	sps.Max_transform_hierarchy_depth_inter = r.ReadUe8()
   638  	sps.Max_transform_hierarchy_depth_intra = r.ReadUe8()
   639  
   640  	sps.Scaling_list_enabled_flag = r.ReadBit()
   641  	if sps.Scaling_list_enabled_flag == 1 {
   642  		sps.Sps_scaling_list_data_present_flag = r.ReadBit()
   643  		if sps.Sps_scaling_list_data_present_flag == 1 {
   644  			sps.Scaling_list = new(H265RawScalingList)
   645  			sps.Scaling_list.decode(r)
   646  		}
   647  	}
   648  
   649  	sps.Amp_enabled_flag = r.ReadBit()
   650  	sps.Sample_adaptive_offset_enabled_flag = r.ReadBit()
   651  
   652  	sps.Pcm_enabled_flag = r.ReadBit()
   653  	if sps.Pcm_enabled_flag == 1 {
   654  		sps.Pcm_sample_bit_depth_luma_minus1 = r.ReadUint8(4)
   655  		sps.Pcm_sample_bit_depth_chroma_minus1 = r.ReadUint8(4)
   656  
   657  		sps.Log2_min_pcm_luma_coding_block_size_minus3 = r.ReadUe8()
   658  		sps.Log2_diff_max_min_pcm_luma_coding_block_size = r.ReadUe8()
   659  
   660  		sps.Pcm_loop_filter_disabled_flag = r.ReadBit()
   661  	}
   662  
   663  	sps.Num_short_term_ref_pic_sets = r.ReadUe8()
   664  	if sps.Num_short_term_ref_pic_sets > 0 {
   665  		sps.St_ref_pic_set = make([]H265RawSTRefPicSet, sps.Num_short_term_ref_pic_sets)
   666  		for i := uint8(0); i < sps.Num_short_term_ref_pic_sets; i++ {
   667  			sps.St_ref_pic_set[i].decode(r, i, sps)
   668  		}
   669  	}
   670  
   671  	sps.Long_term_ref_pics_present_flag = r.ReadBit()
   672  	if sps.Long_term_ref_pics_present_flag == 1 {
   673  		sps.Num_long_term_ref_pics_sps = r.ReadUe8()
   674  		for i := uint8(0); i < sps.Num_long_term_ref_pics_sps; i++ {
   675  			sps.Lt_ref_pic_poc_lsb_sps[i] = r.ReadUint16(int(sps.Log2_max_pic_order_cnt_lsb_minus4 + 4))
   676  			sps.Used_by_curr_pic_lt_sps_flag[i] = r.ReadBit()
   677  		}
   678  	}
   679  
   680  	sps.Sps_temporal_mvp_enabled_flag = r.ReadBit()
   681  	sps.Strong_intra_smoothing_enabled_flag = r.ReadBit()
   682  
   683  	sps.Vui_parameters_present_flag = r.ReadBit()
   684  	if sps.Vui_parameters_present_flag == 1 {
   685  		sps.Vui.decode(r, sps)
   686  	} else {
   687  		sps.Vui.setDefault(sps)
   688  	}
   689  
   690  	sps.Sps_extension_present_flag = r.ReadBit()
   691  
   692  	if sps.Sps_extension_present_flag == 1 {
   693  		sps.Sps_range_extension_flag = r.ReadBit()
   694  		sps.Sps_multilayer_extension_flag = r.ReadBit()
   695  		sps.Sps_3d_extension_flag = r.ReadBit()
   696  		sps.Sps_scc_extension_flag = r.ReadBit()
   697  		sps.Sps_extension_4bits = r.ReadUint8(4)
   698  	}
   699  
   700  	// if (sps.sps_range_extension_flag)
   701  	//     CHECK(FUNC(sps_range_extension)(ctx, rw, current));
   702  	// if (sps.sps_multilayer_extension_flag)
   703  	//     return AVERROR_PATCHWELCOME;
   704  	// if (sps.sps_3d_extension_flag)
   705  	//     return AVERROR_PATCHWELCOME;
   706  	// if (sps.sps_scc_extension_flag)
   707  	//     CHECK(FUNC(sps_scc_extension)(ctx, rw, current));
   708  	// if (sps.sps_extension_4bits)
   709  	//     CHECK(FUNC(extension_data)(ctx, rw, &sps.extension_data));
   710  
   711  	// CHECK(FUNC(rbsp_trailing_bits)(ctx, rw));
   712  
   713  	return
   714  }