【视频编码】H265码流格式解析

示例工程:
【视频编码】H264码流格式解析

有部分的头文件的定义位于H264码流格式解析当中,在示例工程中可以获取,下面记录H265码流格式解析

1.头文件定义(h2645_parser.h 和 hevc_parser.h)

h2645_parser.h中定义了264和265标准都会使用的结构体定义,主要是AUD和SEI,部分定义在H264当中有记录

#pragma once

//7.4.2.4 Table 7-5 Meaning of primary_pic_type
enum aud_type
{
	AUD_PRIMARY_PIC_TYPE_I = 0,				// I
	AUD_PRIMARY_PIC_TYPE_IP = 1,				// I, P
	AUD_PRIMARY_PIC_TYPE_IPB = 2,				// I, P, B
	AUD_PRIMARY_PIC_TYPE_SI = 3,				// SI
	AUD_PRIMARY_PIC_TYPE_SISP = 4,				// SI, SP
	AUD_PRIMARY_PIC_TYPE_ISI = 5,				// I, SI
	AUD_PRIMARY_PIC_TYPE_ISIPSP = 6,                // I, SI, P, SP
	AUD_PRIMARY_PIC_TYPE_ISIPSPB = 7                 // I, SI, P, SP, B
};

//D.1 SEI payload syntax
enum sei_type
{
	SEI_TYPE_BUFFERING_PERIOD = 0,
	SEI_TYPE_PIC_TIMING = 1,
	SEI_TYPE_PAN_SCAN_RECT = 2,
	SEI_TYPE_FILLER_PAYLOAD = 3,
	SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35 = 4,
	SEI_TYPE_USER_DATA_UNREGISTERED = 5,
	SEI_TYPE_RECOVERY_POINT = 6,
	SEI_TYPE_DEC_REF_PIC_MARKING_REPETITION = 7,
	SEI_TYPE_SPARE_PIC = 8,
	SEI_TYPE_SCENE_INFO = 9,
	SEI_TYPE_SUB_SEQ_INFO = 10,
	SEI_TYPE_SUB_SEQ_LAYER_CHARACTERISTICS = 11,
	SEI_TYPE_SUB_SEQ_CHARACTERISTICS = 12,
	SEI_TYPE_FULL_FRAME_FREEZE = 13,
	SEI_TYPE_FULL_FRAME_FREEZE_RELEASE = 14,
	SEI_TYPE_FULL_FRAME_SNAPSHOT = 15,
	SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_START = 16,
	SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_END = 17,
	SEI_TYPE_MOTION_CONSTRAINED_SLICE_GROUP_SET = 18,
	SEI_TYPE_FILM_GRAIN_CHARACTERISTICS = 19,
	SEI_TYPE_DEBLOCKING_FILTER_DISPLAY_PREFERENCE = 20,
	SEI_TYPE_STEREO_VIDEO_INFO = 21
};

hevc_parse.h中定义了hevc标准会使用的一些变量和函数

#pragma once
#ifndef _hevc_PARSER_H_
#define _hevc_PARSER_H_

#include <stdlib.h>
#include <string.h>

#include "base.h"
#include "bs.h"
#include "h2645_parser.h"

#define MAX_VPS_MAX_SUB_LAYERS_MINUS1	6
#define MAX_VPS_NUM_LAYER_SETS_MINUS1	1023
#define MAX_VPS_MAX_LAYER_ID			63
#define MAX_SPS_MAX_SUB_LAYERS_MINUS1	6
#define MAX_SUB_LAYERS_MINUS1			6
#define MAX_CPB_CNT_MINUS1				31

#define EXTENDED_SAR 255

#define MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1 14 // 0-14
#define MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1 14

#define MAX_NUM_SUB_LAYER_MINUS1	6

// Table 7-1 NAL unit type codecs and NAL unit type classes
typedef enum hevc_nalu_type
{
	// VCL
	NALU_TYPE_CODED_SLICE_TRAIL_N	= 0,
	NALU_TYPE_CODED_SLICE_TRAIL_R	= 1,
	NALU_TYPE_CODED_SLICE_TSA_N		= 2,
	NALU_TYPE_CODED_SLICE_TSA_R		= 3,
	NALU_TYPE_CODED_SLICE_STSA_N	= 4,
	NALU_TYPE_CODED_SLICE_STSA_R	= 5,
	NALU_TYPE_CODED_SLICE_RADL_N	= 6,
	NALU_TYPE_CODED_SLICE_RADL_R	= 7,
	NALU_TYPE_CODED_SLICE_RASL_N	= 8,
	NALU_TYPE_CODED_SLICE_RASL_R	= 9,

	NALU_TYPE_RSV_VCL_N10		= 10,
	NALU_TYPE_RSV_VCL_N12		= 12,
	NALU_TYPE_RSV_VCL_N14		= 14,

	NALU_TYPE_RSV_VCL_N11		= 11,
	NALU_TYPE_RSV_VCL_N13		= 13,
	NALU_TYPE_RSV_VCL_N15		= 15,

	NALU_TYPE_CODED_SLICE_BLA_W_LP	= 16,
	NALU_TYPE_CODED_SLICE_BLA_W_RADL= 17,
	NALU_TYPE_CODED_SLICE_BLA_N_LP	= 18,

	NALU_TYPE_CODED_SLICE_IDR_W_RADL= 19,
	NALU_TYPE_CODED_SLICE_IDR_N_LP	= 20,

	NALU_TYPE_CODED_SLICE_CRA_NUT	= 21,

	NALU_TYPE_RSV_IRAP_VCL22	= 22,
	NALU_TYPE_RSV_IRAP_VCL23	= 23,

	NALU_TYPE_RSV_VCL24		= 24,
	NALU_TYPE_RSV_VCL31		= 31,

	// non-VCL
	NALU_TYPE_VPS_NUT				= 32,
	NALU_TYPE_SPS_NUT				= 33,
	NALU_TYPE_PPS_NUT				= 34,
	NALU_TYPE_AUD_NUT				= 35,
	NALU_TYPE_EOS_NUT				= 36,
	NALU_TYPE_EOB_NUT				= 37,
	NALU_TYPE_FD_NUT				= 38,
	NALU_TYPE_PREFIX_SEI_NUT		= 39,
	NALU_TYPE_SUFFIX_SEI_NUT		= 40,
	NALU_TYPE_RSV_NVCL41			= 41,
	NALU_TYPE_RSV_NVCL47			= 47,

	NALU_TYPE_UNSPEC48				= 48,
	NALU_TYPE_UNSPEC49				= 49,
	NALU_TYPE_UNSPEC50				= 50,
	NALU_TYPE_UNSPEC51				= 51,
	NALU_TYPE_UNSPEC52				= 52,
	NALU_TYPE_UNSPEC53				= 53,
	NALU_TYPE_UNSPEC54				= 54,
	NALU_TYPE_UNSPEC55				= 55,
	NALU_TYPE_UNSPEC56				= 56,
	NALU_TYPE_UNSPEC57				= 57,
	NALU_TYPE_UNSPEC58				= 58,
	NALU_TYPE_UNSPEC59				= 59,
	NALU_TYPE_UNSPEC60				= 60,
	NALU_TYPE_UNSPEC61				= 61,
	NALU_TYPE_UNSPEC62				= 62,
	NALU_TYPE_UNSPEC63				= 63
}hevc_nalu_type_t;

// Table 7-7 – Name association to slice_type
enum SliceType
{
	H265_SH_SLICE_TYPE_B = 0,        // P (P slice)
	H265_SH_SLICE_TYPE_P = 1,        // B (B slice)
	H265_SH_SLICE_TYPE_I = 2,        // I (I slice)
};

// 7.3.1.2 NAL unit header syntax
typedef struct hevc_nal
{
	int forbidden_zero_bit;
	int nal_unit_type;
	int nuh_layer_id;
	int nuh_temporal_id_plus1;
} hevc_nal_t;

typedef struct hevc_sei
{
	int payload_type;
	int payload_size;
	uint8_t* payload;
} hevc_sei_t;

// 7.3.3 Profile, tier and level syntax
typedef struct profile_tier_level
{
	int general_profile_space;
	int general_tier_flag;
	int general_profile_idc;
	int general_profile_compatibility_flag[32];
	int general_progressive_source_flag;
	int general_interlaced_source_flag;
	int general_non_packet_constrained_flag;
	int general_frame_only_constraint_flag;
	int general_max_12bit_constraint_flag; // The number of bits in this syntax structure is not affected by this condition
	int general_max_10bit_constraint_flag;
	int general_max_8bit_constraint_flag;
	int general_max_422chroma_constraint_flag;
	int general_max_420chroma_constraint_flag;
	int general_max_monochrome_constraint_flag;
	int general_intra_constraint_flag;
	int general_one_picture_only_constraint_flag;
	int general_lower_bit_rate_contraint_flag;
	int general_max_14bit_constraint_flag;
	int general_reserved_zero_33bits;
	int general_reserved_zero_34bits;
	int general_reserved_zero_7bits;
	// int general_one_picture_only_constraint_flag;
	int general_reserved_zero_35bits;
	int general_reserved_zero_43bits;
	int general_inbld_flag;
	int general_reserved_zero_bit;
	int general_level_idc;
	int sub_layer_profile_present_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_level_present_flag[MAX_SUB_LAYERS_MINUS1];
	int reserved_zero_2bits[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_profile_space[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_tier_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_profile_idc[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_profile_compability_flag[MAX_SUB_LAYERS_MINUS1][32];
	int sub_layer_progressive_source_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_interlaced_source_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_non_packed_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_frame_only_constraint_flag[MAX_SUB_LAYERS_MINUS1];

	// The number of bits in this syntax structure is not affected by the condition
	int sub_layer_max_12bit_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_max_10bit_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_max_8bit_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_max_422chroma_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_max_420chroma_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_max_monochrome_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_intra_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_one_picture_only_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_lower_bit_rate_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_max_14bit_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_reserved_zero_33bits[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_reserved_zero_34bits[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_reserved_zero_7bits[MAX_SUB_LAYERS_MINUS1];
	// int sub_layer_one_picture_only_constraint_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_reserved_zero_35bits[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_reserved_zero_43bits[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_inbld_flag[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_reserved_zero_bit[MAX_SUB_LAYERS_MINUS1];
	int sub_layer_level_idc[MAX_SUB_LAYERS_MINUS1];
} profile_tier_level_t;

// 7.3.4 Scaling list data syntax
typedef struct hevc_scaling_list_data
{
	int scaling_list_pred_mode_flag[4][6];
	int scaling_list_pred_matrix_id_delta[4][6];
	int scaling_list_dc_coef_minus8[4][6];
	int scaling_list_delta_coef;
	int scaling_list[4][6][64];
}hevc_scaling_list_data_t;

// 7.3.7 Short-term reference picture set syntax
typedef struct st_ref_pic_set
{
	int inter_ref_pic_set_prediction_flag;
	int delta_idx_minus1;
	int delta_rps_sign;
	int abs_delta_rps_minus1;

	int used_by_curr_pic_flag[256]; // FIXME: what size?
	int use_delta_flag[256]; // FIXME: what size?

	int num_negative_pics;
	int num_positive_pics;
#define MAX_NUM_NEGATIVE_PICS 16
	int delta_poc_s0_minus1[MAX_NUM_NEGATIVE_PICS];
	int used_by_curr_pic_s0_flag[MAX_NUM_NEGATIVE_PICS];

#define MAX_NUM_POSITIVE_PICS 16
	int delta_poc_s1_minus1[MAX_NUM_POSITIVE_PICS];
	int used_by_curr_pic_s1_flag[MAX_NUM_POSITIVE_PICS];

	int num_delta_pocs;
} st_ref_pic_set_t;

// E.2.3 Sub-layer HRD parameters syntax
typedef struct sub_layer_hrd_parameters
{
	int bit_rate_value_minus1[MAX_CPB_CNT_MINUS1 + 1];
	int cpb_size_value_minus1[MAX_CPB_CNT_MINUS1 + 1];
	int cpb_size_du_value_minus1[MAX_NUM_SUB_LAYER_MINUS1 + 1];
	int bit_rate_du_value_minus1[MAX_NUM_SUB_LAYER_MINUS1 + 1];
	int cbr_flag[MAX_NUM_SUB_LAYER_MINUS1 + 1];
}sub_layer_hrd_parameters_t;

// E.2.2 HRD parameters
typedef struct hrd_parameters
{
	int nal_hrd_parameters_present_flag;
	int vcl_hrd_parameters_present_flag;
	int sub_pic_hrd_parameters_present_flag;
	int tick_divisor_minus2;
	int du_cpb_removal_delay_increment_length_minus1;
	int sub_pic_cpb_params_in_pic_timing_sei_flag;
	int dpb_output_delay_du_length_minus1;
	int bit_rate_scale;
	int cpb_size_scale;
	int cpb_size_du_scale;
	int initial_cpb_removal_delay_length_minus1;
	int au_cpb_removal_delay_length_minus1;
	int dpb_output_delay_length_minus1;
	int fixed_pic_rate_general_flag[MAX_NUM_SUB_LAYER_MINUS1];
	int fixed_pic_rate_within_cvs_flag[MAX_NUM_SUB_LAYER_MINUS1];
	int elemental_duration_in_tc_minus1[MAX_NUM_SUB_LAYER_MINUS1];
	int low_delay_hrd_flag[MAX_NUM_SUB_LAYER_MINUS1];
	int cpb_cnt_minus1[MAX_NUM_SUB_LAYER_MINUS1];
	sub_layer_hrd_parameters_t sub_layer_hrd;
	// nal -> sub_layer_hrd_parameters
	// vcl -> sub_layer_hrd_parameters
}hrd_parameters_t;

// E.2.1 VUI parameters syntax
typedef struct vui_parameters
{
	int aspect_ratio_info_present_flag;
	int aspect_ratio_idc;
	int sar_width;
	int sar_height;
	int overscan_info_present_flag;
	int overscan_appropriate_flag;
	int video_signal_type_present_flag;
	int video_format;
	int video_full_range_flag;
	int colour_description_present_flag;
	int colour_primaries;
	int transfer_characteristics;
	int matrix_coeffs;
	int chroma_loc_info_present_flag;
	int chroma_sample_loc_type_top_field;
	int chroma_sample_loc_type_bottom_field;
	int neutral_chroma_indication_flag;
	int field_seq_flag;
	int frame_field_info_present_flag;
	int default_display_window_flag;
	int def_disp_win_left_offset;
	int def_disp_win_right_offset;
	int def_disp_win_top_offset;
	int def_disp_win_bottom_offset;

	int vui_timing_info_present_flag;
	int vui_num_units_in_tick;
	int vui_time_scale;
	int vui_proc_proportioanl_to_timing_flag;
	int vui_num_ticks_poc_diff_one_minus1;
	int vui_hrd_parameters_present_flag;
	// hrd_parameters(1, sps_max_sub_layers_minus1)
	hrd_parameters_t hrd;

	int bitstream_restriction_flag;
	int tiles_fixed_structure_flag;
	int motion_vectors_over_pic_boundaries_flag;
	int restricted_ref_pic_lists_flag;
	int min_spatial_segmentation_idc;
	int max_bytes_per_pic_denom;
	int max_bits_per_min_cu_denom;
	int log2_max_mv_length_horizontal;
	int log2_max_mv_length_vertical;
}vui_parameters_t;

// 7.3.2.2.2 Sequence parameter set range extension syntax
typedef struct sps_range_extension {
	int transform_skip_rotation_enabled_flag;
	int transform_skip_context_enabled_flag;
	int implicit_rdpcm_enabled_flag;
	int explicit_rdpcm_enabled_flag;
	int extended_precision_processing_flag;
	int intra_smoothing_disabled_flag;
	int high_precision_offsets_enabled_flag;
	int persistent_rice_adaptation_enabled_flag;
	int cabac_bypass_alignment_enabled_flag;
} sps_range_extension_t;

// 7.3.2.2.3 Sequence parameter set screen content coding extension syntax
typedef struct sps_scc_extension {
	int sps_curr_pic_ref_enabled_flag;
	int palette_mode_enabled_flag;
	int palette_max_size;
	int delta_palette_max_predictor_size;
	int sps_palette_predictor_initializers_present_flag;
	int sps_num_palette_predictor_initializers_minus1;
	int sps_palette_predictor_initializer[3][1024]; // luma : [0, (1 << bitdepth_luma) - 1], chroma : [0, (1 << bitdepth_chroma) - 1]
	int motion_vector_resolution_control_idc;
	int intra_boundary_filtering_disabled_flag;
} sps_scc_extension_t;

// 7.3.2.1 Video parameter set RBSP syntax
typedef struct hevc_vps
{
	int vps_video_parameter_set_id;
	int vps_base_layer_internal_flag;
	int vps_base_layer_available_flag;
	int vps_max_layers_minus1;
	int vps_max_sub_layers_minus1; // 0-6
	int vps_temporal_id_nesting_flag;
	int vps_reserved_0xffff_16bits;
	// profile_tier_level_t* vps_profile_tier_level; // profile_tier_level(1, vps_max_sub_layers_minus1)
	profile_tier_level_t ptl;

	int vps_sub_layer_ordering_info_present_flag;
	int vps_max_dec_pic_buffering_minus1[MAX_VPS_MAX_SUB_LAYERS_MINUS1 + 1];
	int vps_max_num_reorder_pics[MAX_VPS_MAX_SUB_LAYERS_MINUS1 + 1];
	int vps_max_latency_increase_plus1[MAX_VPS_MAX_SUB_LAYERS_MINUS1 + 1];

	int vps_max_layer_id;	// 0-63
	int vps_num_layer_sets_minus1;	// 0-1023
	int layer_id_included_flag[MAX_VPS_NUM_LAYER_SETS_MINUS1][MAX_VPS_MAX_LAYER_ID + 1]; // [vps_num_layer_sets_minus1][vps_max_layer_id]
	
	int vps_timing_info_present_flag;
	  int vps_num_units_in_tick;
	  int vps_time_scale;
	  int vps_poc_proportional_to_timing_flag;
	  int vps_num_ticks_poc_diff_one_minus1;
      int vps_num_hrd_parameters; // [0, vps_num_layer_sets_minus1 + 1]
	    int hrd_layer_set_idx[MAX_VPS_NUM_LAYER_SETS_MINUS1 + 1]; // [vps_num_hrd_parameters]
		int cprms_present_flag[MAX_VPS_NUM_LAYER_SETS_MINUS1 + 1];
		hrd_parameters_t vps_hrd_parameters; // hrd_parameters_t* vps_hrd_parameters; // hrd_parameters(cprms_present_flag[i], vps_max_sub_layers_minus1)
		
	int vps_extension_flag;
	int _more_rbsp_data;
	int vps_extension_data_flag;
	// rbsp_trailing_bits
} hevc_vps_t;

// 7.3.2.2.1 General sequence parameter set RBSP syntax
typedef struct hevc_sps
{
	int sps_video_parameter_set_id;
	int sps_max_sub_layers_minus1; // [0, 6], < vps_max_sub_layers_minus1
	int sps_temporal_id_nesting_flag;
	
	profile_tier_level_t sps_profile_tier_level; // profile_tier_level_t* sps_profile_tier_level; // profile_tier_level(1, sps_max_sub_layers_minus1)

	int sps_seq_parameter_set_id;
	int chroma_format_idc;
	int separate_colour_plane_flag;
	int pic_width_in_luma_samples;
	int pic_height_in_luma_samples;
	int conformance_window_flag;
	  int conf_win_left_offset;
	  int conf_win_right_offset;
	  int conf_win_top_offset;
	  int conf_win_bottom_offset;
	int bit_depth_luma_minus8;
	int bit_depth_chroma_minus8;
	int log2_max_pic_order_cnt_lsb_minus4;
	int sps_sub_layer_ordering_info_present_flag;
	  int sps_max_dec_pic_buffering_minus1[MAX_SPS_MAX_SUB_LAYERS_MINUS1 + 1];
	  int sps_max_num_reorder_pics[MAX_SPS_MAX_SUB_LAYERS_MINUS1 + 1];
	  int sps_max_latency_increase_plus1[MAX_SPS_MAX_SUB_LAYERS_MINUS1 + 1];
	
	int log2_min_luma_coding_block_size_minus3;
	int log2_diff_max_min_luma_coding_block_size;
	int log2_min_luma_transform_block_size_minus2;
	int log2_diff_max_min_luma_transform_block_size;
	int max_transform_hierarchy_depth_inter;
	int max_transform_hierarchy_depth_intra;
	int scaling_list_enabled_flag;
	  int sps_scaling_list_data_present_flag;
	  hevc_scaling_list_data_t hevc_sl_data; // scaling_list_data()

	int amp_enabled_flag;
	int sample_adaptive_offset_enabled_flag;
	int pcm_enabled_flag;
	  int pcm_sample_bit_depth_luma_minus1;
	  int pcm_sample_bit_depth_chroma_minus1;
	  int log2_min_pcm_luma_coding_block_size_minus3;
	  int log2_diff_max_min_pcm_luma_coding_block_size;
	  int pcm_loop_filter_disabled_flag;

	int num_short_term_ref_pic_sets; // 0-64
	st_ref_pic_set_t st_rps[64];
	// st_rps[HEVC_MAX_SHORT_TERM_REF_PIC_SETS];

	int long_term_ref_pics_present_flag;
	  int num_long_term_ref_pics_sps;
#define MAX_NUM_LONG_TERM_REF_PICS_SPS	32
	  int lt_ref_pic_poc_lsb_sps[MAX_NUM_LONG_TERM_REF_PICS_SPS];
	  int used_by_curr_pic_lt_sps_flag[MAX_NUM_LONG_TERM_REF_PICS_SPS];

	int sps_temporal_mvp_enabled_flag;
	int strong_intra_smoothing_enabled_flag;
	int vui_parameters_present_flag;
	// vui_parameters()
	vui_parameters_t vui;

	int sps_extension_present_flag;
	  int sps_range_extension_flag; // sps_range_extension()
	  sps_range_extension_t sps_range_extension;
	  int sps_multiplayer_extension_flag; // sps_multilayer_extension_flag(), specified in Annex F
	  int sps_3d_extension_flag; // sps_3d_extension_flag(), specified in Annex I
	  int sps_scc_extension_flag; // sps_scc_extension()
	  sps_scc_extension_t sps_scc_extension;
	  int sps_extension_4bits;
	
	int _more_rbsp_data;
	int sps_extension_data_flag;
	// rbsp_trailing_data()

	int ChromaArrayType;
} hevc_sps_t;

// 7.3.2.3.2 Picture parameter set range extension syntax
typedef struct pps_range_extension
{
	int log2_max_transform_skip_block_size_minus2;
	int cross_component_prediction_enabled_flag;
	int chroma_qp_offset_list_enabled_flag;
	int diff_cu_chroma_qp_offset_depth;
	int chroma_qp_offset_list_len_minus1;
#define MAX_CHROMA_QP_OFFSET_LIST_LEN_MINUS1	5
	int cb_qp_offset_list[MAX_CHROMA_QP_OFFSET_LIST_LEN_MINUS1 + 1];
	int cr_qp_offset_list[MAX_CHROMA_QP_OFFSET_LIST_LEN_MINUS1 + 1];
	int log2_sao_offset_scale_luma;
	int log2_sao_offset_scale_chroma;
} pps_range_extension_t;

// 7.3.2.3.3 Picture parameter set screen content coding extension syntax
typedef struct pps_scc_extension
{
	int pps_curr_pic_ref_enabled_flag;
	int residual_adaptive_colour_transform_enabled_flag;
	int pps_slice_act_qp_offsets_present_flag;
	int pps_act_y_qp_offset_plus5;
	int pps_act_cb_qp_offset_plus5;
	int pps_act_cr_qp_offset_plus3;
	int pps_palette_predictor_initializers_present_flag;
	int pps_num_palette_predictor_initializers; // <= PaletteMaxPredictorSize (<=128)
	int monochrome_palette_flag;
	int luma_bit_depth_entry_minus8;
	int chroma_bit_depth_entry_minus8;
#define PALETTE_MAX_PREDICTOR_SIZE	128
	int pps_palette_predictor_initializer[3][PALETTE_MAX_PREDICTOR_SIZE]; // [Component][PaletteMaxPredictorSize]
} pps_scc_extension_t;

typedef struct hevc_pps {
	int pps_pic_parameter_set_id;
	int pps_seq_parameter_set_id;
	int dependent_slice_segments_enabled_flag;
	int output_flag_present_flag;
	int num_extra_slice_header_bits;
	int sign_data_hiding_enabled_flag;
	int cabac_init_present_flag;
	int num_ref_idx_l0_default_active_minus1;
	int num_ref_idx_l1_default_active_minus1;
	int init_qp_minus26;
	int constrained_intra_pred_flag;
	int transform_skip_enabled_flag;
	int cu_qp_delta_enabled_flag;
	  int diff_cu_qp_delta_depth;
	int pps_cb_qp_offset;
	int pps_cr_qp_offset;
	int pps_slice_chroma_qp_offsets_present_flag;
	int weighted_pred_flag;
	int weighted_bipred_flag;
	int transquant_bypass_enabled_flag;
	int tiles_enabled_flag;
	int entropy_coding_sync_enabled_flag;
	  int num_tile_columns_minus1;
	  int num_tile_rows_minus1;
	  int uniform_spacing_flag;
	  int column_width_minus1[128]; // [0, PicWidthInCtbsY - 1], here, we set 128. FIXME: what size?
	  int row_height_minus1[128];
	  int loop_filter_across_tiles_enabled_flag;
	int pps_loop_filter_across_slices_enabled_flag;
	int deblocking_filter_control_present_flag;
	  int deblocking_filter_override_enabled_flag;
	  int pps_deblocking_filter_disabled_flag;
	  int pps_beta_offset_div2;
	  int pps_tc_offset_div2;
	int pps_scaling_list_data_present_flag;
	hevc_scaling_list_data_t pps_sl_data;  // scaling_list_data

	int lists_modification_present_flag;
	int log2_parallel_merge_level_minus2;
	int slice_segment_header_extension_present_flag;
	int pps_extension_present_flag;
	  int pps_range_extension_flag;
	  pps_range_extension_t pps_range_extension;
	  int pps_multilayer_extension_flag;
	  int pps_3d_extension_flag;
	  int pps_scc_extension_flag;
	  pps_scc_extension_t pps_scc_extension;
	  int pps_extension_4bits;

	int _more_rbsp_data;
	int pps_extension_data_flag;

	// rbsp_trailing_bits()
} hevc_pps_t;

// 7.3.2.5 Access unit delimiter RBSP syntax
typedef struct hevc_aud
{
	uint8_t pic_type;
} hevc_aud_t;

// 7.3.2.6 End of sequence RBSP syntax
// end_of_seq_rbsp() {};

// 7.3.2.7 End of bitstream RBSP syntax
// end_of_bitstream_rbsp() {};

// 7.3.2.8 Filter data RBSP syntax
// filter_data_rbsp(){...};

// 7.3.2.9 Slice segment layer RBSP syntax
/*
slice_segment_layer_rbsp()
{
	slice_segment_header()
	slice_segment_data()
	rbsp_slice_segment_trailing_bits()
}
*/

// 7.3.2.10 RBSP slice segment trailing bits syntax
/*
rbsp_slice_segment_trailing_bits()
{
	rbsp_trailing_bits()
	while(more_rbsp_trailing_data)
	{
		cabac_zero_word // equal to 0x0000
	}
}
*/

// 7.3.2.11 RBSP trailing bits syntax
/*
rbsp_trailing_bits()
{
	rbsp_stop_one_bit // equal to 1
	while(!byte_aligned())
	{
		rbsp_alignment_zero_bit // equal to 0
	}
}
*/

// 7.3.2.12 Byte alignment syntax
// ...


// 7.3.4 Scaling list data syntax
typedef struct scaling_list_data
{
#define SIZE_ID		4
#define MATRIX_ID	6
	int scaling_list_pred_mode_flag[SIZE_ID][MATRIX_ID];
	int scaling_list_pred_matrix_id_delta[SIZE_ID][MATRIX_ID];
	int scaling_list_dc_coef_minus8[SIZE_ID - 2][MATRIX_ID];
	// scaling_list_dc_coef_minus8
	int scaling_list_delta_coef;
} scaling_list_data_t;

// 7.3.6.2 Reference picture list modification syntax
typedef struct ref_pic_lists_modification
{
	int ref_pic_list_modification_flag_l0;

	int list_entry_l0[MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1];
	int ref_pic_list_modification_flag_l1;

	int list_entry_l1[MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1];
} ref_pic_lists_modification_t;

// 7.3.6.3 Weighted prediction parameters syntax
typedef struct pred_weight_table
{
	int luma_log2_weight_denom;
	int delta_chroma_log2_weight_denom;
	// L0
	int luma_weight_l0_flag[MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1];
	int chroma_weight_l0_flag[MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1];
	int delta_luma_weight_l0[MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1];
	int luma_offset_l0[MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1];
	int delta_chroma_weight_l0[MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1][2];
	int delta_chroma_offset_l0[MAX_NUM_REF_IDX_L0_ACTIVE_MINUS1][2];
	// L1
	int luma_weight_l1_flag[MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1];
	int chroma_weight_l1_flag[MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1];
	int delta_luma_weight_l1[MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1];
	int luma_offset_l1[MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1];
	int delta_chroma_weight_l1[MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1][2];
	int delta_chroma_offset_l1[MAX_NUM_REF_IDX_L1_ACTIVE_MINUS1][2];
} pred_weight_table_t;


// 7.3.6.1 General slice segment header syntax
typedef struct hevc_slice_segment_header
{
	int first_slice_segment_in_pic_flag;
	int no_output_of_prior_pics_flag;
	int slice_pic_parameter_set_id;
	int dependent_slice_segment_flag;
	int slice_segment_address;

#define NUM_EXTRA_SLICE_HEADER_BITS 2
	int slice_reserved_flag[NUM_EXTRA_SLICE_HEADER_BITS];
	int slice_type;
	int pic_output_flag;
	int colour_plane_id;
	int slice_pic_order_cnt_lsb;
	int short_term_ref_pic_set_sps_flag;
	// st_ref_pic_set(num_short_term_ref_pic_sets)

	int short_term_ref_pic_set_idx;
	int num_long_term_sps;
	int num_long_term_pics;
#define MAX_NUM_LONG_TERM_SPS 32
#define MAX_NUM_LONG_TERM_PICS 16
	int lt_idx_sps[MAX_NUM_LONG_TERM_SPS - 1]; // FIXME: what size?

#define MAX_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 12
	int poc_lsb_lt[MAX_LOG2_MAX_PIC_ORDER_CNT_LSB_MINUS4 + 4];

	int used_by_curr_pic_lt_flag[64]; // FIXME: what size?
	int delta_poc_msb_present_flag[MAX_NUM_LONG_TERM_SPS + MAX_NUM_LONG_TERM_PICS];
	int delta_poc_msb_cycle_lt[MAX_NUM_LONG_TERM_SPS + MAX_NUM_LONG_TERM_PICS];
	int slice_temporal_mvp_enabled_flag;
	int slice_sao_luma_flag;
	int slice_sao_chroma_flag;
	int num_ref_idx_active_override_flag;
	int num_ref_idx_l0_active_minus1;
	int num_ref_idx_l1_active_minus1;

	ref_pic_lists_modification_t rplm;// ref_pic_lists_modification
	
	int mvd_l1_zero_flag;
	int cabac_init_flag;
	int collocated_from_l0_flag;
	int collocated_ref_idx;

	pred_weight_table_t pwt; // pred_weight_table
	int five_minus_max_num_merge_cand;
	int use_integer_mv_flag;
	int slice_qp_delta;
	int slice_cb_qp_offset;
	int slice_cr_qp_offset;
	int slice_act_y_qp_offset;
	int slice_act_cb_qp_offset;
	int slice_act_cr_qp_offset;
	int cu_chroma_qp_offset_enabled_flag;
	int deblocking_filter_override_flag;
	int slice_deblocking_filter_disabled_flag;
	int slice_beta_offset_div2;
	int slice_tc_offset_div2;
	int slice_loop_filter_across_slices_enabled_flag;
	int num_entry_point_offsets;
	int offset_len_minus1; // 0-31
#define MAX_NUM_ENTRY_POINT_OFFSETS 16
	int entry_point_offset_minus1[MAX_NUM_ENTRY_POINT_OFFSETS];
	int slice_segment_header_extension_length;
#define MAX_SLICE_SEGMENT_HEADER_EXTENSION_LENGTH 255
	int slice_segment_header_extension_data_byte[MAX_SLICE_SEGMENT_HEADER_EXTENSION_LENGTH];

	// byte alignment
} hevc_slice_segment_header_t;

// 7.3.8.1 General slice segment data syntax
typedef struct hevc_slice_segment_data_rbsp
{
	int rbsp_size;
	uint8_t* rbsp_buf;
} hevc_slice_segment_data_rbsp_t;

typedef struct hevc_stream
{
	hevc_nal_t* nal;
	hevc_vps_t* vps;
	hevc_sps_t* sps;
	hevc_pps_t* pps;
	hevc_aud_t* aud;
	hevc_sei_t* sei; //This is a TEMP pointer at whats in h->seis...    
	int num_seis;
	hevc_slice_segment_header_t* sh;
	hevc_slice_segment_data_rbsp_t* sd_rbsp;

	hevc_vps_t* vps_table[32]; // FIXME: what size?
	hevc_sps_t* sps_table[32];
	hevc_pps_t* pps_table[256];
	hevc_sei_t** seis;
}hevc_stream_t;

#endif // !_hevc_PARSER_H_

 
hevc_stream_t* hevc_new();
void hevc_free(hevc_stream_t* h);

int get_num_pic_total_curr(hevc_stream_t* h);


// 7.3.1.1 Nal unit syntax
void hevc_decode_nal_unit(hevc_stream_t* h, uint8_t* buf, int size);

// 7.3.2.1 Video parameter set RBSP syntax
void hevc_decode_video_parameter_set_rbsp(hevc_stream_t* h, bs_t* b);

// 7.3.2.2.1 General sequence parameter set RBSP syntax
void hevc_decode_seq_parameter_set_rbsp(hevc_stream_t* h, bs_t* b);

// 7.3.2.2.2 Sequence parameter set range extension syntax
void hevc_decode_sps_range_extension(hevc_sps_t* sps, bs_t* b);

// 7.3.2.2.3 Sequence parameter set screen content coding extension syntax
void hevc_decode_sps_scc_extension(hevc_sps_t* sps, bs_t* b);

// 7.3.2.3.1 General picture parameter set RBSP syntax
void hevc_decode_pic_parameter_set_rbsp(hevc_stream_t* h, bs_t* b);

// 7.3.2.3.2 Picture parameter set range extension syntax
void hevc_decode_pps_range_extension(hevc_stream_t* h, bs_t* b);

// 7.3.2.3.3 Picture parameter set screen content coding extension syntax
void hevc_decode_pps_scc_extension(hevc_stream_t* h, bs_t* b);

// 7.3.2.4 Supplemental enhancement information RBSP syntax
void hevc_decode_sei_rbsp(hevc_stream_t* h, bs_t* b);

// 7.3.2.9 Slice segment layer RBSP syntax
void hevc_decode_slice_segment_layer_rbsp(hevc_stream_t* h, bs_t* b);

// 7.3.2.11 RBSP trailing bits syntax
void hevc_decode_rbsp_trailing_bits(bs_t* b);

// 7.3.3 Profile, tier and level syntax
void hevc_decode_profile_tier_level(profile_tier_level_t* ptl, bs_t* b, int profile_present_flag, int max_num_sub_layer_minus1);

// 7.3.4 Scaling list data syntax
void hevc_decode_scaling_list_data(hevc_scaling_list_data_t* sl_data, bs_t* b);

// 7.3.5 Supplement enhancement information message syntax
void hevc_decode_sei(hevc_stream_t* h, bs_t* b);

// 7.3.6.2 Reference picture list modification syntax
void hevc_decode_ref_pic_lists_modification(hevc_stream_t* h, bs_t* b);

// 7.3.6.3 Weighted prediction parameters syntax
void hevc_decode_pred_weight_table(hevc_stream_t* h, bs_t* b);

// 7.3.7 Short-term reference picture set syntax
void hevc_decode_st_ref_pic_set(hevc_sps_t* sps, st_ref_pic_set_t* st_rps, bs_t* b, int num_short_term_ref_pic_sets, int st_rps_idx);

// D.1 SEI payload syntax
void hevc_decode_sei_payload(hevc_stream_t* h, bs_t* b, int payloadType, int payloadSize);

// E.2.1 VUI parameters
void hevc_decode_vui_parameters(hevc_sps_t* sps, bs_t* b);

// E.2.2 HRD parameters
void hevc_decode_hrd_parameters(hrd_parameters_t* hrd, bs_t* b, int common_inf_present_flag, int max_num_sub_layers_minus1);

// E.2.3 Sub-layer HRD parameters syntax
void hevc_decode_sub_layer_hrd_parameters(sub_layer_hrd_parameters_t* sub_layer_hrd, bs_t* b, int sub_pic_hrd_params_present_flag, int cpb_cnt);


// debug info
void hevc_debug_nal(hevc_stream_t* h, hevc_nal_t* nal);
void debug_vps(hevc_stream_t* h);
void debug_sps(hevc_stream_t* h);
void debug_pps(hevc_stream_t* h);
void debug_slice_header(hevc_stream_t* h);
void debug_aud(hevc_stream_t* h);
void debug_seis(hevc_stream_t* h);
void debug_bytes(uint8_t* buf, int len);
void debug_hrd_parameters(hrd_parameters_t* hrd, int common_inf_present_flag, int vps_max_sub_layers_minus1);

2. cpp文件(hevc_parser.cpp)

#include <stdio.h>
#include "hevc_parser.h"

hevc_stream_t* hevc_new()
{
	hevc_stream_t* h = (hevc_stream_t*)calloc(1, sizeof(hevc_stream_t));

	h->nal = (hevc_nal_t*)calloc(1, sizeof(hevc_nal_t));
	int i;

	// initialize tables
	for (i = 0; i < 32; i++) {h->vps_table[i] = (hevc_vps_t*)calloc(1, sizeof(hevc_vps_t));}
	for (i = 0; i < 32; i++) { h->sps_table[i] = (hevc_sps_t*)calloc(1, sizeof(hevc_sps_t)); }
	for (i = 0; i < 256; i++) { h->pps_table[i] = (hevc_pps_t*)calloc(1, sizeof(hevc_pps_t)); }

	h->vps = h->vps_table[0];
	h->sps = h->sps_table[0];
	h->pps = h->pps_table[0];
	h->aud = (hevc_aud_t*)calloc(1, sizeof(hevc_aud_t));
	h->num_seis = 0;
	h->seis = NULL;
	h->sei = NULL;  // This is a TEMP pointer at whats in h->seis...
	h->sh = (hevc_slice_segment_header_t*)calloc(1, sizeof(hevc_slice_segment_header_t));

	return h;
}

void hevc_sei_free(hevc_sei_t* s)
{
	if (s->payload != NULL) free(s->payload);
	free(s);
}

void hevc_free(hevc_stream_t * h)
{
	free(h->nal);
	int i;
	for (i = 0; i < 32; i++) { free(h->vps_table[i]); }
	for (i = 0; i < 32; i++) { free(h->sps_table[i]); }
	for (i = 0; i < 256; i++) { free(h->pps_table[i]); }

	free(h->aud);
	if (h->seis != NULL)
	{
		for (int i = 0; i < h->num_seis; i++)
		{
			hevc_sei_t* sei = h->seis[i];
			hevc_sei_free(sei);
		}
		free(h->seis);
	}
	free(h->sh);
	free(h);
}

void hevc_decode_sei_end_bits(hevc_stream_t * h, bs_t * b)
{
	// if the message doesn't end at a byte border
	if (!bs_byte_aligned(b))
	{
		if (!bs_read_u1(b))
			//fprintf(stderr, "WARNING: bit_equal_to_one is 0!!!!\n");
			ERROR("WARNING: bit_equal_to_one is 0");
		while (!bs_byte_aligned(b))
		{
			if (bs_read_u1(b))
				// fprintf(stderr, "WARNING: bit_equal_to_zero is 1!!!!\n");
				ERROR("WARNING: bit_equal_to_zero is 1");
		}
	}

	hevc_decode_rbsp_trailing_bits(b);
}

// 7.3.1.1 Nal unit syntax
void hevc_decode_nal_unit(hevc_stream_t* h, uint8_t* buf, int size)
{
	hevc_nal_t* nal = h->nal;

	bs_t* b = bs_new(buf, size);

	nal->forbidden_zero_bit = bs_read_f(b, 1);
	nal->nal_unit_type = bs_read_u(b, 6);
	nal->nuh_layer_id = bs_read_u(b, 6);
	nal->nuh_temporal_id_plus1 = bs_read_u(b, 3);
	bs_free(b);

	int nal_size = size;
	int rbsp_size = size;
	uint8_t* rbsp_buf = (uint8_t*)malloc(rbsp_size);

	// 在rbsp中,存在0x000003这样的分段码,函数会去掉这个分段码,将数据放到rbsp_buf中
	int rc = nal_to_rbsp(2, buf, &nal_size, rbsp_buf, &rbsp_size);

	if (rc < 0) {
		ERROR("transfer nal to rbsp failed");
		free(rbsp_buf);
		return;
	} // handle conversion error

	b = bs_new(rbsp_buf, rbsp_size);

	switch (nal->nal_unit_type)
	{
		case NALU_TYPE_VPS_NUT:
			hevc_decode_video_parameter_set_rbsp(h, b);
			break;
		case NALU_TYPE_SPS_NUT:
			hevc_decode_seq_parameter_set_rbsp(h, b);
			break;
		case NALU_TYPE_PPS_NUT:
			hevc_decode_pic_parameter_set_rbsp(h, b);
			break;
		case NALU_TYPE_PREFIX_SEI_NUT:
		case NALU_TYPE_SUFFIX_SEI_NUT:
			hevc_decode_sei_rbsp(h, b);
			break;
		case NALU_TYPE_CODED_SLICE_TRAIL_N:
		case NALU_TYPE_CODED_SLICE_TRAIL_R:
		case NALU_TYPE_CODED_SLICE_TSA_N:
		case NALU_TYPE_CODED_SLICE_TSA_R:
		case NALU_TYPE_CODED_SLICE_STSA_N:
		case NALU_TYPE_CODED_SLICE_STSA_R:
		case NALU_TYPE_CODED_SLICE_RADL_N:
		case NALU_TYPE_CODED_SLICE_RADL_R:
		case NALU_TYPE_CODED_SLICE_RASL_N:
		case NALU_TYPE_CODED_SLICE_RASL_R:
		case NALU_TYPE_CODED_SLICE_BLA_W_LP:
		case NALU_TYPE_CODED_SLICE_BLA_W_RADL:
		case NALU_TYPE_CODED_SLICE_BLA_N_LP:
		case NALU_TYPE_CODED_SLICE_IDR_W_RADL:
		case NALU_TYPE_CODED_SLICE_IDR_N_LP:
		case NALU_TYPE_CODED_SLICE_CRA_NUT:
			hevc_decode_slice_segment_layer_rbsp(h, b);
			break;
	};
}

// 7.3.2.1 Video parameter set RBSP syntax
void hevc_decode_video_parameter_set_rbsp(hevc_stream_t* h, bs_t* b)
{
	int i, j;
	int vps_video_parameter_set_id = bs_read_u(b, 4);
	h->vps = h->vps_table[vps_video_parameter_set_id];
	hevc_vps_t* vps = h->vps;
	memset(vps, 0, sizeof(hevc_vps_t));

	vps->vps_video_parameter_set_id		= vps_video_parameter_set_id;
	vps->vps_base_layer_internal_flag	= bs_read_u1(b);
	vps->vps_base_layer_available_flag	= bs_read_u1(b);
	vps->vps_max_layers_minus1			= bs_read_u(b, 6);
	vps->vps_max_sub_layers_minus1		= bs_read_u(b, 3);
	vps->vps_temporal_id_nesting_flag	= bs_read_u1(b);
	vps->vps_reserved_0xffff_16bits		= bs_read_u(b, 16);

	// profiler tier level
	hevc_decode_profile_tier_level(&(vps->ptl), b, 1, vps->vps_max_sub_layers_minus1);

	vps->vps_sub_layer_ordering_info_present_flag = bs_read_u1(b);
	for (i = (vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers_minus1);
		i <= vps->vps_max_sub_layers_minus1; i++)
	{
		vps->vps_max_dec_pic_buffering_minus1[i] = bs_read_ue(b);
		vps->vps_max_num_reorder_pics[i] = bs_read_ue(b);
		vps->vps_max_latency_increase_plus1[i] = bs_read_ue(b);
	}

	vps->vps_max_layer_id = bs_read_u(b, 6);
	vps->vps_num_layer_sets_minus1 = bs_read_ue(b);
	for (i = 1; i <= vps->vps_num_layer_sets_minus1; i++)
	{
		for (j = 0; j <= vps->vps_max_layer_id; j++)
		{
			vps->layer_id_included_flag[i][j] = bs_read_u1(b);
		}
	}

	vps->vps_timing_info_present_flag = bs_read_u1(b);
	if (vps->vps_timing_info_present_flag)
	{
		vps->vps_num_units_in_tick					= bs_read_u(b, 32);
		vps->vps_time_scale							= bs_read_u(b, 32);
		vps->vps_poc_proportional_to_timing_flag	= bs_read_u1(b);
		if (vps->vps_poc_proportional_to_timing_flag)
		{
			vps->vps_num_ticks_poc_diff_one_minus1	= bs_read_ue(b);
		}
		vps->vps_num_hrd_parameters = bs_read_ue(b);
		for (i = 0; i < vps->vps_num_hrd_parameters; i++)
		{
			vps->hrd_layer_set_idx[i] = bs_read_ue(b);
			if (i > 0)
			{
				vps->cprms_present_flag[i] = bs_read_u1(b);
			}
			hevc_decode_hrd_parameters(&(vps->vps_hrd_parameters), b, vps->cprms_present_flag[i], vps->vps_max_sub_layers_minus1);
		}
	}
	vps->vps_extension_flag = bs_read_u1(b);
	if (vps->vps_extension_flag)
	{
		while (!bs_eof(b))
		{
			vps->vps_extension_data_flag = bs_read_u1(b);
		}
	}
	hevc_decode_rbsp_trailing_bits(b);
}

// 7.3.2.2 Sequence parameter set RBSP syntax
// 7.3.2.2.1 General sequence parameter set RBSP syntax
void hevc_decode_seq_parameter_set_rbsp(hevc_stream_t* h, bs_t* b)
{
	int i, j;
	int sps_video_parameter_set_id = bs_read_u(b, 4);
	h->sps = h->sps_table[sps_video_parameter_set_id];
	hevc_sps_t* sps = h->sps;
	memset(sps, 0, sizeof(hevc_sps_t));

	sps->sps_video_parameter_set_id = sps_video_parameter_set_id;
	sps->sps_max_sub_layers_minus1 = bs_read_u(b, 3);
	sps->sps_temporal_id_nesting_flag = bs_read_u1(b);

	hevc_decode_profile_tier_level(&(sps->sps_profile_tier_level), b, 1, sps->sps_max_sub_layers_minus1);

	sps->sps_seq_parameter_set_id						= bs_read_ue(b);
	sps->chroma_format_idc								= bs_read_ue(b);
	sps->ChromaArrayType = sps->chroma_format_idc;
	if (sps->chroma_format_idc == 3)
	{
		sps->separate_colour_plane_flag					= bs_read_u1(b);
		if (sps->separate_colour_plane_flag)
		{
			sps->ChromaArrayType = 0;
		}
	}
	sps->pic_width_in_luma_samples						= bs_read_ue(b);
	sps->pic_height_in_luma_samples						= bs_read_ue(b);
	sps->conformance_window_flag						= bs_read_u1(b);
	if (sps->conformance_window_flag)
	{
		sps->conf_win_left_offset						= bs_read_ue(b);
		sps->conf_win_right_offset						= bs_read_ue(b);
		sps->conf_win_top_offset						= bs_read_ue(b);
		sps->conf_win_bottom_offset						= bs_read_ue(b);
	}
	sps->bit_depth_luma_minus8							= bs_read_ue(b);
	sps->bit_depth_chroma_minus8						= bs_read_ue(b);
	sps->log2_max_pic_order_cnt_lsb_minus4				= bs_read_ue(b);
	sps->sps_sub_layer_ordering_info_present_flag		= bs_read_u1(b);
	for (i = (sps->sps_sub_layer_ordering_info_present_flag ? 0 : sps->sps_max_sub_layers_minus1);
		i <= sps->sps_max_sub_layers_minus1; i++)
	{
		sps->sps_max_dec_pic_buffering_minus1[i]		= bs_read_ue(b);
		sps->sps_max_num_reorder_pics[i]				= bs_read_ue(b);
		sps->sps_max_latency_increase_plus1[i]			= bs_read_ue(b);
	}

	sps->log2_min_luma_coding_block_size_minus3			= bs_read_ue(b);
	sps->log2_diff_max_min_luma_coding_block_size		= bs_read_ue(b);
	sps->log2_min_luma_transform_block_size_minus2		= bs_read_ue(b);
	sps->log2_diff_max_min_luma_transform_block_size	= bs_read_ue(b);
	sps->max_transform_hierarchy_depth_inter			= bs_read_ue(b);
	sps->max_transform_hierarchy_depth_intra			= bs_read_ue(b);
	sps->scaling_list_enabled_flag						= bs_read_u1(b);
	if (sps->scaling_list_enabled_flag)
	{
		sps->sps_scaling_list_data_present_flag			= bs_read_u1(b);
		if (sps->sps_scaling_list_data_present_flag)
		{
			hevc_decode_scaling_list_data(&(sps->hevc_sl_data), b);
		}
	}

	sps->amp_enabled_flag						= bs_read_u1(b);
	sps->sample_adaptive_offset_enabled_flag	= bs_read_u1(b);
	sps->pcm_enabled_flag						= bs_read_u1(b);
	if (sps->pcm_enabled_flag)
	{
		sps->pcm_sample_bit_depth_luma_minus1				= bs_read_u(b, 4);
		sps->pcm_sample_bit_depth_chroma_minus1				= bs_read_u(b, 4);
		sps->log2_min_pcm_luma_coding_block_size_minus3		= bs_read_ue(b);
		sps->log2_diff_max_min_pcm_luma_coding_block_size	= bs_read_ue(b);
		sps->pcm_loop_filter_disabled_flag					= bs_read_u1(b);
	}
	sps->num_short_term_ref_pic_sets = bs_read_ue(b);
	for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
	{
		hevc_decode_st_ref_pic_set(sps, &sps->st_rps[i], b, sps->num_short_term_ref_pic_sets, i);
	}
	sps->long_term_ref_pics_present_flag = bs_read_u1(b);
	if (sps->long_term_ref_pics_present_flag)
	{
		sps->num_long_term_ref_pics_sps = bs_read_ue(b);
		for (i = 0; i < sps->num_long_term_ref_pics_sps; i++)
		{
			sps->lt_ref_pic_poc_lsb_sps[i] = bs_read_u(b, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
			sps->used_by_curr_pic_lt_sps_flag[i] = bs_read_u1(b);
		}
	}

	sps->sps_temporal_mvp_enabled_flag = bs_read_u1(b);
	sps->strong_intra_smoothing_enabled_flag = bs_read_u1(b);
	sps->vui_parameters_present_flag = bs_read_u1(b);
	if (sps->vui_parameters_present_flag)
	{
		hevc_decode_vui_parameters(sps, b);
	}

	sps->sps_extension_present_flag = bs_read_u1(b);
	if (sps->sps_extension_present_flag)
	{
		sps->sps_range_extension_flag = bs_read_u1(b);
		sps->sps_multiplayer_extension_flag = bs_read_u1(b);
		sps->sps_3d_extension_flag = bs_read_u1(b);
		sps->sps_scc_extension_flag = bs_read_u1(b);
		sps->sps_extension_4bits = bs_read_u(b, 4);
	}

	if (sps->sps_range_extension_flag)
	{
		hevc_decode_sps_range_extension(sps, b);
	}

	// sps_multiplayer_extension_flag
	// sps_3d_extension_flag

	if (sps->sps_scc_extension_flag)
	{
		hevc_decode_sps_scc_extension(sps, b);
	}

	if (sps->sps_extension_4bits)
	{
		while (!bs_eof(b))
		{
			sps->sps_extension_data_flag = bs_read_u1(b);
		}
	}
	hevc_decode_rbsp_trailing_bits(b);
}

// 7.3.2.2.2 Sequence parameter set range extension syntax
void hevc_decode_sps_range_extension(hevc_sps_t* sps, bs_t* b)
{
	sps_range_extension_t *sre = &sps->sps_range_extension;
	sre->transform_skip_rotation_enabled_flag = bs_read_u1(b);
	sre->transform_skip_context_enabled_flag = bs_read_u1(b);
	sre->implicit_rdpcm_enabled_flag = bs_read_u1(b);
	sre->explicit_rdpcm_enabled_flag = bs_read_u1(b);
	sre->extended_precision_processing_flag = bs_read_u1(b);
	sre->intra_smoothing_disabled_flag = bs_read_u1(b);
	sre->high_precision_offsets_enabled_flag = bs_read_u1(b);
	sre->persistent_rice_adaptation_enabled_flag = bs_read_u1(b);
	sre->cabac_bypass_alignment_enabled_flag = bs_read_u1(b);
}

// 7.3.2.2.3 Sequence parameter set screen content coding extension syntax
void hevc_decode_sps_scc_extension(hevc_sps_t* sps, bs_t* b)
{
	int i;
	int comp, num_comps;
	sps_scc_extension_t* sse = &sps->sps_scc_extension;
	sse->sps_curr_pic_ref_enabled_flag = bs_read_u1(b);
	sse->palette_mode_enabled_flag = bs_read_u1(b);
	if (sse->palette_mode_enabled_flag)
	{
		sse->palette_max_size = bs_read_ue(b);
		sse->delta_palette_max_predictor_size = bs_read_ue(b);
		sse->sps_palette_predictor_initializers_present_flag = bs_read_u1(b);
		if (sse->sps_palette_predictor_initializers_present_flag)
		{
			sse->sps_num_palette_predictor_initializers_minus1 = bs_read_ue(b);
			num_comps = (sps->chroma_format_idc == 0) ? 1 : 3;
			for (comp = 0; comp < num_comps; comp++)
			{
				for (i = 0; i <= sse->sps_num_palette_predictor_initializers_minus1; i++)
				{
					sse->sps_palette_predictor_initializer[comp][i] = bs_read_u(b, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
				}
			}
		}
	}
	sse->motion_vector_resolution_control_idc = bs_read_u(b, 2);
	sse->intra_boundary_filtering_disabled_flag = bs_read_u1(b);
}

// 7.3.2.3 Picture parameter set RBSP syntax
// 7.3.2.3.1 General picture parameter set RBSP syntax
void hevc_decode_pic_parameter_set_rbsp(hevc_stream_t* h, bs_t* b)
{
	int i;
	int pps_pic_parameter_set_id = bs_read_ue(b);
	h->pps = h->pps_table[pps_pic_parameter_set_id];
	hevc_pps_t* pps = h->pps;
	memset(pps, 0, sizeof(hevc_pps_t));
	
	pps->pps_pic_parameter_set_id = pps_pic_parameter_set_id;
	pps->pps_seq_parameter_set_id = bs_read_ue(b);
	pps->dependent_slice_segments_enabled_flag = bs_read_u1(b);
	pps->output_flag_present_flag = bs_read_u1(b);
	pps->num_extra_slice_header_bits = bs_read_u(b, 3);
	pps->sign_data_hiding_enabled_flag = bs_read_u1(b);
	pps->cabac_init_present_flag = bs_read_u1(b);
	pps->num_ref_idx_l0_default_active_minus1 = bs_read_ue(b);
	pps->num_ref_idx_l1_default_active_minus1 = bs_read_ue(b);
	pps->init_qp_minus26 = bs_read_se(b);
	pps->constrained_intra_pred_flag = bs_read_u1(b);
	pps->transform_skip_enabled_flag = bs_read_u1(b);
	pps->cu_qp_delta_enabled_flag = bs_read_u1(b);
	if (pps->cu_qp_delta_enabled_flag)
	{
		pps->diff_cu_qp_delta_depth = bs_read_ue(b);
	}
	pps->pps_cb_qp_offset = bs_read_se(b);
	pps->pps_cr_qp_offset = bs_read_se(b);
	pps->pps_slice_chroma_qp_offsets_present_flag = bs_read_u1(b);
	pps->weighted_pred_flag = bs_read_u1(b);
	pps->weighted_bipred_flag = bs_read_u1(b);
	pps->transquant_bypass_enabled_flag = bs_read_u1(b);
	pps->tiles_enabled_flag = bs_read_u1(b);
	pps->entropy_coding_sync_enabled_flag = bs_read_u1(b);
	if (pps->tiles_enabled_flag)
	{
		pps->num_tile_columns_minus1 = bs_read_ue(b);
		pps->num_tile_rows_minus1 = bs_read_ue(b);
		pps->uniform_spacing_flag = bs_read_u1(b);
		if (!pps->uniform_spacing_flag)
		{
			for (i = 0; i < pps->num_tile_columns_minus1; i++)
			{
				pps->column_width_minus1[i] = bs_read_ue(b);
			}
			for (i = 0; i < pps->num_tile_rows_minus1; i++)
			{
				pps->row_height_minus1[i] = bs_read_ue(b);
			}
		}

		pps->loop_filter_across_tiles_enabled_flag = bs_read_u1(b);
	}

	pps->pps_loop_filter_across_slices_enabled_flag = bs_read_u1(b);
	pps->deblocking_filter_control_present_flag = bs_read_u1(b);
	if (pps->deblocking_filter_control_present_flag)
	{
		pps->deblocking_filter_override_enabled_flag = bs_read_u1(b);
		pps->pps_deblocking_filter_disabled_flag = bs_read_u1(b);
		if (!pps->pps_deblocking_filter_disabled_flag)
		{
			pps->pps_beta_offset_div2 = bs_read_se(b);
			pps->pps_tc_offset_div2 = bs_read_se(b);
		}
	}

	pps->pps_scaling_list_data_present_flag = bs_read_u1(b);
	if (pps->pps_scaling_list_data_present_flag)
	{
		hevc_decode_scaling_list_data(&pps->pps_sl_data, b);
	}

	pps->lists_modification_present_flag = bs_read_u1(b);
	pps->log2_parallel_merge_level_minus2 = bs_read_ue(b);
	pps->slice_segment_header_extension_present_flag = bs_read_u1(b);
	pps->pps_extension_present_flag = bs_read_u1(b);
	if (pps->pps_extension_present_flag)
	{
		pps->pps_range_extension_flag = bs_read_u1(b);
		pps->pps_multilayer_extension_flag = bs_read_u1(b);
		pps->pps_3d_extension_flag = bs_read_u1(b);
		pps->pps_scc_extension_flag = bs_read_u1(b);
		pps->pps_extension_4bits = bs_read_u(b, 4);
	}

	if (pps->pps_range_extension_flag)
	{
		hevc_decode_pps_range_extension(h, b);
	}

	// pps_multilayer_extension
	// pps_3d_extension

	if (pps->pps_scc_extension_flag)
	{
		hevc_decode_pps_scc_extension(h, b);
	}

	if (pps->pps_extension_4bits)
	{
		while (!bs_eof(b))
		{
			pps->pps_extension_data_flag = bs_read_u1(b);
		}
	}
	hevc_decode_rbsp_trailing_bits(b);
}

// 7.3.2.3.2 Picture parameter set range extension syntax
void hevc_decode_pps_range_extension(hevc_stream_t* h, bs_t *b)
{
	int i;
	pps_range_extension_t* pps_re = &h->pps->pps_range_extension;
	memset(pps_re, 0, sizeof(pps_range_extension_t));

	if (h->pps->transform_skip_enabled_flag)
	{
		pps_re->log2_max_transform_skip_block_size_minus2 = bs_read_ue(b);
	}
	pps_re->cross_component_prediction_enabled_flag = bs_read_u1(b);
	pps_re->chroma_qp_offset_list_enabled_flag = bs_read_u1(b);
	if (pps_re->chroma_qp_offset_list_enabled_flag)
	{
		pps_re->diff_cu_chroma_qp_offset_depth = bs_read_ue(b);
		pps_re->chroma_qp_offset_list_len_minus1 = bs_read_ue(b);
		for (i = 0; i <= pps_re->chroma_qp_offset_list_len_minus1; i++)
		{
			pps_re->cb_qp_offset_list[i] = bs_read_se(b);
			pps_re->cr_qp_offset_list[i] = bs_read_se(b);
		}
	}
	pps_re->log2_sao_offset_scale_luma = bs_read_ue(b);
	pps_re->log2_sao_offset_scale_chroma = bs_read_ue(b);
}

// 7.3.2.3.3 Picture parameter set screen content coding extension syntax
void hevc_decode_pps_scc_extension(hevc_stream_t* h, bs_t* b)
{
	pps_scc_extension_t* pps_se = &h->pps->pps_scc_extension;
	pps_se->pps_curr_pic_ref_enabled_flag = bs_read_u1(b);
	pps_se->residual_adaptive_colour_transform_enabled_flag = bs_read_u1(b);
	if (pps_se->residual_adaptive_colour_transform_enabled_flag)
	{
		pps_se->pps_slice_act_qp_offsets_present_flag = bs_read_u1(b);
		pps_se->pps_act_y_qp_offset_plus5 = bs_read_se(b);
		pps_se->pps_act_cb_qp_offset_plus5 = bs_read_se(b);
		pps_se->pps_act_cr_qp_offset_plus3 = bs_read_se(b);
	}
	pps_se->pps_palette_predictor_initializers_present_flag = bs_read_u1(b);
	if (pps_se->pps_palette_predictor_initializers_present_flag)
	{
		pps_se->pps_num_palette_predictor_initializers = bs_read_ue(b);
		if (pps_se->pps_num_palette_predictor_initializers > 0)
		{
			pps_se->monochrome_palette_flag = bs_read_u1(b);
			pps_se->luma_bit_depth_entry_minus8 = bs_read_ue(b);
			if (!pps_se->monochrome_palette_flag)
			{
				pps_se->chroma_bit_depth_entry_minus8 = bs_read_ue(b);
			}
			int num_comps = pps_se->monochrome_palette_flag;
			for (int comp = 0; comp < num_comps; comp++)
			{
				for (int i = 0; i < pps_se->pps_num_palette_predictor_initializers; i++)
				{
					pps_se->pps_palette_predictor_initializer[comp][i] = bs_read_u(b, h->sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
				}
			}
		}
	}
}

//7.3.2.4 Supplemental enhancement information RBSP syntax
void hevc_decode_sei_rbsp(hevc_stream_t* h, bs_t* b)
{
	//return;
	for (int i = 0; i < h->num_seis; i++)
	{
		hevc_sei_free(h->seis[i]);
	}

	h->num_seis = 0;
	do {
		h->num_seis++;
		h->seis = (hevc_sei_t * *)realloc(h->seis, h->num_seis * sizeof(hevc_sei_t*));

		// sei new
		hevc_sei_t* s = (hevc_sei_t*)malloc(sizeof(hevc_sei_t));
		memset(s, 0, sizeof(hevc_sei_t));
		s->payload = NULL;

		h->seis[h->num_seis - 1] = s;
		h->sei = h->seis[h->num_seis - 1];
		hevc_decode_sei(h, b);
	} while (!bs_eof(b));

	hevc_decode_rbsp_trailing_bits(b);

}
// 7.3.2.11 RBSP trailing bits syntax
void hevc_decode_rbsp_trailing_bits(bs_t* b)
{
	int rbsp_stop_one_bit = bs_read_f(b, 1); // equal to 1

	while (!bs_byte_aligned(b))
	{
		int rbsp_alignment_zero_bit = bs_read_f(b, 1); // equal to 0
	}
}

// 7.3.3 Profile, tier and level syntax
void hevc_decode_profile_tier_level(profile_tier_level_t* ptl, bs_t* b, int profile_present_flag, int max_num_sub_layer_minus1)
{
	int i, j;
	int tmp1, tmp2;
	if (profile_present_flag)
	{
		ptl->general_profile_space = bs_read_u(b, 2);
		ptl->general_tier_flag = bs_read_u1(b);
		ptl->general_profile_idc = bs_read_u(b, 5);
		for (int i = 0; i < 32; i++)
		{
			ptl->general_profile_compatibility_flag[i] = bs_read_u1(b);
		}
		ptl->general_progressive_source_flag = bs_read_u1(b);
		ptl->general_interlaced_source_flag = bs_read_u1(b);
		ptl->general_non_packet_constrained_flag = bs_read_u1(b);
		ptl->general_frame_only_constraint_flag = bs_read_u1(b);

		int general_profile_idc = ptl->general_profile_idc;

		if (general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] ||
			general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] ||
			general_profile_idc == 6 || ptl->general_profile_compatibility_flag[6] ||
			general_profile_idc == 7 || ptl->general_profile_compatibility_flag[7] ||
			general_profile_idc == 8 || ptl->general_profile_compatibility_flag[8] ||
			general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] ||
			general_profile_idc == 10 || ptl->general_profile_compatibility_flag[10] ||
			general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11])
		{ // The number of bits in this syntax structure is not affected by this condition
			ptl->general_max_12bit_constraint_flag			= bs_read_u1(b);
			ptl->general_max_10bit_constraint_flag			= bs_read_u1(b);
			ptl->general_max_8bit_constraint_flag			= bs_read_u1(b);
			ptl->general_max_422chroma_constraint_flag		= bs_read_u1(b);
			ptl->general_max_420chroma_constraint_flag		= bs_read_u1(b);
			ptl->general_intra_constraint_flag				= bs_read_u1(b);
			ptl->general_one_picture_only_constraint_flag	= bs_read_u1(b);
			ptl->general_lower_bit_rate_contraint_flag		= bs_read_u1(b);
			if (general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] ||
				general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] ||
				general_profile_idc == 10 || ptl->general_profile_compatibility_flag[10] ||
				general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11])
			{
				ptl->general_max_14bit_constraint_flag = bs_read_u1(b);
				tmp1 = bs_read_u(b, 32);
				tmp2 = bs_read_u(b, 1);
				ptl->general_reserved_zero_33bits = tmp1 + tmp2;
			}
			else
			{
				tmp1 = bs_read_u(b, 32);
				tmp2 = bs_read_u(b, 2);
				ptl->general_reserved_zero_34bits = tmp1 + tmp2;
			}
		}
		else if (general_profile_idc == 2 || ptl->general_profile_compatibility_flag[2])
		{
			ptl->general_reserved_zero_7bits = bs_read_u(b, 7);
			ptl->general_one_picture_only_constraint_flag = bs_read_u1(b);
			tmp1 = bs_read_u(b, 32);
			tmp2 = bs_read_u(b, 3);
			ptl->general_reserved_zero_35bits = tmp1 + tmp2;
		}
		else
		{
			tmp1 = bs_read_u(b, 32);
			tmp2 = bs_read_u(b, 11);
			ptl->general_reserved_zero_43bits = tmp1 + tmp2;
		}
		if (general_profile_idc == 1 || ptl->general_profile_compatibility_flag[1] ||
			general_profile_idc == 2 || ptl->general_profile_compatibility_flag[2] ||
			general_profile_idc == 3 || ptl->general_profile_compatibility_flag[3] ||
			general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] ||
			general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] ||
			general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] ||
			general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11])
		{ // The number of bits in this syntax structure is not affected by this condition
			ptl->general_inbld_flag = bs_read_u1(b);
		}
		else
		{
			ptl->general_reserved_zero_bit = bs_read_u1(b);
		}
	}

	ptl->general_level_idc = bs_read_u8(b);
	for (i = 0; i < max_num_sub_layer_minus1; i++)
	{
		ptl->sub_layer_profile_present_flag[i] = bs_read_u1(b);
		ptl->sub_layer_level_present_flag[i] = bs_read_u1(b);
	}
	if (max_num_sub_layer_minus1 > 0)
	{
		for (i = max_num_sub_layer_minus1; i < 8; i++)
		{
			ptl->reserved_zero_2bits[i] = bs_read_u(b, 2);
		}
	}

	for (i = 0; i < max_num_sub_layer_minus1; i++)
	{
		if (ptl->sub_layer_profile_present_flag[i])
		{
			ptl->sub_layer_profile_space[i] = bs_read_u(b, 2);
			ptl->sub_layer_tier_flag[i] = bs_read_u1(b);
			ptl->sub_layer_profile_idc[i] = bs_read_u(b, 5);
			for (j = 0; j < 32; j++)
			{
				ptl->sub_layer_profile_compability_flag[i][j] = bs_read_u1(b);
			}
			ptl->sub_layer_progressive_source_flag[i]		= bs_read_u1(b);
			ptl->sub_layer_interlaced_source_flag[i]		= bs_read_u1(b);
			ptl->sub_layer_non_packed_constraint_flag[i]	= bs_read_u1(b);
			ptl->sub_layer_frame_only_constraint_flag[i]	= bs_read_u1(b);
			
			int sub_layer_profile_idc = ptl->sub_layer_profile_idc[i];
			if (sub_layer_profile_idc == 4 || ptl->sub_layer_profile_compability_flag[i][4] ||
				sub_layer_profile_idc == 5 || ptl->sub_layer_profile_compability_flag[i][5] ||
				sub_layer_profile_idc == 6 || ptl->sub_layer_profile_compability_flag[i][6] ||
				sub_layer_profile_idc == 7 || ptl->sub_layer_profile_compability_flag[i][7] ||
				sub_layer_profile_idc == 8 || ptl->sub_layer_profile_compability_flag[i][8] ||
				sub_layer_profile_idc == 9 || ptl->sub_layer_profile_compability_flag[i][9] ||
				sub_layer_profile_idc == 10 || ptl->sub_layer_profile_compability_flag[i][10] ||
				sub_layer_profile_idc == 11 || ptl->sub_layer_profile_compability_flag[i][11])
			{ // The number of bits in this syntax structure is not affected by this condition
				ptl->sub_layer_max_12bit_constraint_flag[i] = bs_read_u1(b);
				ptl->sub_layer_max_10bit_constraint_flag[i] = bs_read_u1(b);
				ptl->sub_layer_max_8bit_constraint_flag[i] = bs_read_u1(b);
				ptl->sub_layer_max_422chroma_constraint_flag[i] = bs_read_u1(b);
				ptl->sub_layer_max_420chroma_constraint_flag[i] = bs_read_u1(b);
				ptl->sub_layer_max_monochrome_constraint_flag[i] = bs_read_u1(b);
				ptl->sub_layer_intra_constraint_flag[i] = bs_read_u1(b);
				ptl->sub_layer_one_picture_only_constraint_flag[i] = bs_read_u1(b);
				ptl->sub_layer_lower_bit_rate_constraint_flag[i] = bs_read_u1(b);
				if (sub_layer_profile_idc == 5 || ptl->sub_layer_profile_compability_flag[i][5] ||
					sub_layer_profile_idc == 9 || ptl->sub_layer_profile_compability_flag[i][9] ||
					sub_layer_profile_idc == 10 || ptl->sub_layer_profile_compability_flag[i][10] ||
					sub_layer_profile_idc == 11 || ptl->sub_layer_profile_compability_flag[i][11])
				{
					ptl->sub_layer_max_14bit_constraint_flag[i] = bs_read_u1(b);
					tmp1 = bs_read_u(b, 32);
					tmp2 = bs_read_u(b, 1);
					ptl->sub_layer_reserved_zero_33bits[i] = tmp1 + tmp2;
				}
				else
				{
					tmp1 = bs_read_u(b, 32);
					tmp2 = bs_read_u(b, 2);
					ptl->sub_layer_reserved_zero_34bits[i] = tmp1 + tmp2;
				}
			}
			else if (sub_layer_profile_idc == 2 || ptl->sub_layer_profile_compability_flag[i][2])
			{
				ptl->sub_layer_reserved_zero_7bits[i] = bs_read_u(b, 7);
				ptl->sub_layer_one_picture_only_constraint_flag[i] = bs_read_u1(b);
				tmp1 = bs_read_u(b, 32);
				tmp2 = bs_read_u(b, 3);
				ptl->sub_layer_reserved_zero_35bits[i] = tmp1 + tmp2;
			}
			else
			{
				tmp1 = bs_read_u(b, 32);
				tmp2 = bs_read_u(b, 11);
				ptl->sub_layer_reserved_zero_43bits[i] = tmp1 + tmp2;
			}

			if (sub_layer_profile_idc == 1 || ptl->sub_layer_profile_compability_flag[i][1] ||
				sub_layer_profile_idc == 2 || ptl->sub_layer_profile_compability_flag[i][2] ||
				sub_layer_profile_idc == 3 || ptl->sub_layer_profile_compability_flag[i][3] ||
				sub_layer_profile_idc == 4 || ptl->sub_layer_profile_compability_flag[i][4] ||
				sub_layer_profile_idc == 5 || ptl->sub_layer_profile_compability_flag[i][5] ||
				sub_layer_profile_idc == 9 || ptl->sub_layer_profile_compability_flag[i][9] ||
				sub_layer_profile_idc == 11 || ptl->sub_layer_profile_compability_flag[i][11])
			{ // The number of bits in this syntax structure is not affected by this condition
				ptl->sub_layer_inbld_flag[i] = bs_read_u1(b);
			}
			else
			{
				ptl->sub_layer_reserved_zero_bit[i] = bs_read_u1(b);
			}
		}
		if (ptl->sub_layer_level_present_flag[i])
		{
			ptl->sub_layer_level_idc[i] = bs_read_u8(b);
		}
	}
}

// 7.3.4 Scaling list data syntax
void hevc_decode_scaling_list_data(hevc_scaling_list_data_t* sl_data, bs_t* b)
{
	int i, j, k;
	int next_coef, coef_num;
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 6; j += (i == 3) ? 3 : 1)
		{
			sl_data->scaling_list_pred_mode_flag[i][j] = bs_read_u1(b);
			if (!sl_data->scaling_list_pred_mode_flag[i][j])
			{
				sl_data->scaling_list_pred_matrix_id_delta[i][j] = bs_read_ue(b);
			}
			else
			{
				next_coef = 8;
				coef_num = ff_min(64, 1 << (4 + (i << 1)));
				if (i > 1)
				{
					sl_data->scaling_list_dc_coef_minus8[i - 2][j] = bs_read_se(b);
					next_coef = sl_data->scaling_list_dc_coef_minus8[i - 2][j] = 8;
				}

				for (k = 0; k < coef_num; k++)
				{
					sl_data->scaling_list_delta_coef = bs_read_se(b);
					next_coef = (next_coef + sl_data->scaling_list_delta_coef + 256) % 256;
					sl_data->scaling_list[i][j][k] = next_coef;
				}
			}
		}
	}
}

// 7.3.5 Supplement enhancement information message syntax
void hevc_decode_sei(hevc_stream_t* h, bs_t* b)
{
	h->sei->payload_type = _read_ff_coded_number(b);
	h->sei->payload_size = _read_ff_coded_number(b);
	hevc_decode_sei_payload(h, b, h->sei->payload_type, h->sei->payload_size);
	hevc_decode_rbsp_trailing_bits(b);
}

// 7.3.6 Slice segment header syntax
// 7.3.6.1 General slice segment header syntax
void hevc_decoed_slice_segment_header(hevc_stream_t* h, bs_t* b)
{
	hevc_slice_segment_header_t* sh = h->sh;
	sh->first_slice_segment_in_pic_flag = bs_read_u1(b);

	hevc_sps_t* sps = h->sps;
	hevc_pps_t* pps = h->pps;

	if (h->nal->nal_unit_type >= NALU_TYPE_CODED_SLICE_BLA_W_LP && h->nal->nal_unit_type <= NALU_TYPE_RSV_IRAP_VCL23)
	{
		sh->no_output_of_prior_pics_flag = bs_read_u1(b);
	}
	sh->slice_pic_parameter_set_id = bs_read_ue(b);
	if (!sh->first_slice_segment_in_pic_flag)
	{
		if (pps->dependent_slice_segments_enabled_flag)
		{
			sh->dependent_slice_segment_flag = bs_read_u1(b);
		}
		sh->slice_segment_address = bs_read_u(b, h->sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
	}

	int cu_qp_delta_val = 0;
	if (!sh->dependent_slice_segment_flag)
	{
		for (int i = 0; i < h->pps->num_extra_slice_header_bits; i++)
		{
			sh->slice_reserved_flag[i] = bs_read_u1(b);
		}
		sh->slice_type = bs_read_ue(b);
		if (pps->output_flag_present_flag)
		{
			sh->pic_output_flag = bs_read_u1(b);
		}

		if (sps->separate_colour_plane_flag == 1)
		{
			sh->colour_plane_id = bs_read_u(b, 2);
		}

		if (h->nal->nal_unit_type != NALU_TYPE_CODED_SLICE_IDR_W_RADL && h->nal->nal_unit_type != NALU_TYPE_CODED_SLICE_IDR_N_LP)
		{
			sh->slice_pic_order_cnt_lsb = bs_read_u(b, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
			sh->short_term_ref_pic_set_sps_flag = bs_read_u1(b);
			if (!sh->short_term_ref_pic_set_sps_flag)
			{
				hevc_decode_st_ref_pic_set(sps, sps->st_rps, b, sps->num_short_term_ref_pic_sets, 0);
			}
			else if (sps->num_short_term_ref_pic_sets > 1)
			{
				sh->short_term_ref_pic_set_idx = bs_read_u(b, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
			}

			if (sps->long_term_ref_pics_present_flag)
			{
				if (sps->num_long_term_ref_pics_sps > 0)
				{
					sh->num_long_term_sps = bs_read_ue(b);
				}
				sh->num_long_term_pics = bs_read_ue(b);
				for (int i = 0; i < sh->num_long_term_sps + sh->num_long_term_pics; i++)
				{
					if (i < sh->num_long_term_sps)
					{
						if (sps->num_long_term_ref_pics_sps > 1)
						{
							sh->lt_idx_sps[i] = bs_read_u(b, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
						}
					}
					else
					{
						sh->poc_lsb_lt[i] = bs_read_u(b, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
						sh->used_by_curr_pic_lt_flag[i] = bs_read_u1(b);
					}
					sh->delta_poc_msb_present_flag[i] = bs_read_u1(b);
					if (sh->delta_poc_msb_present_flag[i])
					{
						sh->delta_poc_msb_cycle_lt[i] = bs_read_ue(b);
					}
				}
			}

			if (sps->sps_temporal_mvp_enabled_flag)
			{
				sh->slice_temporal_mvp_enabled_flag = bs_read_u1(b);
			}
		}

		if (sps->sample_adaptive_offset_enabled_flag)
		{
			sh->slice_sao_luma_flag = bs_read_u1(b);
			if (sps->ChromaArrayType != 0)
			{
				sh->slice_sao_chroma_flag = bs_read_u1(b);
			}
		}

		if (sh->slice_type == H265_SH_SLICE_TYPE_P || sh->slice_type == H265_SH_SLICE_TYPE_B)
		{
			sh->num_ref_idx_active_override_flag = bs_read_u1(b);
			if (sh->num_ref_idx_active_override_flag)
			{
				sh->num_ref_idx_l0_active_minus1 = bs_read_ue(b);
				if (sh->slice_type == H265_SH_SLICE_TYPE_B)
				{
					sh->num_ref_idx_l1_active_minus1 = bs_read_ue(b);
				}
			}

			int num_pic_total_curr = 0;
			if (pps->lists_modification_present_flag && get_num_pic_total_curr(h))
			{
				hevc_decode_ref_pic_lists_modification(h, b);
			}

			if (sh->slice_type == H265_SH_SLICE_TYPE_B)
			{
				sh->mvd_l1_zero_flag = bs_read_u1(b);
			}
			if (h->pps->cabac_init_present_flag)
			{
				sh->cabac_init_flag = bs_read_u1(b);
			}
			if (sh->slice_temporal_mvp_enabled_flag)
			{
				if (sh->slice_type == H265_SH_SLICE_TYPE_B)
				{
					sh->collocated_from_l0_flag = bs_read_u1(b);
				}
				if ((sh->collocated_from_l0_flag && sh->num_ref_idx_l0_active_minus1 > 0) ||
					(!sh->collocated_from_l0_flag && sh->num_ref_idx_l1_active_minus1 > 0))
				{
					sh->collocated_ref_idx = bs_read_ue(b);
				}
			}
			if ((h->pps->weighted_pred_flag && sh->slice_type == H265_SH_SLICE_TYPE_P) ||
				(h->pps->weighted_bipred_flag && sh->slice_type == H265_SH_SLICE_TYPE_B))
			{
				hevc_decode_pred_weight_table(h, b);
			}
			sh->five_minus_max_num_merge_cand = bs_read_ue(b);
			if (h->sps->sps_scc_extension.motion_vector_resolution_control_idc == 2)
			{
				sh->use_integer_mv_flag = bs_read_u1(b);
			}
		}

		sh->slice_qp_delta = bs_read_se(b);
		if (h->pps->pps_slice_chroma_qp_offsets_present_flag)
		{
			sh->slice_cb_qp_offset = bs_read_se(b);
			sh->slice_cr_qp_offset = bs_read_se(b);
		}
		if (h->pps->pps_scc_extension.pps_slice_act_qp_offsets_present_flag)
		{
			sh->slice_act_y_qp_offset = bs_read_se(b);
			sh->slice_act_cb_qp_offset = bs_read_se(b);
			sh->slice_act_cr_qp_offset = bs_read_se(b);
		}
		if (h->pps->pps_range_extension.chroma_qp_offset_list_enabled_flag)
		{
			sh->cu_chroma_qp_offset_enabled_flag = bs_read_u1(b);
		}
		if (h->pps->deblocking_filter_override_enabled_flag)
		{
			sh->deblocking_filter_override_flag = bs_read_u1(b);
		}
		if (sh->deblocking_filter_override_flag)
		{
			sh->slice_deblocking_filter_disabled_flag = bs_read_u1(b);
			if (!sh->slice_deblocking_filter_disabled_flag)
			{
				sh->slice_beta_offset_div2 = bs_read_se(b);
				sh->slice_tc_offset_div2 = bs_read_se(b);
			}
		}

		if (h->pps->pps_loop_filter_across_slices_enabled_flag && 
			(sh->slice_sao_luma_flag || sh->slice_sao_chroma_flag || !sh->slice_deblocking_filter_disabled_flag))
		{
			sh->slice_loop_filter_across_slices_enabled_flag = bs_read_u1(b);
		}
	}

	if (h->pps->tiles_enabled_flag || h->pps->entropy_coding_sync_enabled_flag)
	{
		sh->num_entry_point_offsets = bs_read_ue(b);
		if (sh->num_entry_point_offsets > 0)
		{
			sh->offset_len_minus1 = bs_read_ue(b);
			for (int i = 0; i < sh->num_entry_point_offsets; i++)
			{
				sh->entry_point_offset_minus1[i] = bs_read_u(b, h->sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
			}
		}
	}
	
	if (h->pps->slice_segment_header_extension_present_flag)
	{
		sh->slice_segment_header_extension_length = bs_read_ue(b);
		for (int i = 0; i < sh->slice_segment_header_extension_length; i++)
		{
			sh->slice_segment_header_extension_data_byte[i] = bs_read_u8(b);
		}
	}
	bs_byte_aligned(b);
}

// 7.3.6.2 Reference picture list modification syntax
void hevc_decode_ref_pic_lists_modification(hevc_stream_t* h, bs_t* b)
{
	int i;
	ref_pic_lists_modification_t* rplm = &h->sh->rplm;
	rplm->ref_pic_list_modification_flag_l0 = bs_read_u1(b);
	if (rplm->ref_pic_list_modification_flag_l0)
	{
		for (i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++)
		{
			rplm->list_entry_l0[i] = bs_read_u(b, h->sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
		}
	}
	if (h->sh->slice_type == H265_SH_SLICE_TYPE_B)
	{
		rplm->ref_pic_list_modification_flag_l1 = bs_read_u1(b);
		if (rplm->ref_pic_list_modification_flag_l1)
		{
			for (i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++)
			{
				rplm->list_entry_l1[i] = bs_read_u(b, h->sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
			}
		}
	}

}

// 7.3.6.3 Weighted prediction parameters syntax
void hevc_decode_pred_weight_table(hevc_stream_t* h, bs_t* b)
{
	int i, j;
	pred_weight_table_t* pwt = &h->sh->pwt;
	pwt->luma_log2_weight_denom = bs_read_ue(b);
	if (h->sps->ChromaArrayType != 0)
	{
		pwt->delta_chroma_log2_weight_denom = bs_read_se(b);
	}
	
	for (i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++) // FIXME: should add pic_layer_id check and nuh_layer_id check
	{	
		pwt->luma_weight_l0_flag[i] = bs_read_u1(b);
	}
	if (h->sps->ChromaArrayType != 0)
	{
		for (i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++) // FIXME: should add pic_layer_id check and nuh_layer_id check
		{
			pwt->chroma_weight_l0_flag[i] = bs_read_u1(b);
		}
	}

	for (i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++)
	{
		if (pwt->luma_weight_l0_flag[i])
		{
			pwt->delta_luma_weight_l0[i] = bs_read_se(b);
			pwt->luma_offset_l0[i] = bs_read_se(b);
		}
		if (pwt->chroma_weight_l0_flag)
		{
			for (j = 0; j < 2; j++)
			{
				pwt->delta_chroma_weight_l0[i][j] = bs_read_se(b);
				pwt->delta_chroma_offset_l0[i][j] = bs_read_se(b);
			}
		}
	}

	if (h->sh->slice_type == H265_SH_SLICE_TYPE_B)
	{
		for (i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++) // FIXME: add pic_layer_id check
		{
			pwt->luma_weight_l1_flag[i] = bs_read_u1(b);
		}

		if (h->sps->ChromaArrayType != 0)
		{
			for (i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++) // FIXME: add pic_layer_id check
			{
				pwt->chroma_weight_l1_flag[i] = bs_read_u1(b);
			}
		}

		for (i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++)
		{
			if (pwt->luma_weight_l1_flag[i])
			{
				pwt->delta_luma_weight_l1[i] = bs_read_se(b);
				pwt->luma_offset_l1[i] = bs_read_se(b);
			}
			if (h->sps->ChromaArrayType != 0)
			{
				for (j = 0; j < 2; j++)
				{
					pwt->delta_chroma_weight_l1[i][j] = bs_read_se(b);
					pwt->delta_chroma_offset_l1[i][j] = bs_read_se(b);
				}
			}
		}
	}
}

int get_num_pic_total_curr(hevc_stream_t* h)
{
	int num_pic_total_curr = 0;
	st_ref_pic_set_t* sp_rps = h->sps->st_rps; // FIXME: h->sps->st_rps[idx]
	int i;
	
	for (i = 0; i < sp_rps->num_negative_pics; i++)
	{
		if (sp_rps->used_by_curr_pic_s0_flag[i])
		{
			num_pic_total_curr++;
		}
	}

	for (i = 0; i < sp_rps->num_positive_pics; i++)
	{
		if (sp_rps->used_by_curr_pic_s1_flag[i])
		{
			num_pic_total_curr++;
		}
	}

	for (i = 0; i < h->sh->num_long_term_sps + h->sh->num_long_term_pics; i++)
	{
		if (sp_rps->used_by_curr_pic_s1_flag[i])
		{
			num_pic_total_curr++;
		}
	}

	if (h->pps->pps_scc_extension.pps_curr_pic_ref_enabled_flag)
	{
		num_pic_total_curr++;
	}

	return num_pic_total_curr;
}

// 7.3.7 Short-term reference picture set syntax
void hevc_decode_st_ref_pic_set(hevc_sps_t* sps, st_ref_pic_set_t* st_rps, bs_t* b, int num_short_term_ref_pic_sets, int st_rps_idx)
{
	int i;
	if (st_rps_idx != 0)
	{
		st_rps->inter_ref_pic_set_prediction_flag = bs_read_u1(b);
		if (st_rps->inter_ref_pic_set_prediction_flag)
		{
			const st_ref_pic_set_t* tmp_rps;
			if (st_rps_idx == num_short_term_ref_pic_sets)
			{
				st_rps->delta_idx_minus1 = bs_read_ue(b);
			}
			st_rps->delta_rps_sign = bs_read_u1(b);
			st_rps->abs_delta_rps_minus1 = bs_read_ue(b);
			tmp_rps = &sps->st_rps[st_rps - sps->st_rps - 1];
			for (i = 0; i <= tmp_rps->num_delta_pocs; i++)
			{
				st_rps->used_by_curr_pic_flag[i] = bs_read_u1(b);
				if (!st_rps->used_by_curr_pic_flag[i])
				{
					st_rps->use_delta_flag[i] = bs_read_u1(b);
				}
			}
		}
		else
		{
			st_rps->num_negative_pics = bs_read_ue(b);
			st_rps->num_positive_pics = bs_read_ue(b);
			for (i = 0; i <= st_rps->num_negative_pics; i++)
			{
				st_rps->delta_poc_s0_minus1[i] = bs_read_ue(b);
				st_rps->used_by_curr_pic_s0_flag[i] = bs_read_u1(b);
			}

			for (i = 0; i <= st_rps->num_positive_pics; i++)
			{
				st_rps->delta_poc_s1_minus1[i] = bs_read_ue(b);
				st_rps->used_by_curr_pic_s1_flag[i] = bs_read_u1(b);
			}
		}
	}
}

// 7.xx RBSP trailing bits syntax
//void hevc_decode_rbsp_trailing_bits(bs_t* b)
//{
//	int rbsp_stop_one_bit = bs_read_f(b, 1); // equal to 1
//
//	while (!bs_byte_aligned(b))
//	{
//		int rbsp_alignment_zero_bit = bs_read_f(b, 1); // equal to 0
//	}
//}

static void decode_user_data_unregistered(hevc_stream_t* h, bs_t* b, int payloadSize)
{
	hevc_sei_t* s = h->sei;

	s->payload = (uint8_t*)malloc(payloadSize);

	int i;

	for (i = 0; i < 16; i++)
		s->payload[i] = bs_read_u(b, 8);
	for (i = 16; i < payloadSize; i++)
		s->payload[i] = bs_read_u(b, 8);
}


// D.1 SEI payload syntax
void hevc_decode_sei_payload(hevc_stream_t* h, bs_t* b, int payloadType, int payloadSize)
{
	int sei_type = h->nal->nal_unit_type;
	hevc_sei_t* s = h->sei;

	if (sei_type == NALU_TYPE_PREFIX_SEI_NUT)
	{
		switch (payloadType)
		{
		case 0:
			break;
		case 1:
			break;
		case 2:
			break;
		case 3:
			break;
		case 4:
			break;
		case 5:
			decode_user_data_unregistered(h, b, payloadSize);
			break;
		default:
			break;
		}
	}
	else if (sei_type == NALU_TYPE_SUFFIX_SEI_NUT)
	{
		switch (payloadType)
		{
		case 3:
			break;
		case 4:
			break;
		case 5:
			break;
		case 17:
			break;
		case 22:
			break;
		case 132:
			break;
		default:
			break;
		}
	}


	hevc_decode_sei_end_bits(h, b);
}

// E.2.1 VUI parameters
void hevc_decode_vui_parameters(hevc_sps_t* sps, bs_t* b)
{
	vui_parameters_t* vui = &sps->vui;
	vui->aspect_ratio_info_present_flag = bs_read_u1(b);
	if (vui->aspect_ratio_info_present_flag)
	{
		vui->aspect_ratio_idc = bs_read_u8(b);
		if (vui->aspect_ratio_idc == EXTENDED_SAR)
		{
			vui->sar_width = bs_read_u(b, 16);
			vui->sar_height = bs_read_u(b, 16);
		}
	}

	vui->overscan_info_present_flag = bs_read_u1(b);
	if (vui->overscan_info_present_flag)
	{
		vui->overscan_appropriate_flag = bs_read_u1(b);
	}
	vui->video_signal_type_present_flag = bs_read_u1(b);
	if (vui->video_signal_type_present_flag)
	{
		vui->video_format = bs_read_u(b, 3);
		vui->video_full_range_flag = bs_read_u1(b);
		vui->colour_description_present_flag = bs_read_u1(b);
		if (vui->colour_description_present_flag)
		{
			vui->colour_primaries = bs_read_u8(b);
			vui->transfer_characteristics = bs_read_u8(b);
			vui->matrix_coeffs = bs_read_u8(b);
		}
	}
	vui->chroma_loc_info_present_flag = bs_read_u1(b);
	if (vui->chroma_loc_info_present_flag)
	{
		vui->chroma_sample_loc_type_top_field = bs_read_ue(b);
		vui->chroma_sample_loc_type_bottom_field = bs_read_ue(b);
	}

	vui->neutral_chroma_indication_flag = bs_read_u1(b);
	vui->field_seq_flag = bs_read_u1(b);
	vui->frame_field_info_present_flag = bs_read_u1(b);
	vui->default_display_window_flag = bs_read_u1(b);
	if (vui->default_display_window_flag)
	{
		vui->def_disp_win_left_offset = bs_read_ue(b);
		vui->def_disp_win_right_offset = bs_read_ue(b);
		vui->def_disp_win_top_offset = bs_read_ue(b);
		vui->def_disp_win_bottom_offset = bs_read_ue(b);
	}

	vui->vui_timing_info_present_flag = bs_read_u1(b);
	if (vui->vui_timing_info_present_flag)
	{
		vui->vui_num_units_in_tick = bs_read_u(b, 32);
		vui->vui_time_scale = bs_read_u(b, 32);
		vui->vui_proc_proportioanl_to_timing_flag = bs_read_u1(b);
		if (vui->vui_proc_proportioanl_to_timing_flag)
		{
			vui->vui_num_ticks_poc_diff_one_minus1 = bs_read_ue(b);
		}
		vui->vui_hrd_parameters_present_flag = bs_read_u1(b);
		if (vui->vui_hrd_parameters_present_flag)
		{
			hevc_decode_hrd_parameters(&(vui->hrd), b, 1, sps->sps_max_sub_layers_minus1);
		}
	}

	vui->bitstream_restriction_flag = bs_read_u1(b);
	if (vui->bitstream_restriction_flag)
	{
		vui->tiles_fixed_structure_flag = bs_read_u1(b);
		vui->motion_vectors_over_pic_boundaries_flag = bs_read_u1(b);
		vui->restricted_ref_pic_lists_flag = bs_read_u1(b);
		vui->min_spatial_segmentation_idc = bs_read_ue(b);
		vui->max_bytes_per_pic_denom = bs_read_ue(b);
		vui->max_bits_per_min_cu_denom = bs_read_ue(b);
		vui->log2_max_mv_length_horizontal = bs_read_ue(b);
		vui->log2_max_mv_length_vertical = bs_read_ue(b);
	}
}

// E.2.2 HRD parameters
void hevc_decode_hrd_parameters(hrd_parameters_t* hrd, bs_t* b, int common_inf_present_flag,
							  int max_num_sub_layers_minus1)
{
	if (common_inf_present_flag)
	{
		hrd->nal_hrd_parameters_present_flag = bs_read_u1(b);
		hrd->vcl_hrd_parameters_present_flag = bs_read_u1(b);
		if (hrd->nal_hrd_parameters_present_flag || hrd->vcl_hrd_parameters_present_flag)
		{
			hrd->sub_pic_hrd_parameters_present_flag = bs_read_u1(b);
			if (hrd->sub_pic_hrd_parameters_present_flag)
			{
				hrd->tick_divisor_minus2 = bs_read_u8(b);
				hrd->du_cpb_removal_delay_increment_length_minus1 = bs_read_u(b, 5);
				hrd->sub_pic_cpb_params_in_pic_timing_sei_flag = bs_read_u(b, 1);
				hrd->dpb_output_delay_du_length_minus1 = bs_read_u(b, 5);
			}

			hrd->bit_rate_scale = bs_read_u(b, 4);
			hrd->cpb_size_scale = bs_read_u(b, 4);
			if (hrd->sub_pic_hrd_parameters_present_flag)
			{
				hrd->cpb_size_du_scale = bs_read_u(b, 4);
			}
			hrd->initial_cpb_removal_delay_length_minus1	= bs_read_u(b, 5);
			hrd->au_cpb_removal_delay_length_minus1			= bs_read_u(b, 5);
			hrd->dpb_output_delay_length_minus1				= bs_read_u(b, 5);
		}
	}
	for (int i = 0; i <= max_num_sub_layers_minus1; i++)
	{
		hrd->fixed_pic_rate_general_flag[i] = bs_read_u1(b);
		if (!hrd->fixed_pic_rate_general_flag[i])
		{
			hrd->fixed_pic_rate_within_cvs_flag[i] = bs_read_u1(b);
		}

		if (hrd->fixed_pic_rate_within_cvs_flag[i])
		{
			hrd->elemental_duration_in_tc_minus1[i] = bs_read_ue(b);
		}
		else
		{
			hrd->low_delay_hrd_flag[i] = bs_read_u1(b);
		}

		if (!hrd->low_delay_hrd_flag[i])
		{
			hrd->cpb_cnt_minus1[i] = bs_read_ue(b);
		}

		int b_sub_layer_hrd_parameters = hrd->nal_hrd_parameters_present_flag || hrd->vcl_hrd_parameters_present_flag;
		if (b_sub_layer_hrd_parameters)
		{
			if (hrd->nal_hrd_parameters_present_flag)
			{
				hevc_decode_sub_layer_hrd_parameters(&hrd->sub_layer_hrd, b, hrd->sub_pic_hrd_parameters_present_flag, hrd->cpb_cnt_minus1[i]);
			}
			if (hrd->vcl_hrd_parameters_present_flag)
			{
				hevc_decode_sub_layer_hrd_parameters(&hrd->sub_layer_hrd, b, hrd->sub_pic_hrd_parameters_present_flag, hrd->cpb_cnt_minus1[i]);
			}
		}
	}
}

// E.2.3 Sub-layer HRD parameters syntax
void hevc_decode_sub_layer_hrd_parameters(sub_layer_hrd_parameters_t* sub_layer_hrd, bs_t* b, int sub_pic_hrd_params_present_flag, int cpb_cnt)
{
	int i;
	for (i = 0; i < cpb_cnt; i++)
	{
		sub_layer_hrd->bit_rate_value_minus1[i] = bs_read_ue(b);
		sub_layer_hrd->cpb_size_value_minus1[i] = bs_read_ue(b);
		if (sub_pic_hrd_params_present_flag)
		{
			sub_layer_hrd->cpb_size_du_value_minus1[i] = bs_read_ue(b);
			sub_layer_hrd->bit_rate_du_value_minus1[i] = bs_read_ue(b);
		}
		sub_layer_hrd->cbr_flag[i] = bs_read_u1(b);
	}
}

void hevc_decode_slice_segment_layer_rbsp(hevc_stream_t* h, bs_t* b)
{
	hevc_decoed_slice_segment_header(h, b);
	// hevc_decode_slice_segment_data
	// rbsp_slice_segment_trailing_bits
}

// debug info
void hevc_debug_nal(hevc_stream_t* h, hevc_nal_t* nal)
{
	printf("==================== NAL ====================\n");
	printf(" forbidden_zero_bit : %d \n", nal->forbidden_zero_bit);
	printf(" nal_unit_type : %d \n", nal->nal_unit_type);
	printf(" nuh_layer_id : %d \n", nal->nuh_layer_id);
	printf(" nuh_temporal_id_plus1 : %d \n", nal->nuh_temporal_id_plus1);

	// TODO make into subroutine
	const char* nal_unit_type_name;
	switch (nal->nal_unit_type)
	{
	case NALU_TYPE_VPS_NUT:
		nal_unit_type_name = "VPS";
		debug_vps(h);
		break;
	case NALU_TYPE_SPS_NUT:
		nal_unit_type_name = "SPS";
		debug_sps(h);
		break;
	case NALU_TYPE_PPS_NUT:
		nal_unit_type_name = "PPS";
		debug_pps(h);
		break;
	case NALU_TYPE_PREFIX_SEI_NUT:
	case NALU_TYPE_SUFFIX_SEI_NUT:
		nal_unit_type_name = "SEI";
		debug_seis(h);
		break;
	case NALU_TYPE_AUD_NUT:
		nal_unit_type_name = "AUD";
		debug_aud(h);
		break;
	case NALU_TYPE_CODED_SLICE_TRAIL_N:
	case NALU_TYPE_CODED_SLICE_TRAIL_R:
	case NALU_TYPE_CODED_SLICE_TSA_N:
	case NALU_TYPE_CODED_SLICE_TSA_R:
	case NALU_TYPE_CODED_SLICE_STSA_N:
	case NALU_TYPE_CODED_SLICE_STSA_R:
	case NALU_TYPE_CODED_SLICE_RADL_N:
	case NALU_TYPE_CODED_SLICE_RADL_R:
	case NALU_TYPE_CODED_SLICE_RASL_N:
	case NALU_TYPE_CODED_SLICE_RASL_R:
	case NALU_TYPE_CODED_SLICE_BLA_W_LP:
	case NALU_TYPE_CODED_SLICE_BLA_W_RADL:
	case NALU_TYPE_CODED_SLICE_BLA_N_LP:
	case NALU_TYPE_CODED_SLICE_IDR_W_RADL:
	case NALU_TYPE_CODED_SLICE_IDR_N_LP:
	case NALU_TYPE_CODED_SLICE_CRA_NUT:
		// hevc_decode_slice_segment_layer_rbsp(h, b);
		nal_unit_type_name = "SLICE";
		debug_slice_header(h);
		break;
	};

	//switch (nal->nal_unit_type)
	//{
	//case  NALU_TYPE_CODED_SLICE_IDR:               NALU_type_name = "Coded slice of an IDR picture"; break;
	//case  NALU_TYPE_SEI:                           NALU_type_name = "Supplemental enhancement information (SEI)"; break;
	//case  NALU_TYPE_SPS:                           NALU_type_name = "Sequence parameter set"; break;
	//case  NALU_TYPE_PPS:                           NALU_type_name = "Picture parameter set"; break;
	//case  NALU_TYPE_AUD:                           NALU_type_name = "Access unit delimiter"; break;
	//case  NALU_TYPE_END_OF_SEQUENCE:               NALU_type_name = "End of sequence"; break;
	//case  NALU_TYPE_END_OF_STREAM:                 NALU_type_name = "End of stream"; break;
	//case  NALU_TYPE_FILLER:                        NALU_type_name = "Filler data"; break;
	//case  NALU_TYPE_SPS_EXT:                       NALU_type_name = "Sequence parameter set extension"; break;
	//	// 14..18    // Reserved
	//case  NALU_TYPE_CODED_SLICE_AUX:               NALU_type_name = "Coded slice of an auxiliary coded picture without partitioning"; break;
	//	// 20..23    // Reserved
	//	// 24..31    // Unspecified
	//default:                                           nal_unit_type_name = "Unknown"; break;
	//}
	//printf(" nal_unit_type : %d ( %s ) \n", nal->nal_unit_type, nal_unit_type_name);

	//if (nal->nal_unit_type == NAL_UNIT_TYPE_CODED_SLICE_NON_IDR) { debug_slice_header(h); }
	//else if (nal->nal_unit_type == NAL_UNIT_TYPE_CODED_SLICE_IDR) { debug_slice_header(h); }
	//else if (nal->nal_unit_type == NAL_UNIT_TYPE_SPS) { debug_sps(h); }
	//else if (nal->nal_unit_type == NAL_UNIT_TYPE_PPS) { debug_pps(h); }
	//else if (nal->nal_unit_type == NAL_UNIT_TYPE_AUD) { debug_aud(h); }
	//else if (nal->nal_unit_type == NAL_UNIT_TYPE_SEI) { debug_seis(h); }
	//printf("\n\n");
}

void debug_aud(hevc_stream_t* h)
{
	hevc_aud_t* aud = h->aud;
	printf("======= Access Unit Delimiter =======\n");
	const char* primary_pic_type_name;
	switch (aud->pic_type)
	{
	case AUD_PRIMARY_PIC_TYPE_I:       primary_pic_type_name = "I"; break;
	case AUD_PRIMARY_PIC_TYPE_IP:      primary_pic_type_name = "I, P"; break;
	case AUD_PRIMARY_PIC_TYPE_IPB:     primary_pic_type_name = "I, P, B"; break;
	case AUD_PRIMARY_PIC_TYPE_SI:      primary_pic_type_name = "SI"; break;
	case AUD_PRIMARY_PIC_TYPE_SISP:    primary_pic_type_name = "SI, SP"; break;
	case AUD_PRIMARY_PIC_TYPE_ISI:     primary_pic_type_name = "I, SI"; break;
	case AUD_PRIMARY_PIC_TYPE_ISIPSP:  primary_pic_type_name = "I, SI, P, SP"; break;
	case AUD_PRIMARY_PIC_TYPE_ISIPSPB: primary_pic_type_name = "I, SI, P, SP, B"; break;
	default: primary_pic_type_name = "Unknown"; break;
	}
	printf(" pic_type : %d ( %s ) \n", aud->pic_type, primary_pic_type_name);
}

void debug_seis(hevc_stream_t* h)
{
	hevc_sei_t** seis = h->seis;
	int num_seis = h->num_seis;

	printf("======= SEI =======\n");
	const char* sei_type_name;
	int i;
	for (i = 0; i < num_seis; i++)
	{
		hevc_sei_t* s = seis[i];
		switch (s->payload_type)
		{
		case SEI_TYPE_BUFFERING_PERIOD:          sei_type_name = "Buffering period"; break;
		case SEI_TYPE_PIC_TIMING:                sei_type_name = "Pic timing"; break;
		case SEI_TYPE_PAN_SCAN_RECT:             sei_type_name = "Pan scan rect"; break;
		case SEI_TYPE_FILLER_PAYLOAD:            sei_type_name = "Filler payload"; break;
		case SEI_TYPE_USER_DATA_REGISTERED_ITU_T_T35: sei_type_name = "User data registered ITU-T T35"; break;
		case SEI_TYPE_USER_DATA_UNREGISTERED:    sei_type_name = "User data unregistered"; break;
		case SEI_TYPE_RECOVERY_POINT:            sei_type_name = "Recovery point"; break;
		case SEI_TYPE_DEC_REF_PIC_MARKING_REPETITION: sei_type_name = "Dec ref pic marking repetition"; break;
		case SEI_TYPE_SPARE_PIC:                 sei_type_name = "Spare pic"; break;
		case SEI_TYPE_SCENE_INFO:                sei_type_name = "Scene info"; break;
		case SEI_TYPE_SUB_SEQ_INFO:              sei_type_name = "Sub seq info"; break;
		case SEI_TYPE_SUB_SEQ_LAYER_CHARACTERISTICS: sei_type_name = "Sub seq layer characteristics"; break;
		case SEI_TYPE_SUB_SEQ_CHARACTERISTICS:   sei_type_name = "Sub seq characteristics"; break;
		case SEI_TYPE_FULL_FRAME_FREEZE:         sei_type_name = "Full frame freeze"; break;
		case SEI_TYPE_FULL_FRAME_FREEZE_RELEASE: sei_type_name = "Full frame freeze release"; break;
		case SEI_TYPE_FULL_FRAME_SNAPSHOT:       sei_type_name = "Full frame snapshot"; break;
		case SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_START: sei_type_name = "Progressive refinement segment start"; break;
		case SEI_TYPE_PROGRESSIVE_REFINEMENT_SEGMENT_END: sei_type_name = "Progressive refinement segment end"; break;
		case SEI_TYPE_MOTION_CONSTRAINED_SLICE_GROUP_SET: sei_type_name = "Motion constrained slice group set"; break;
		case SEI_TYPE_FILM_GRAIN_CHARACTERISTICS: sei_type_name = "Film grain characteristics"; break;
		case SEI_TYPE_DEBLOCKING_FILTER_DISPLAY_PREFERENCE: sei_type_name = "Deblocking filter display preference"; break;
		case SEI_TYPE_STEREO_VIDEO_INFO:         sei_type_name = "Stereo video info"; break;
		default: sei_type_name = "Unknown"; break;
		}
		printf("=== %s ===\n", sei_type_name);
		printf(" payloadType : %d \n", s->payload_type);
		printf(" payloadSize : %d \n", s->payload_size);

		printf(" payload : ");
		debug_bytes(s->payload, s->payload_size);
	}
}

void debug_profile_tier_level(profile_tier_level_t* ptl, int profile_present_flag, int max_num_sub_layers_minus1)
{
	int i, j;
	int general_profile_idc = ptl->general_profile_idc;
	printf(" ===== profile tier level ===== \n");
	if (profile_present_flag)
	{
		printf(" ptl->general_profile_space : %d \n", ptl->general_profile_space);
		printf(" ptl->general_tier_flag : %d \n", ptl->general_tier_flag);
		printf(" ptl->general_profile_idc : %d \n", ptl->general_profile_idc);
		for (i = 0; i < 32; i++)
		{
			printf(" ptl->general_profile_compatibility_flag[%d] : %d \n", i, ptl->general_profile_compatibility_flag[i]);
		}

		printf(" ptl->general_progressive_source_flag : %d \n", ptl->general_progressive_source_flag);
		printf(" ptl->general_interlaced_source_flag : %d \n", ptl->general_interlaced_source_flag);
		printf(" ptl->general_non_packet_constrained_flag : %d \n", ptl->general_non_packet_constrained_flag);
		printf(" ptl->general_frame_only_constraint_flag : %d \n", ptl->general_frame_only_constraint_flag);

		if (general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] ||
			general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] ||
			general_profile_idc == 6 || ptl->general_profile_compatibility_flag[6] ||
			general_profile_idc == 7 || ptl->general_profile_compatibility_flag[7] ||
			general_profile_idc == 8 || ptl->general_profile_compatibility_flag[8] ||
			general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] ||
			general_profile_idc == 10 || ptl->general_profile_compatibility_flag[10] ||
			general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11])
		{
			printf(" ptl->general_max_12bit_constraint_flag : %d \n", ptl->general_max_12bit_constraint_flag);
			printf(" ptl->general_max_10bit_constraint_flag : %d \n", ptl->general_max_10bit_constraint_flag);
			printf(" ptl->general_max_8bit_constraint_flag : %d \n", ptl->general_max_8bit_constraint_flag);
			printf(" ptl->general_max_422chroma_constraint_flag : %d \n", ptl->general_max_422chroma_constraint_flag);
			printf(" ptl->general_max_420chroma_constraint_flag : %d \n", ptl->general_max_420chroma_constraint_flag);
			printf(" ptl->general_max_monochrome_constraint_flag : %d \n", ptl->general_max_monochrome_constraint_flag);
			printf(" ptl->general_intra_constraint_flag : %d \n", ptl->general_intra_constraint_flag);
			printf(" ptl->general_one_picture_only_constraint_flag : %d \n", ptl->general_one_picture_only_constraint_flag);
			printf(" ptl->general_lower_bit_rate_contraint_flag : %d \n", ptl->general_lower_bit_rate_contraint_flag);
		}

		if (general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] ||
			general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] ||
			general_profile_idc == 10 || ptl->general_profile_compatibility_flag[10] ||
			general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11])
		{
			printf(" ptl->general_max_14bit_constraint_flag : %d \n", ptl->general_max_14bit_constraint_flag);
			// printf(" ptl->general_reserved_zero_33bits : %d \n", ptl->general_reserved_zero_33bits);
		}
		else
		{
			// printf(" ptl->general_reserved_zero_34bits : %d \n", ptl->general_reserved_zero_34bits);
		}
	}
	else if (general_profile_idc == 2 || ptl->general_profile_compatibility_flag[2])
	{
		// printf(" ptl->general_reserved_zero_7bits : %d \n", ptl->general_reserved_zero_7bits);
		printf(" ptl->general_one_picture_only_constraint_flag : %d \n", ptl->general_one_picture_only_constraint_flag);
		// printf(" ptl->general_reserved_zero_35bits : %d \n", ptl->general_reserved_zero_35bits);
	}
	else
	{
		// printf(" ptl->general_reserved_zero_43bits : %d \n", ptl->general_reserved_zero_43bits);
	}
	
	if (general_profile_idc == 1 || ptl->general_profile_compatibility_flag[1] ||
		general_profile_idc == 2 || ptl->general_profile_compatibility_flag[2] ||
		general_profile_idc == 3 || ptl->general_profile_compatibility_flag[3] ||
		general_profile_idc == 4 || ptl->general_profile_compatibility_flag[4] ||
		general_profile_idc == 5 || ptl->general_profile_compatibility_flag[5] ||
		general_profile_idc == 9 || ptl->general_profile_compatibility_flag[9] ||
		general_profile_idc == 11 || ptl->general_profile_compatibility_flag[11])
	{
		printf(" ptl->general_inbld_flag : %d \n", ptl->general_inbld_flag);
	}
	else
	{
		// printf(" ptl->general_reserved_zero_bit : %d \n", ptl->general_reserved_zero_bit);
	}

	printf(" ptl->general_level_idc : %d \n", ptl->general_level_idc);
	for (i = 0; i < max_num_sub_layers_minus1; i++)
	{
		printf(" ptl->sub_layer_profile_present_flag[%d] : %d \n", ptl->sub_layer_profile_present_flag[i]);
		printf(" ptl->sub_layer_level_present_flag[%d] : %d \n", ptl->sub_layer_level_present_flag[i]);
	}

	if (max_num_sub_layers_minus1 > 0)
	{
		for (i = max_num_sub_layers_minus1; i < 8; i++)
		{
			// printf(" ptl->reserved_zero_2bits : %d \n", ptl->reserved_zero_2bits);
		}
	}

	for (i = 0; i < max_num_sub_layers_minus1; i++)
	{
		if (ptl->sub_layer_profile_present_flag[i])
		{
			printf(" ptl->sub_layer_profile_space[%d] : %d \n", i, ptl->sub_layer_profile_space[i]);
			printf(" ptl->sub_layer_tier_flag[%d] : %d \n", i, ptl->sub_layer_tier_flag[i]);
			printf(" ptl->sub_layer_profile_idc[%d] : %d \n", i, ptl->sub_layer_profile_idc[i]);
			for (j = 0; j < 32; j++)
			{
				printf(" ptl->sub_layer_profile_compability_flag[%d][%d] : %d \n", i, j, ptl->sub_layer_profile_compability_flag[i][j]);
			}
			printf(" ptl->sub_layer_progressive_source_flag[%d] : %d \n", i, ptl->sub_layer_progressive_source_flag[i]);
			printf(" ptl->sub_layer_interlaced_source_flag[%d] : %d \n", i, ptl->sub_layer_interlaced_source_flag[i]);
			printf(" ptl->sub_layer_non_packed_constraint_flag[%d] : %d \n", i, ptl->sub_layer_non_packed_constraint_flag[i]);
			printf(" ptl->sub_layer_frame_only_constraint_flag[%d] : %d \n", i, ptl->sub_layer_frame_only_constraint_flag[i]);

			if (ptl->sub_layer_profile_idc[i] == 4 || ptl->sub_layer_profile_compability_flag[i][4] ||
				ptl->sub_layer_profile_idc[i] == 5 || ptl->sub_layer_profile_compability_flag[i][5] ||
				ptl->sub_layer_profile_idc[i] == 6 || ptl->sub_layer_profile_compability_flag[i][6] ||
				ptl->sub_layer_profile_idc[i] == 7 || ptl->sub_layer_profile_compability_flag[i][7] ||
				ptl->sub_layer_profile_idc[i] == 8 || ptl->sub_layer_profile_compability_flag[i][8] ||
				ptl->sub_layer_profile_idc[i] == 9 || ptl->sub_layer_profile_compability_flag[i][9] ||
				ptl->sub_layer_profile_idc[i] == 10 || ptl->sub_layer_profile_compability_flag[i][10] || 
				ptl->sub_layer_profile_idc[i] == 11 || ptl->sub_layer_profile_compability_flag[i][11])
			{
				printf(" ptl->sub_layer_max_12bit_constraint_flag[%d] : %d \n", i, ptl->sub_layer_max_12bit_constraint_flag[i]);
				printf(" ptl->sub_layer_max_10bit_constraint_flag[%d] : %d \n", i, ptl->sub_layer_max_10bit_constraint_flag[i]);
				printf(" ptl->sub_layer_max_8bit_constraint_flag[%d] : %d \n", i, ptl->sub_layer_max_8bit_constraint_flag[i]);
				printf(" ptl->sub_layer_max_422chroma_constraint_flag[%d] : %d \n", i, ptl->sub_layer_max_422chroma_constraint_flag[i]);
				printf(" ptl->sub_layer_max_420chroma_constraint_flag[%d] : %d \n", i, ptl->sub_layer_max_420chroma_constraint_flag[i]);
				printf(" ptl->sub_layer_max_monochrome_constraint_flag[%d] : %d \n", i, ptl->sub_layer_max_monochrome_constraint_flag[i]);
				printf(" ptl->sub_layer_intra_constraint_flag[%d] : %d \n", i, ptl->sub_layer_intra_constraint_flag[i]);
				printf(" ptl->sub_layer_one_picture_only_constraint_flag[%d] : %d \n", i, ptl->sub_layer_one_picture_only_constraint_flag[i]);
				printf(" ptl->sub_layer_lower_bit_rate_constraint_flag[%d] : %d \n", i, ptl->sub_layer_lower_bit_rate_constraint_flag[i]);
				if (ptl->sub_layer_profile_idc[i] == 5 || ptl->sub_layer_profile_compability_flag[i][5] ||
					ptl->sub_layer_profile_idc[i] == 9 || ptl->sub_layer_profile_compability_flag[i][9] ||
					ptl->sub_layer_profile_idc[i] == 10 || ptl->sub_layer_profile_compability_flag[i][10] ||
					ptl->sub_layer_profile_idc[i] == 11 || ptl->sub_layer_profile_compability_flag[i][11])
				{
					printf(" ptl->sub_layer_max_14bit_constraint_flag[%d] : %d \n", i, ptl->sub_layer_max_14bit_constraint_flag[i]);
					printf(" ptl->sub_layer_reserved_zero_33bits[%d] : %d \n", i, ptl->sub_layer_reserved_zero_33bits[i]);
				}
				else
				{
					printf(" ptl->sub_layer_reserved_zero_34bits[%d] : %d \n", i, ptl->sub_layer_reserved_zero_34bits[i]);
				}
			}
			else if (ptl->sub_layer_profile_idc[i] == 2 || ptl->sub_layer_profile_compability_flag[i][2])
			{
				printf(" ptl->sub_layer_reserved_zero_7bits[%d] : %d \n", i, ptl->sub_layer_reserved_zero_7bits[i]);
				printf(" ptl->sub_layer_one_picture_only_constraint_flag[%d] : %d \n", i, ptl->sub_layer_one_picture_only_constraint_flag[i]);
				printf(" ptl->sub_layer_reserved_zero_35bits[%d] : %d \n", i, ptl->sub_layer_reserved_zero_35bits[i]);
			}
			else
			{
				printf(" ptl->sub_layer_reserved_zero_43bits[%d] : %d \n", i, ptl->sub_layer_reserved_zero_43bits[i]);
			}

			if (ptl->sub_layer_profile_idc[i] == 1 || ptl->sub_layer_profile_compability_flag[i][1] ||
				ptl->sub_layer_profile_idc[i] == 2 || ptl->sub_layer_profile_compability_flag[i][2] ||
				ptl->sub_layer_profile_idc[i] == 3 || ptl->sub_layer_profile_compability_flag[i][3] ||
				ptl->sub_layer_profile_idc[i] == 4 || ptl->sub_layer_profile_compability_flag[i][4] ||
				ptl->sub_layer_profile_idc[i] == 5 || ptl->sub_layer_profile_compability_flag[i][5] ||
				ptl->sub_layer_profile_idc[i] == 9 || ptl->sub_layer_profile_compability_flag[i][9] ||
				ptl->sub_layer_profile_idc[i] == 11 || ptl->sub_layer_profile_compability_flag[i][11])
			{
				printf(" ptl->sub_layer_inbld_flag[%d] : %d \n", i, ptl->sub_layer_inbld_flag[i]);
			}
			else
			{
				printf(" ptl->sub_layer_reserved_zero_bit[%d] : %d \n", i, ptl->sub_layer_reserved_zero_bit[i]);
			}
		}
		if (ptl->sub_layer_level_present_flag[i])
		{
			printf(" ptl->sub_layer_level_present_flag[%d] : %d \n", i, ptl->sub_layer_level_present_flag[i]);
		}
	}
}

void debug_vps(hevc_stream_t* h)
{
	int i, j;
	hevc_vps_t* vps = h->vps;
	printf("======= VPS =======\n");
	printf(" vps_video_parameter_set_id : %d \n", vps->vps_video_parameter_set_id);
	printf(" vps_base_layer_internal_flag : %d \n", vps->vps_base_layer_internal_flag);
	printf(" vps_base_layer_available_flag : %d \n", vps->vps_base_layer_available_flag);
	printf(" vps_max_layers_minus1 : %d \n", vps->vps_max_layers_minus1);
	printf(" vps_max_sub_layers_minus1 : %d \n", vps->vps_max_sub_layers_minus1);
	printf(" vps_temporal_id_nesting_flag : %d \n", vps->vps_temporal_id_nesting_flag);
	printf(" vps_reserved_0xffff_16bits : %d \n", vps->vps_reserved_0xffff_16bits);
	
	// profiler tier level
	debug_profile_tier_level(&h->vps->ptl, 1, vps->vps_max_sub_layers_minus1); // hevc_decode_profile_tier_level(&(vps->ptl), b, 1, vps->vps_max_sub_layers_minus1);
	printf(" vps_sub_layer_ordering_info_present_flag : %d \n", vps->vps_sub_layer_ordering_info_present_flag);
	for (i = (vps->vps_sub_layer_ordering_info_present_flag ? 0 : vps->vps_max_sub_layers_minus1);
		i <= vps->vps_max_sub_layers_minus1; i++)
	{
		printf(" vps_max_dec_pic_buffering_minus1[%d] : %d \n", i, vps->vps_max_dec_pic_buffering_minus1[i]);
		printf(" vps_max_num_reorder_pics[%d] : %d \n", i, vps->vps_max_num_reorder_pics[i]);
		printf(" vps_max_latency_increase_plus1[%d] : %d \n", i, vps->vps_max_latency_increase_plus1[i]);
	}

	printf(" vps_max_layer_id : %d \n", vps->vps_max_layer_id);
	printf(" vps_num_layer_sets_minus1 : %d \n", vps->vps_num_layer_sets_minus1);

	for (i = 0; i <= vps->vps_num_layer_sets_minus1; i++)
	{
		for (j = 0; j <= vps->vps_max_layer_id; j++)
		{
			printf(" layer_id_included_flag[%d][%d] : %d \n", i, j, vps->layer_id_included_flag[i][j]);
		}
	}
	printf(" vps_timing_info_present_flag : %d \n", vps->vps_timing_info_present_flag);
	if (vps->vps_timing_info_present_flag)
	{
		printf(" vps_num_units_in_tick : %d \n", vps->vps_num_units_in_tick);
		printf(" vps_time_scale : %d \n", vps->vps_time_scale);
		printf(" vps_poc_proportional_to_timing_flag : %d \n", vps->vps_poc_proportional_to_timing_flag);
		if (vps->vps_poc_proportional_to_timing_flag)
		{
			printf(" vps_num_ticks_poc_diff_one_minus1 : %d \n", vps->vps_num_ticks_poc_diff_one_minus1);
		}
		printf(" vps_num_hrd_parameters : %d \n", vps->vps_num_hrd_parameters);
		for (i = 0; i < vps->vps_num_hrd_parameters; i++)
		{
			printf(" hrd_layer_set_idx[%d] : %d \n", i, vps->hrd_layer_set_idx[i]);
			if (i > 0)
			{
				printf(" cprms_present_flag[%d] : %d \n", i, vps->cprms_present_flag[i]);
			}
			debug_hrd_parameters(&vps->vps_hrd_parameters, vps->cprms_present_flag[i], vps->vps_max_sub_layers_minus1);
			// hevc_decode_hrd_parameters(&(vps->vps_hrd_parameters), b, vps->cprms_present_flag[i], vps->vps_max_sub_layers_minus1);
		}
	}
	printf(" vps_extension_flag : %d \n", vps->vps_extension_flag);
	printf(" vps_extension_data_flag : %d \n", vps->vps_extension_data_flag);
}

void debug_sub_layer_hrd_parameters(sub_layer_hrd_parameters_t* sub_layer_hrd, int sub_pic_hrd_parameters_present_flag, int cpb_cnt)
{
	int i;
	for (i = 0; i < cpb_cnt; i++)
	{
		printf(" bit_rate_value_minus1[%d] : %d \n", i, sub_layer_hrd->bit_rate_value_minus1[i]);
		printf(" cpb_size_value_minus1[%d] : %d \n", i, sub_layer_hrd->cpb_size_value_minus1[i]);
		if (sub_pic_hrd_parameters_present_flag)
		{
			printf(" bit_rate_du_value_minus1[%d] : %d \n", i, sub_layer_hrd->bit_rate_du_value_minus1[i]);
			printf(" cpb_size_du_value_minus1[%d] : %d \n", i, sub_layer_hrd->cpb_size_du_value_minus1[i]);
		}
		printf(" cbr_flag[%d] : %d \n", i, sub_layer_hrd->cbr_flag[i]);
	}
}

void debug_hrd_parameters(hrd_parameters_t* hrd, int common_inf_present_flag, int vps_max_sub_layers_minus1)
{
	printf(" ===== HRD parameters ===== \n");
	if (common_inf_present_flag)
	{
		printf(" nal_hrd_parameters_present_flag : %d \n", hrd->nal_hrd_parameters_present_flag);
		printf(" vcl_hrd_parameters_present_flag : %d \n", hrd->vcl_hrd_parameters_present_flag);
		if (hrd->nal_hrd_parameters_present_flag || hrd->vcl_hrd_parameters_present_flag)
		{
			printf(" sub_pic_hrd_parameters_present_flag : %d \n", hrd->sub_pic_hrd_parameters_present_flag);
			if (hrd->sub_pic_hrd_parameters_present_flag)
			{
				printf(" tick_divisor_minus2 : %d \n", hrd->tick_divisor_minus2);
				printf(" du_cpb_removal_delay_increment_length_minus1 : %d \n", hrd->du_cpb_removal_delay_increment_length_minus1);
				printf(" sub_pic_cpb_params_in_pic_timing_sei_flag : %d \n", hrd->sub_pic_cpb_params_in_pic_timing_sei_flag);
				printf(" dpb_output_delay_du_length_minus1 : %d \n", hrd->dpb_output_delay_du_length_minus1);
			}

			printf(" bit_rate_scale : %d \n", hrd->bit_rate_scale);
			printf(" cpb_size_scale : %d \n", hrd->cpb_size_scale);
			if (hrd->sub_pic_hrd_parameters_present_flag)
			{
				printf(" cpb_size_du_scale : %d \n", hrd->cpb_size_du_scale);
			}
			printf(" initial_cpb_removal_delay_length_minus1 : %d \n", hrd->initial_cpb_removal_delay_length_minus1);
			printf(" au_cpb_removal_delay_length_minus1 : %d \n", hrd->au_cpb_removal_delay_length_minus1);
			printf(" dpb_output_delay_length_minus1 : %d \n", hrd->dpb_output_delay_length_minus1);
		}
	}
	for (int i = 0; i <= vps_max_sub_layers_minus1; i++)
	{
		printf(" fixed_pic_rate_general_flag[%d] : %d \n", i, hrd->fixed_pic_rate_general_flag[i]);
		if (!hrd->fixed_pic_rate_general_flag[i])
		{
			printf(" fixed_pic_rate_within_cvs_flag[%d] : %d \n", i, hrd->fixed_pic_rate_within_cvs_flag[i]);
		}

		if (hrd->fixed_pic_rate_within_cvs_flag[i])
		{
			printf(" elemental_duration_in_tc_minus1[%d] : %d \n", i, hrd->elemental_duration_in_tc_minus1[i]);
		}
		else
		{
			printf(" low_delay_hrd_flag[%d] : %d \n", i, hrd->low_delay_hrd_flag[i]);
		}

		if (!hrd->low_delay_hrd_flag[i])
		{
			printf(" cpb_cnt_minus1[%d] : %d \n", i, hrd->cpb_cnt_minus1[i]);
		}

		int b_sub_layer_hrd_parameters = hrd->nal_hrd_parameters_present_flag || hrd->vcl_hrd_parameters_present_flag;
		if (b_sub_layer_hrd_parameters)
		{
			/*if (hrd->nal_hrd_parameters_present_flag)
			{
				hevc_decode_sub_layer_hrd_parameters(hrd->sub_layer_hrd, b, hrd->sub_pic_hrd_parameters_present_flag, hrd->cpb_cnt_minus1[i]);
			}
			if (hrd->vcl_hrd_parameters_present_flag)
			{
				hevc_decode_sub_layer_hrd_parameters(hrd->sub_layer_hrd, b, hrd->sub_pic_hrd_parameters_present_flag, hrd->cpb_cnt_minus1[i]);
			}*/
			debug_sub_layer_hrd_parameters(&hrd->sub_layer_hrd, hrd->sub_pic_hrd_parameters_present_flag, hrd->cpb_cnt_minus1[i]);
		}
	}
}

void debug_scaling_list_data(hevc_scaling_list_data_t* sl_data)
{
	int sizeId;
	int matrixId;
	int i;
	for (sizeId = 0; sizeId < 4; sizeId++)
	{
		for (matrixId = 0; matrixId < 6; matrixId += (sizeId == 3) ? 3 : 1)
		{
			printf(" scaling_list_pred_mode_flag[%d][%d] : %d \n", sizeId, matrixId, sl_data->scaling_list_pred_mode_flag[sizeId][matrixId]);
			if (!sl_data->scaling_list_pred_mode_flag[sizeId][matrixId])
			{
				printf(" scaling_list_pred_matrix_id_delta[%d][%d] : %d \n", sizeId, matrixId, sl_data->scaling_list_pred_matrix_id_delta[sizeId][matrixId]);
			}
			else
			{
				int next_coef = 8;
				int coef_num = ff_min(64, (1 << (4 + (sizeId << 1))));
				if (sizeId > 1)
				{
					printf(" scaling_list_dc_coef_minus8[%d][%d] : %d \n", sizeId, matrixId, sl_data->scaling_list_dc_coef_minus8[sizeId - 2][matrixId]);
				}
				for (i = 0; i < coef_num; i++)
				{
					// printf(" scaling_list_dc_coef_minus8[%d][%d] : %d \n", sizeId, matrixId, sl_data->scaling_list_delta_coef);
				}
			}
		}
	}
}

// hevc_decode_st_ref_pic_set(sps, &sps->st_rps[i], b, sps->num_short_term_ref_pic_sets, i);
// void hevc_decode_st_ref_pic_set(hevc_sps_t* sps, st_ref_pic_set_t* st_rps, bs_t* b, int num_short_term_ref_pic_sets, int st_rps_idx)
void debug_srpc(hevc_sps_t* sps, st_ref_pic_set_t* st_rps, int num_short_term_ref_pic_sets, int st_rps_idx)
{
	int i;
	if (st_rps_idx != 0)
	{
		printf(" inter_ref_pic_set_prediction_flag : %d \n", st_rps->inter_ref_pic_set_prediction_flag);
		if (st_rps->inter_ref_pic_set_prediction_flag)
		{
			const st_ref_pic_set_t* tmp_rps;
			if (st_rps_idx == num_short_term_ref_pic_sets)
			{
				printf(" delta_idx_minus1 : %d \n", st_rps->delta_idx_minus1);
			}
			printf(" delta_rps_sign : %d \n", st_rps->delta_rps_sign);
			printf(" abs_delta_rps_minus1 : %d \n", st_rps->abs_delta_rps_minus1);
			tmp_rps = &sps->st_rps[st_rps - sps->st_rps - 1];
			for (i = 0; i <= tmp_rps->num_delta_pocs; i++)
			{
				printf(" used_by_curr_pic_flag[%d] : %d \n", i, st_rps->used_by_curr_pic_flag[i]);
				if (!st_rps->used_by_curr_pic_flag[i])
				{
					printf(" use_delta_flag[%d] : %d \n", i, st_rps->use_delta_flag[i]);
				}
			}
		}
		else
		{
			printf(" num_negative_pics : %d \n", st_rps->num_negative_pics);
			printf(" num_positive_pics : %d \n", st_rps->num_positive_pics);
			for (i = 0; i <= st_rps->num_negative_pics; i++)
			{
				printf(" delta_poc_s0_minus1[%d] : %d \n", i, st_rps->delta_poc_s0_minus1[i]);
				printf(" used_by_curr_pic_s0_flag[%d] : %d \n", i, st_rps->used_by_curr_pic_s0_flag[i]);
			}

			for (i = 0; i <= st_rps->num_positive_pics; i++)
			{
				printf(" delta_poc_s1_minus1[%d] : %d \n", i, st_rps->delta_poc_s1_minus1[i]);
				printf(" used_by_curr_pic_s1_flag[%d] : %d \n", i, st_rps->used_by_curr_pic_s1_flag[i]);
			}
		}
	}
}

void debug_vui(hevc_sps_t* sps)
{
	vui_parameters_t* vui = &sps->vui;
	printf(" ===== VUI ===== \n");
	printf(" aspect_ratio_info_present_flag : %d \n", vui->aspect_ratio_info_present_flag);
	if (vui->aspect_ratio_info_present_flag)
	{
		printf(" aspect_ratio_idc : %d \n", vui->aspect_ratio_idc);
		if (vui->aspect_ratio_idc == EXTENDED_SAR)
		{
			printf(" sar_width : %d \n", vui->sar_width);
			printf(" sar_height : %d \n", vui->sar_height);
		}
	}

	printf(" overscan_info_present_flag : %d \n", vui->overscan_info_present_flag);
	if (vui->overscan_info_present_flag)
	{
		printf(" overscan_appropriate_flag : %d \n", vui->overscan_appropriate_flag);
	}
	printf(" video_signal_type_present_flag : %d \n", vui->video_signal_type_present_flag);
	if (vui->video_signal_type_present_flag)
	{
		printf(" video_format : %d \n", vui->video_format);
		printf(" video_full_range_flag : %d \n", vui->video_full_range_flag);
		printf(" colour_description_present_flag : %d \n", vui->colour_description_present_flag);

		if (vui->colour_description_present_flag)
		{
			printf(" colour_primaries : %d \n", vui->colour_primaries);
			printf(" transfer_characteristics : %d \n", vui->transfer_characteristics);
			printf(" matrix_coeffs : %d \n", vui->matrix_coeffs);
		}
	}
	printf(" chroma_loc_info_present_flag : %d \n", vui->chroma_loc_info_present_flag);
	if (vui->chroma_loc_info_present_flag)
	{
		printf(" chroma_sample_loc_type_top_field : %d \n", vui->chroma_sample_loc_type_top_field);
		printf(" chroma_sample_loc_type_bottom_field : %d \n", vui->chroma_sample_loc_type_bottom_field);
	}

	printf(" neutral_chroma_indication_flag : %d \n", vui->neutral_chroma_indication_flag);
	printf(" field_seq_flag : %d \n", vui->field_seq_flag);
	printf(" frame_field_info_present_flag : %d \n", vui->frame_field_info_present_flag);
	printf(" default_display_window_flag : %d \n", vui->default_display_window_flag);

	if (vui->default_display_window_flag)
	{
		printf(" def_disp_win_left_offset : %d \n", vui->def_disp_win_left_offset);
		printf(" def_disp_win_right_offset : %d \n", vui->def_disp_win_right_offset);
		printf(" def_disp_win_top_offset : %d \n", vui->def_disp_win_top_offset);
		printf(" def_disp_win_bottom_offset : %d \n", vui->def_disp_win_bottom_offset);
	}

	printf(" vui_timing_info_present_flag : %d \n", vui->vui_timing_info_present_flag);
	if (vui->vui_timing_info_present_flag)
	{
		printf(" vui_num_units_in_tick : %d \n", vui->vui_num_units_in_tick);
		printf(" vui_time_scale : %d \n", vui->vui_time_scale);
		printf(" vui_proc_proportioanl_to_timing_flag : %d \n", vui->vui_proc_proportioanl_to_timing_flag);
		if (vui->vui_proc_proportioanl_to_timing_flag)
		{
			printf(" vui_num_ticks_poc_diff_one_minus1 : %d \n", vui->vui_num_ticks_poc_diff_one_minus1);
		}
		printf(" vui_hrd_parameters_present_flag : %d \n", vui->vui_hrd_parameters_present_flag);
		if (vui->vui_hrd_parameters_present_flag)
		{
			debug_hrd_parameters(&vui->hrd, 1, sps->sps_max_sub_layers_minus1);
			// hevc_decode_hrd_parameters(&(vui->hrd), b, 1, sps->sps_max_sub_layers_minus1);
		}
	}

	printf(" bitstream_restriction_flag : %d \n", vui->bitstream_restriction_flag);
	if (vui->bitstream_restriction_flag)
	{
		printf(" tiles_fixed_structure_flag : %d \n", vui->tiles_fixed_structure_flag);
		printf(" motion_vectors_over_pic_boundaries_flag : %d \n", vui->motion_vectors_over_pic_boundaries_flag);
		printf(" restricted_ref_pic_lists_flag : %d \n", vui->restricted_ref_pic_lists_flag);
		printf(" min_spatial_segmentation_idc : %d \n", vui->min_spatial_segmentation_idc);
		printf(" max_bytes_per_pic_denom : %d \n", vui->max_bytes_per_pic_denom);
		printf(" max_bits_per_min_cu_denom : %d \n", vui->max_bits_per_min_cu_denom);
		printf(" log2_max_mv_length_horizontal : %d \n", vui->log2_max_mv_length_horizontal);
		printf(" log2_max_mv_length_vertical : %d \n", vui->log2_max_mv_length_vertical);
	}
}

void debug_sps(hevc_stream_t* h)
{
	int i, j;
	//int sps_video_parameter_set_id = bs_read_u(b, 4);
	//h->sps = h->sps_table[sps_video_parameter_set_id];
	//hevc_sps_t* sps = h->sps;
	//memset(sps, 0, sizeof(hevc_sps_t));
	hevc_sps_t* sps = h->sps;
	printf(" ===== SPS ===== \n");
	printf(" sps_video_parameter_set_id : %d \n", sps->sps_video_parameter_set_id);
	printf(" sps_max_sub_layers_minus1 : %d \n", sps->sps_max_sub_layers_minus1);
	printf(" sps_temporal_id_nesting_flag : %d \n", sps->sps_temporal_id_nesting_flag);
	debug_profile_tier_level(&(sps->sps_profile_tier_level), 1, sps->sps_max_sub_layers_minus1);

	printf(" sps_seq_parameter_set_id : %d \n", sps->sps_seq_parameter_set_id);
	printf(" chroma_format_idc : %d \n", sps->chroma_format_idc);

	if (sps->chroma_format_idc == 3)
	{
		printf(" separate_colour_plane_flag : %d \n", sps->separate_colour_plane_flag);
	}

	printf(" pic_width_in_luma_samples : %d \n", sps->pic_width_in_luma_samples);
	printf(" pic_height_in_luma_samples : %d \n", sps->pic_height_in_luma_samples);
	printf(" conformance_window_flag : %d \n", sps->conformance_window_flag);
	if (sps->conformance_window_flag)
	{
		printf(" conf_win_left_offset : %d \n", sps->conf_win_left_offset);
		printf(" conf_win_right_offset : %d \n", sps->conf_win_right_offset);
		printf(" conf_win_top_offset : %d \n", sps->conf_win_top_offset);
		printf(" conf_win_bottom_offset : %d \n", sps->conf_win_bottom_offset);
	}
	printf(" bit_depth_luma_minus8 : %d \n", sps->bit_depth_luma_minus8);
	printf(" bit_depth_chroma_minus8 : %d \n", sps->bit_depth_chroma_minus8);
	printf(" log2_max_pic_order_cnt_lsb_minus4 : %d \n", sps->log2_max_pic_order_cnt_lsb_minus4);
	printf(" sps_sub_layer_ordering_info_present_flag : %d \n", sps->sps_sub_layer_ordering_info_present_flag);
	for (i = (sps->sps_sub_layer_ordering_info_present_flag ? 0 : sps->sps_max_sub_layers_minus1);
		i <= sps->sps_max_sub_layers_minus1; i++)
	{
		printf(" sps_max_dec_pic_buffering_minus1[%d] : %d \n", i, sps->sps_max_dec_pic_buffering_minus1[i]);
		printf(" sps_max_num_reorder_pics[%d] : %d \n", i, sps->sps_max_num_reorder_pics[i]);
		printf(" sps_max_latency_increase_plus1[%d] : %d \n", i, sps->sps_max_latency_increase_plus1[i]);
	}
	printf(" log2_min_luma_coding_block_size_minus3 : %d \n", sps->log2_min_luma_coding_block_size_minus3);
	printf(" log2_diff_max_min_luma_coding_block_size : %d \n", sps->log2_diff_max_min_luma_coding_block_size);
	printf(" log2_min_luma_transform_block_size_minus2 : %d \n", sps->log2_min_luma_transform_block_size_minus2);
	printf(" log2_diff_max_min_luma_transform_block_size : %d \n", sps->log2_diff_max_min_luma_transform_block_size);
	printf(" max_transform_hierarchy_depth_inter : %d \n", sps->max_transform_hierarchy_depth_inter);
	printf(" max_transform_hierarchy_depth_intra : %d \n", sps->max_transform_hierarchy_depth_intra);
	printf(" scaling_list_enabled_flag : %d \n", sps->scaling_list_enabled_flag);

	if (sps->scaling_list_enabled_flag)
	{
		printf(" sps_scaling_list_data_present_flag : %d \n", sps->sps_scaling_list_data_present_flag);
		if (sps->sps_scaling_list_data_present_flag)
		{
			debug_scaling_list_data(&sps->hevc_sl_data); // hevc_decode_scaling_list_data(&(sps->hevc_sl_data), b);
		}
	}

	printf(" amp_enabled_flag : %d \n", sps->amp_enabled_flag);
	printf(" sample_adaptive_offset_enabled_flag : %d \n", sps->sample_adaptive_offset_enabled_flag);
	printf(" pcm_enabled_flag : %d \n", sps->pcm_enabled_flag);
	if (sps->pcm_enabled_flag)
	{
		printf(" pcm_sample_bit_depth_luma_minus1 : %d \n", sps->pcm_sample_bit_depth_luma_minus1);
		printf(" pcm_sample_bit_depth_chroma_minus1 : %d \n", sps->pcm_sample_bit_depth_chroma_minus1);
		printf(" log2_min_pcm_luma_coding_block_size_minus3 : %d \n", sps->log2_min_pcm_luma_coding_block_size_minus3);
		printf(" log2_diff_max_min_pcm_luma_coding_block_size : %d \n", sps->log2_diff_max_min_pcm_luma_coding_block_size);
		printf(" pcm_loop_filter_disabled_flag : %d \n", sps->pcm_loop_filter_disabled_flag);
	}
	printf(" num_short_term_ref_pic_sets : %d \n", sps->num_short_term_ref_pic_sets);
	for (i = 0; i < sps->num_short_term_ref_pic_sets; i++)
	{
		// hevc_decode_st_ref_pic_set(sps, &sps->st_rps[i], b, sps->num_short_term_ref_pic_sets, i);
		debug_srpc(sps, &sps->st_rps[i], sps->num_short_term_ref_pic_sets, i);
	}
	printf(" long_term_ref_pics_present_flag : %d \n", sps->long_term_ref_pics_present_flag);
	if (sps->long_term_ref_pics_present_flag)
	{
		printf(" num_long_term_ref_pics_sps : %d \n", sps->num_long_term_ref_pics_sps);
		for (i = 0; i < sps->num_long_term_ref_pics_sps; i++)
		{
			printf(" lt_ref_pic_poc_lsb_sps[%d] : %d \n", i, sps->lt_ref_pic_poc_lsb_sps[i]);
			printf(" used_by_curr_pic_lt_sps_flag[%d] : %d \n", i, sps->used_by_curr_pic_lt_sps_flag[i]);
		}
	}

	printf(" sps_temporal_mvp_enabled_flag : %d \n", sps->sps_temporal_mvp_enabled_flag);
	printf(" strong_intra_smoothing_enabled_flag : %d \n", sps->strong_intra_smoothing_enabled_flag);
	printf(" vui_parameters_present_flag : %d \n", sps->vui_parameters_present_flag);
	if (sps->vui_parameters_present_flag)
	{
		// hevc_decode_vui_parameters(sps, b);
		debug_vui(sps);
	}
	printf(" sps_extension_present_flag : %d \n", sps->sps_extension_present_flag);
	if (sps->sps_extension_present_flag)
	{
		printf(" ===== sps extension present ===== \n");
		printf(" sps_range_extension_flag : %d \n", sps->sps_range_extension_flag);
		printf(" sps_multiplayer_extension_flag : %d \n", sps->sps_multiplayer_extension_flag);
		printf(" sps_3d_extension_flag : %d \n", sps->sps_3d_extension_flag);
		printf(" sps_scc_extension_flag : %d \n", sps->sps_scc_extension_flag);
		printf(" sps_extension_4bits : %d \n", sps->sps_extension_4bits);
	}

	if (sps->sps_range_extension_flag)
	{
		// hevc_decode_sps_range_extension(sps, b);
		printf(" ===== sps range extension ===== \n");
		sps_range_extension_t* sre = &sps->sps_range_extension;
		printf(" transform_skip_rotation_enabled_flag : %d \n", sre->transform_skip_rotation_enabled_flag);
		printf(" transform_skip_context_enabled_flag : %d \n", sre->transform_skip_context_enabled_flag);
		printf(" implicit_rdpcm_enabled_flag : %d \n", sre->implicit_rdpcm_enabled_flag);
		printf(" explicit_rdpcm_enabled_flag : %d \n", sre->explicit_rdpcm_enabled_flag);
		printf(" extended_precision_processing_flag : %d \n", sre->extended_precision_processing_flag);
		printf(" intra_smoothing_disabled_flag : %d \n", sre->intra_smoothing_disabled_flag);
		printf(" high_precision_offsets_enabled_flag : %d \n", sre->high_precision_offsets_enabled_flag);
		printf(" persistent_rice_adaptation_enabled_flag : %d \n", sre->persistent_rice_adaptation_enabled_flag);
		printf(" cabac_bypass_alignment_enabled_flag : %d \n", sre->cabac_bypass_alignment_enabled_flag);
	}

	// sps_multiplayer_extension_flag
	// sps_3d_extension_flag

	if (sps->sps_scc_extension_flag)
	{
		// hevc_decode_sps_scc_extension(sps, b);
		printf(" ===== sps scc extension ===== \n");
		int i;
		int comp, num_comps;
		sps_scc_extension_t* sse = &sps->sps_scc_extension;
		printf(" sps_curr_pic_ref_enabled_flag : %d \n", sse->sps_curr_pic_ref_enabled_flag);
		printf(" palette_mode_enabled_flag : %d \n", sse->palette_mode_enabled_flag);
		if (sse->palette_mode_enabled_flag)
		{
			printf(" palette_max_size : %d \n", sse->palette_max_size);
			printf(" delta_palette_max_predictor_size : %d \n", sse->delta_palette_max_predictor_size);
			printf(" sps_palette_predictor_initializers_present_flag : %d \n", sse->sps_palette_predictor_initializers_present_flag);
			if (sse->sps_palette_predictor_initializers_present_flag)
			{
				printf(" sps_num_palette_predictor_initializers_minus1 : %d \n", sse->sps_num_palette_predictor_initializers_minus1);
				num_comps = (sps->chroma_format_idc == 0) ? 1 : 3;
				for (comp = 0; comp < num_comps; comp++)
				{
					for (i = 0; i <= sse->sps_num_palette_predictor_initializers_minus1; i++)
					{
						printf(" palette_max_size[%d][%d] : %d \n", comp, i, sse->sps_palette_predictor_initializer[comp][i]);
					}
				}
			}
		}
		printf(" motion_vector_resolution_control_idc : %d \n", sse->motion_vector_resolution_control_idc);
		printf(" intra_boundary_filtering_disabled_flag : %d \n", sse->intra_boundary_filtering_disabled_flag);
	}

	if (sps->sps_extension_4bits)
	{
		/*while (!bs_eof(b))
		{
			sps-> = bs_read_u1(b);
		}*/
		printf(" sps_extension_data_flag : %d \n", sps->sps_extension_data_flag);
	}
	// hevc_decode_rbsp_trailing_bits(b);
}

void debug_pps(hevc_stream_t* h)
{
	int i;
	hevc_pps_t* pps = h->pps;
	printf(" pps_pic_parameter_set_id : %d \n", pps->pps_pic_parameter_set_id);
	printf(" pps_seq_parameter_set_id : %d \n", pps->pps_seq_parameter_set_id);
	printf(" dependent_slice_segments_enabled_flag : %d \n", pps->dependent_slice_segments_enabled_flag);
	printf(" output_flag_present_flag : %d \n", pps->output_flag_present_flag);
	printf(" num_extra_slice_header_bits : %d \n", pps->num_extra_slice_header_bits);
	printf(" sign_data_hiding_enabled_flag : %d \n", pps->sign_data_hiding_enabled_flag);
	printf(" cabac_init_present_flag : %d \n", pps->cabac_init_present_flag);
	printf(" num_ref_idx_l0_default_active_minus1 : %d \n", pps->num_ref_idx_l0_default_active_minus1);
	printf(" num_ref_idx_l1_default_active_minus1 : %d \n", pps->num_ref_idx_l1_default_active_minus1);
	printf(" init_qp_minus26 : %d \n", pps->init_qp_minus26);
	printf(" constrained_intra_pred_flag : %d \n", pps->constrained_intra_pred_flag);
	printf(" transform_skip_enabled_flag : %d \n", pps->transform_skip_enabled_flag);
	printf(" cu_qp_delta_enabled_flag : %d \n", pps->cu_qp_delta_enabled_flag);
	if (pps->cu_qp_delta_enabled_flag)
	{
		printf(" diff_cu_qp_delta_depth : %d \n", pps->diff_cu_qp_delta_depth);
	}
	printf(" pps_cb_qp_offset : %d \n", pps->pps_cb_qp_offset);
	printf(" pps_cr_qp_offset : %d \n", pps->pps_cr_qp_offset);
	printf(" pps_slice_chroma_qp_offsets_present_flag : %d \n", pps->pps_slice_chroma_qp_offsets_present_flag);
	printf(" weighted_pred_flag : %d \n", pps->weighted_pred_flag);
	printf(" weighted_bipred_flag : %d \n", pps->weighted_bipred_flag);
	printf(" transquant_bypass_enabled_flag : %d \n", pps->transquant_bypass_enabled_flag);
	printf(" tiles_enabled_flag : %d \n", pps->tiles_enabled_flag);
	printf(" entropy_coding_sync_enabled_flag : %d \n", pps->entropy_coding_sync_enabled_flag);
	if (pps->tiles_enabled_flag)
	{
		printf(" num_tile_columns_minus1 : %d \n", pps->num_tile_columns_minus1);
		printf(" num_tile_rows_minus1 : %d \n", pps->num_tile_rows_minus1);
		printf(" uniform_spacing_flag : %d \n", pps->uniform_spacing_flag);
		if (!pps->uniform_spacing_flag)
		{
			for (i = 0; i < pps->num_tile_columns_minus1; i++)
			{
				printf(" column_width_minus1[%d] : %d \n", i, pps->column_width_minus1[i]);
			}
			for (i = 0; i < pps->num_tile_rows_minus1; i++)
			{
				printf(" row_height_minus1[%d] : %d \n", i, pps->row_height_minus1[i]);
			}
		}
		printf(" loop_filter_across_tiles_enabled_flag : %d \n", pps->loop_filter_across_tiles_enabled_flag);
	}
	printf(" pps_loop_filter_across_slices_enabled_flag : %d \n", pps->pps_loop_filter_across_slices_enabled_flag);
	printf(" deblocking_filter_control_present_flag : %d \n", pps->deblocking_filter_control_present_flag);
	if (pps->deblocking_filter_control_present_flag)
	{
		printf(" deblocking_filter_override_enabled_flag : %d \n", pps->deblocking_filter_override_enabled_flag);
		printf(" pps_deblocking_filter_disabled_flag : %d \n", pps->pps_deblocking_filter_disabled_flag);
		if (!pps->pps_deblocking_filter_disabled_flag)
		{
			printf(" pps_beta_offset_div2 : %d \n", pps->pps_beta_offset_div2);
			printf(" pps_tc_offset_div2 : %d \n", pps->pps_tc_offset_div2);
		}
	}

	printf(" pps_scaling_list_data_present_flag : %d \n", pps->pps_scaling_list_data_present_flag);
	if (pps->pps_scaling_list_data_present_flag)
	{
		debug_scaling_list_data(&pps->pps_sl_data);
	}

	printf(" lists_modification_present_flag : %d \n", pps->lists_modification_present_flag);
	printf(" log2_parallel_merge_level_minus2 : %d \n", pps->log2_parallel_merge_level_minus2);
	printf(" slice_segment_header_extension_present_flag : %d \n", pps->slice_segment_header_extension_present_flag);
	printf(" pps_extension_present_flag : %d \n", pps->pps_extension_present_flag);
	if (pps->pps_extension_present_flag)
	{
		printf(" pps_range_extension_flag : %d \n", pps->pps_range_extension_flag);
		printf(" pps_multilayer_extension_flag : %d \n", pps->pps_multilayer_extension_flag);
		printf(" pps_3d_extension_flag : %d \n", pps->pps_3d_extension_flag);
		printf(" pps_scc_extension_flag : %d \n", pps->pps_scc_extension_flag);
		printf(" pps_extension_4bits : %d \n", pps->pps_extension_4bits);
	}

	if (pps->pps_range_extension_flag)
	{
		pps_range_extension_t* pps_re = &h->pps->pps_range_extension;
		if (h->pps->transform_skip_enabled_flag)
		{
			printf(" log2_max_transform_skip_block_size_minus2 : %d \n", pps_re->log2_max_transform_skip_block_size_minus2);
		}
		printf(" cross_component_prediction_enabled_flag : %d \n", pps_re->cross_component_prediction_enabled_flag);
		printf(" chroma_qp_offset_list_enabled_flag : %d \n", pps_re->chroma_qp_offset_list_enabled_flag);
		if (pps_re->chroma_qp_offset_list_enabled_flag)
		{
			printf(" diff_cu_chroma_qp_offset_depth : %d \n", pps_re->diff_cu_chroma_qp_offset_depth);
			printf(" chroma_qp_offset_list_len_minus1 : %d \n", pps_re->chroma_qp_offset_list_len_minus1);
			for (i = 0; i <= pps_re->chroma_qp_offset_list_len_minus1; i++)
			{
				printf(" cb_qp_offset_list[%d] : %d \n", i, pps_re->cb_qp_offset_list[i]);
				printf(" cr_qp_offset_list[%d] : %d \n", i, pps_re->cr_qp_offset_list[i]);
			}
		}
		printf(" log2_sao_offset_scale_luma : %d \n", pps_re->log2_sao_offset_scale_luma);
		printf(" log2_sao_offset_scale_chroma : %d \n", pps_re->log2_sao_offset_scale_chroma);
	}

	// pps_multilayer_extension
	// pps_3d_extension
	if (pps->pps_scc_extension_flag)
	{
		// hevc_decode_pps_scc_extension(h, b);
		pps_scc_extension_t* pps_se = &h->pps->pps_scc_extension;
		printf(" pps_curr_pic_ref_enabled_flag : %d \n", pps_se->pps_curr_pic_ref_enabled_flag);
		printf(" residual_adaptive_colour_transform_enabled_flag : %d \n", pps_se->residual_adaptive_colour_transform_enabled_flag);
		if (pps_se->residual_adaptive_colour_transform_enabled_flag)
		{
			printf(" pps_slice_act_qp_offsets_present_flag : %d \n", pps_se->pps_slice_act_qp_offsets_present_flag);
			printf(" pps_act_y_qp_offset_plus5 : %d \n", pps_se->pps_act_y_qp_offset_plus5);
			printf(" pps_act_cb_qp_offset_plus5 : %d \n", pps_se->pps_act_cb_qp_offset_plus5);
			printf(" pps_act_cr_qp_offset_plus3 : %d \n", pps_se->pps_act_cr_qp_offset_plus3);
		}
		printf(" pps_palette_predictor_initializers_present_flag : %d \n", pps_se->pps_palette_predictor_initializers_present_flag);
		if (pps_se->pps_palette_predictor_initializers_present_flag)
		{
			printf(" pps_num_palette_predictor_initializers : %d \n", pps_se->pps_num_palette_predictor_initializers);
			if (pps_se->pps_num_palette_predictor_initializers > 0)
			{
				printf(" monochrome_palette_flag : %d \n", pps_se->monochrome_palette_flag);
				printf(" luma_bit_depth_entry_minus8 : %d \n", pps_se->luma_bit_depth_entry_minus8);
				if (!pps_se->monochrome_palette_flag)
				{
					printf(" chroma_bit_depth_entry_minus8 : %d \n", pps_se->chroma_bit_depth_entry_minus8);
				}
				int num_comps = pps_se->monochrome_palette_flag;
				for (int comp = 0; comp < num_comps; comp++)
				{
					for (int i = 0; i < pps_se->pps_num_palette_predictor_initializers; i++)
					{
						printf(" chroma_bit_depth_entry_minus8[%d][%d] : %d \n", comp, i, pps_se->pps_palette_predictor_initializer[comp][i]);
					}
				}
			}
		}
	}

	if (pps->pps_extension_4bits)
	{
		printf(" pps_extension_data_flag : %d \n", pps->pps_extension_data_flag);
	}
	// hevc_decode_rbsp_trailing_bits(b);
}

// void debug_pwt()

void debug_slice_header(hevc_stream_t* h)
{
	hevc_sps_t* sps = h->sps;
	hevc_pps_t* pps = h->pps;
	hevc_slice_segment_header_t* sh = h->sh;
	printf(" first_slice_segment_in_pic_flag : %d \n", sh->first_slice_segment_in_pic_flag);

	if (h->nal->nal_unit_type >= NALU_TYPE_CODED_SLICE_BLA_W_LP && h->nal->nal_unit_type <= NALU_TYPE_RSV_IRAP_VCL23)
	{
		printf(" no_output_of_prior_pics_flag : %d \n", sh->no_output_of_prior_pics_flag);
	}
	printf(" slice_pic_parameter_set_id : %d \n", sh->slice_pic_parameter_set_id);
	if (!sh->first_slice_segment_in_pic_flag)
	{
		if (pps->dependent_slice_segments_enabled_flag)
		{
			printf(" dependent_slice_segment_flag : %d \n", sh->dependent_slice_segment_flag);
		}
		printf(" slice_segment_address : %d \n", sh->slice_segment_address);
	}

	int cu_qp_delta_val = 0;
	if (!sh->dependent_slice_segment_flag)
	{
		for (int i = 0; i < h->pps->num_extra_slice_header_bits; i++)
		{
			printf(" slice_reserved_flag[%d] : %d \n", i, sh->slice_reserved_flag[i]);
		}
		printf(" slice_type : %d \n", sh->slice_type);
		if (pps->output_flag_present_flag)
		{
			printf(" pic_output_flag : %d \n", sh->pic_output_flag);
		}

		if (sps->separate_colour_plane_flag == 1)
		{
			printf(" colour_plane_id : %d \n", sh->colour_plane_id);
		}

		if (h->nal->nal_unit_type != NALU_TYPE_CODED_SLICE_IDR_W_RADL && h->nal->nal_unit_type != NALU_TYPE_CODED_SLICE_IDR_N_LP)
		{
			printf(" slice_pic_order_cnt_lsb : %d \n", sh->slice_pic_order_cnt_lsb);
			printf(" short_term_ref_pic_set_sps_flag : %d \n", sh->short_term_ref_pic_set_sps_flag);
			if (!sh->short_term_ref_pic_set_sps_flag)
			{
				// hevc_decode_st_ref_pic_set(sps, sps->st_rps, b, sps->num_short_term_ref_pic_sets, 0);
				printf(" ===== RPS ===== \n");
				st_ref_pic_set_t* st_rps = sps->st_rps;
				if (h->sps->st_rps != 0)
				{
					printf(" inter_ref_pic_set_prediction_flag : %d \n", st_rps->inter_ref_pic_set_prediction_flag);
					if (st_rps->inter_ref_pic_set_prediction_flag)
					{
						const st_ref_pic_set_t* tmp_rps;
						//if (st_rps_idx == num_short_term_ref_pic_sets)
						{
							printf(" delta_idx_minus1 : %d \n", st_rps->delta_idx_minus1);
						}
						printf(" delta_rps_sign : %d \n", st_rps->delta_rps_sign);
						printf(" abs_delta_rps_minus1 : %d \n", st_rps->abs_delta_rps_minus1);
						tmp_rps = &sps->st_rps[st_rps - sps->st_rps - 1];
						for (int i = 0; i <= tmp_rps->num_delta_pocs; i++)
						{
							printf(" used_by_curr_pic_flag[%d] : %d \n", i, st_rps->used_by_curr_pic_flag[i]);
							if (!st_rps->used_by_curr_pic_flag[i])
							{
								printf(" use_delta_flag[%d] : %d \n", i, st_rps->use_delta_flag[i]);
							}
						}
					}
					else
					{
						printf(" num_negative_pics : %d \n", st_rps->num_negative_pics);
						printf(" num_positive_pics : %d \n", st_rps->num_positive_pics);
						for (int i = 0; i <= st_rps->num_negative_pics; i++)
						{
							printf(" delta_poc_s0_minus1[%d] : %d \n", i, st_rps->delta_poc_s0_minus1[i]);
							printf(" used_by_curr_pic_s0_flag[%d] : %d \n", i, st_rps->used_by_curr_pic_s0_flag[i]);
						}

						for (int i = 0; i <= st_rps->num_positive_pics; i++)
						{
							printf(" delta_poc_s1_minus1[%d] : %d \n", i, st_rps->delta_poc_s1_minus1[i]);
							printf(" used_by_curr_pic_s1_flag[%d] : %d \n", i, st_rps->used_by_curr_pic_s1_flag[i]);
						}
					}
				}
			}
			else if (sps->num_short_term_ref_pic_sets > 1)
			{
				printf(" short_term_ref_pic_set_idx : %d \n", sh->short_term_ref_pic_set_idx);
			}

			if (sps->long_term_ref_pics_present_flag)
			{
				if (sps->num_long_term_ref_pics_sps > 0)
				{
					printf(" num_long_term_sps : %d \n", sh->num_long_term_sps);
				}
				printf(" num_long_term_pics : %d \n", sh->num_long_term_pics);
				for (int i = 0; i < sh->num_long_term_sps + sh->num_long_term_pics; i++)
				{
					if (i < sh->num_long_term_sps)
					{
						if (sps->num_long_term_ref_pics_sps > 1)
						{
							printf(" lt_idx_sps[%d] : %d \n", i, sh->lt_idx_sps[i]);
						}
					}
					else
					{
						printf(" poc_lsb_lt[%d] : %d \n", i, sh->poc_lsb_lt[i]);
						printf(" used_by_curr_pic_lt_flag[%d] : %d \n", i, sh->used_by_curr_pic_lt_flag[i]);
					}
					printf(" delta_poc_msb_present_flag[%d] : %d \n", i, sh->delta_poc_msb_present_flag[i]);
					if (sh->delta_poc_msb_present_flag[i])
					{
						printf(" delta_poc_msb_cycle_lt[%d] : %d \n", i, sh->delta_poc_msb_cycle_lt[i]);
					}
				}
			}

			if (sps->sps_temporal_mvp_enabled_flag)
			{
				printf(" slice_temporal_mvp_enabled_flag : %d \n", sh->slice_temporal_mvp_enabled_flag);
			}
		}

		if (sps->sample_adaptive_offset_enabled_flag)
		{
			printf(" slice_sao_luma_flag : %d \n", sh->slice_sao_luma_flag);
			if (sps->ChromaArrayType != 0)
			{
				printf(" slice_sao_chroma_flag : %d \n", sh->slice_sao_chroma_flag);
			}
		}

		if (sh->slice_type == H265_SH_SLICE_TYPE_P || sh->slice_type == H265_SH_SLICE_TYPE_B)
		{
			printf(" num_ref_idx_active_override_flag : %d \n", sh->num_ref_idx_active_override_flag);
			if (sh->num_ref_idx_active_override_flag)
			{
				printf(" num_ref_idx_l0_active_minus1 : %d \n", sh->num_ref_idx_l0_active_minus1);
				if (sh->slice_type == H265_SH_SLICE_TYPE_B)
				{
					printf(" num_ref_idx_l1_active_minus1 : %d \n", sh->num_ref_idx_l1_active_minus1);
				}
			}

			int num_pic_total_curr = 0;
			if (pps->lists_modification_present_flag && get_num_pic_total_curr(h))
			{
				printf(" ===== PPS->RPLM ===== \n");
				ref_pic_lists_modification_t* rplm = &h->sh->rplm;
				// hevc_decode_ref_pic_lists_modification(h);
				printf(" rplm->ref_pic_list_modification_flag_l0 : %d \n", rplm->ref_pic_list_modification_flag_l0);
				if (rplm->ref_pic_list_modification_flag_l0)
				{
					for (int i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++)
					{
						printf(" rplm->list_entry_l0[%d] : %d \n", i, rplm->list_entry_l0[i]);
						// rplm->list_entry_l0[i] = bs_read_u(b, h->sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
					}
				}
				if (h->sh->slice_type == H265_SH_SLICE_TYPE_B)
				{
					printf(" rplm->ref_pic_list_modification_flag_l1 : %d \n", rplm->ref_pic_list_modification_flag_l1);
					if (rplm->ref_pic_list_modification_flag_l1)
					{
						for (int i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++)
						{
							printf(" rplm->list_entry_l1[%d] : %d \n", i, rplm->list_entry_l1[i]);
						}
					}
				}
			}

			if (sh->slice_type == H265_SH_SLICE_TYPE_B)
			{
				printf(" mvd_l1_zero_flag : %d \n", sh->mvd_l1_zero_flag);
			}
			if (h->pps->cabac_init_present_flag)
			{
				printf(" cabac_init_flag : %d \n", sh->cabac_init_flag);
			}
			if (sh->slice_temporal_mvp_enabled_flag)
			{
				if (sh->slice_type == H265_SH_SLICE_TYPE_B)
				{
					printf(" collocated_from_l0_flag : %d \n", sh->collocated_from_l0_flag);
				}
				if ((sh->collocated_from_l0_flag && sh->num_ref_idx_l0_active_minus1 > 0) ||
					(!sh->collocated_from_l0_flag && sh->num_ref_idx_l1_active_minus1 > 0))
				{
					printf(" collocated_ref_idx : %d \n", sh->collocated_ref_idx);
				}
			}
			if ((h->pps->weighted_pred_flag && sh->slice_type == H265_SH_SLICE_TYPE_P) ||
				(h->pps->weighted_bipred_flag && sh->slice_type == H265_SH_SLICE_TYPE_B))
			{
				printf(" ===== PWT ===== \n");
				// hevc_decode_pred_weight_table(h, b);
				pred_weight_table_t* pwt = &sh->pwt;
				printf(" luma_log2_weight_denom : %d \n", pwt->luma_log2_weight_denom);
				if (h->sps->ChromaArrayType != 0)
				{
					printf(" delta_chroma_log2_weight_denom : %d \n", pwt->delta_chroma_log2_weight_denom);
				}

				for (int i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++) // FIXME: should add pic_layer_id check and nuh_layer_id check
				{
					printf(" luma_weight_l0_flag[%d] : %d \n", i, pwt->luma_weight_l0_flag[i]);
				}
				if (h->sps->ChromaArrayType != 0)
				{
					for (int i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++) // FIXME: should add pic_layer_id check and nuh_layer_id check
					{
						printf(" chroma_weight_l0_flag[%d] : %d \n", i, pwt->chroma_weight_l0_flag[i]);
					}
				}

				for (int i = 0; i <= h->sh->num_ref_idx_l0_active_minus1; i++)
				{
					if (pwt->luma_weight_l0_flag[i])
					{
						printf(" delta_luma_weight_l0[%d] : %d \n", i, pwt->delta_luma_weight_l0[i]);
						printf(" luma_offset_l0[%d] : %d \n", i, pwt->luma_offset_l0[i]);
					}
					if (pwt->chroma_weight_l0_flag)
					{
						for (int j = 0; j < 2; j++)
						{
							printf(" delta_chroma_weight_l0[%d][%d] : %d \n", i, j, pwt->delta_chroma_weight_l0[i][j]);
							printf(" delta_chroma_offset_l0[%d][%d] : %d \n", i, j, pwt->delta_chroma_offset_l0[i][j]);
						}
					}
				}

				if (h->sh->slice_type == H265_SH_SLICE_TYPE_B)
				{
					for (int i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++) // FIXME: add pic_layer_id check
					{
						printf(" luma_weight_l1_flag[%d] : %d \n", i, pwt->luma_weight_l1_flag[i]);
					}

					if (h->sps->ChromaArrayType != 0)
					{
						for (int i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++) // FIXME: add pic_layer_id check
						{
							printf(" chroma_weight_l1_flag[%d] : %d \n", i, pwt->chroma_weight_l1_flag[i]);
						}
					}

					for (int i = 0; i <= h->sh->num_ref_idx_l1_active_minus1; i++)
					{
						if (pwt->luma_weight_l1_flag[i])
						{
							printf(" delta_luma_weight_l1[%d] : %d \n", i, pwt->delta_luma_weight_l1[i]);
							printf(" luma_offset_l1[%d] : %d \n", i, pwt->luma_offset_l1[i]);
						}
						if (h->sps->ChromaArrayType != 0)
						{
							for (int j = 0; j < 2; j++)
							{
								printf(" delta_chroma_weight_l1[%d][%d] : %d \n", i, pwt->delta_chroma_weight_l1[i][j]);
								printf(" delta_chroma_offset_l1[%d][%d] : %d \n", i, pwt->delta_chroma_offset_l1[i][j]);
							}
						}
					}
				}

			}
			printf(" five_minus_max_num_merge_cand : %d \n", sh->five_minus_max_num_merge_cand);
			if (h->sps->sps_scc_extension.motion_vector_resolution_control_idc == 2)
			{
				printf(" use_integer_mv_flag : %d \n", sh->use_integer_mv_flag);
			}
		}

		printf(" slice_qp_delta : %d \n", sh->slice_qp_delta);
		if (h->pps->pps_slice_chroma_qp_offsets_present_flag)
		{
			printf(" slice_cb_qp_offset : %d \n", sh->slice_cb_qp_offset);
			printf(" slice_cr_qp_offset : %d \n", sh->slice_cr_qp_offset);
		}
		if (h->pps->pps_scc_extension.pps_slice_act_qp_offsets_present_flag)
		{
			printf(" slice_act_y_qp_offset : %d \n", sh->slice_act_y_qp_offset);
			printf(" slice_act_cb_qp_offset : %d \n", sh->slice_act_cb_qp_offset);
			printf(" slice_act_cr_qp_offset : %d \n", sh->slice_act_cr_qp_offset);
		}
		if (h->pps->pps_range_extension.chroma_qp_offset_list_enabled_flag)
		{
			printf(" cu_chroma_qp_offset_enabled_flag : %d \n", sh->cu_chroma_qp_offset_enabled_flag);
		}
		if (h->pps->deblocking_filter_override_enabled_flag)
		{
			printf(" deblocking_filter_override_flag : %d \n", sh->deblocking_filter_override_flag);
		}
		if (sh->deblocking_filter_override_flag)
		{
			printf(" slice_deblocking_filter_disabled_flag : %d \n", sh->slice_deblocking_filter_disabled_flag);
			if (!sh->slice_deblocking_filter_disabled_flag)
			{
				printf(" slice_beta_offset_div2 : %d \n", sh->slice_beta_offset_div2);
				printf(" slice_tc_offset_div2 : %d \n", sh->slice_tc_offset_div2);
			}
		}

		if (h->pps->pps_loop_filter_across_slices_enabled_flag &&
			(sh->slice_sao_luma_flag || sh->slice_sao_chroma_flag || !sh->slice_deblocking_filter_disabled_flag))
		{
			printf(" slice_loop_filter_across_slices_enabled_flag : %d \n", sh->slice_loop_filter_across_slices_enabled_flag);
		}
	}
}

parser.cpp

#pragma pack(1)
#pragma warning(disable : 4996)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "parser.h"

/**
 Find the beginning and end of a NAL (Network Abstraction Layer) unit in a byte buffer containing H264 bitstream data.
 @param[in]   buf        the buffer
 @param[in]   size       the size of the buffer
 @param[out]  nal_start  the beginning offset of the nal
 @param[out]  nal_end    the end offset of the nal
 @return                 the length of the nal, or 0 if did not find start of nal, or -1 if did not find end of nal
 */
int find_nal_unit(uint8_t* buf, int size, int* nal_start, int* nal_end)
{
	int i;
	// find start
	*nal_start = 0;
	*nal_end = 0;

	i = 0;
	while (   //( next_bits( 24 ) != 0x000001 && next_bits( 32 ) != 0x00000001 )
		(buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0x01) &&
		(buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0 || buf[i + 3] != 0x01)
		)
	{
		i++; // skip leading zero
		if (i + 4 >= size) { return 0; } // did not find nal start
	}

	if (buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0x01) // ( next_bits( 24 ) != 0x000001 )
	{
		i++;
	}

	if (buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0x01) { /* error, should never happen */ return 0; }
	i += 3;
	*nal_start = i;

	while (   //( next_bits( 24 ) != 0x000000 && next_bits( 24 ) != 0x000001 )
		(buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0) &&
		(buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0x01)
		)
	{
		i++;
		// FIXME the next line fails when reading a nal that ends exactly at the end of the data
		if (i + 3 >= size) { *nal_end = size; return -1; } // did not find nal end, stream ended first
	}

	*nal_end = i;
	return (*nal_end - *nal_start);
}

int parse_internal(const char* file_name)
{
	FILE* f_bitstream = NULL;
	hevc_nal_t* n;

	f_bitstream = fopen(file_name, "rb");
	if (!f_bitstream) {
		ERROR("failed to open input file");
		return -1;
	}

	n = (hevc_nal_t*)calloc(1, sizeof(hevc_nal_t));
	if (n == NULL) {
		ERROR("Alloc NALU Error");
		return 0;
	}

	uint8_t* p = (uint8_t*)calloc(BUFSIZE, sizeof(uint8_t));
	if (p == NULL) {
		free(n);
		ERROR("failed to alloc nalu buffer");
		return 0;
	}

	hevc_stream_t* h = hevc_new();

	size_t rsz = 0;
	size_t sz = 0;
	int nal_start, nal_end;
	int len = 0;
	int debug = 1;
	int nal_cnt = 0;

	while (1) {
		rsz = fread(p + sz, 1, BUFSIZE - sz, f_bitstream);
		if (!rsz) {
			ERROR("read stram failed");
			break;
		}

		sz += rsz;
		while (find_nal_unit(p, sz, &nal_start, &nal_end) > 0) {
			p += nal_start;
			hevc_decode_nal_unit(h, p, nal_end - nal_start);

			if (debug)
			{
				// debug_bytes(p - 4, nal_end - nal_start + 4 >= 16 ? 16 : nal_end - nal_start + 4);
				hevc_debug_nal(h, h->nal);
			}

			p += (nal_end - nal_start);
			sz -= nal_end;
		}

		// 这里需要多执行一次,对于最后一个NALU而言,确定其大小必须依靠更后一个NALU,但更后一个NALU是不存在的
		find_nal_unit(p, sz, &nal_start, &nal_end);
	}
}

int parser()
{
	int type = 1;
	if (type == 0)
	{
		const char* h264_name = "output.h264";
		// h264_parser(h264_name);
	}
	else if (type == 1)
	{
		const char* hevc_name = "output.h265";
		parse_internal(hevc_name);
	}
	else 
	{
		ERROR("invalid type, return");
		return -1;
	}

	return 0;
}

3.输出结果

==================== NAL ====================
 forbidden_zero_bit : 0 
 nal_unit_type : 32 
 nuh_layer_id : 0 
 nuh_temporal_id_plus1 : 1 
======= VPS =======
 vps_video_parameter_set_id : 0 
 vps_base_layer_internal_flag : 1 
 vps_base_layer_available_flag : 1 
 vps_max_layers_minus1 : 0 
 vps_max_sub_layers_minus1 : 0 
 vps_temporal_id_nesting_flag : 1 
 vps_reserved_0xffff_16bits : 65535 
 ===== profile tier level ===== 
 ptl->general_profile_space : 0 
 ptl->general_tier_flag : 0 
 ptl->general_profile_idc : 1 
 ptl->general_profile_compatibility_flag[0] : 0 
 ptl->general_profile_compatibility_flag[1] : 1 
 ptl->general_profile_compatibility_flag[2] : 1 
 ptl->general_profile_compatibility_flag[3] : 0 
 ptl->general_profile_compatibility_flag[4] : 0 
 ptl->general_profile_compatibility_flag[5] : 0 
 ptl->general_profile_compatibility_flag[6] : 0 
 ptl->general_profile_compatibility_flag[7] : 0 
 ptl->general_profile_compatibility_flag[8] : 0 
 ptl->general_profile_compatibility_flag[9] : 0 
 ptl->general_profile_compatibility_flag[10] : 0 
 ptl->general_profile_compatibility_flag[11] : 0 
 ptl->general_profile_compatibility_flag[12] : 0 
 ptl->general_profile_compatibility_flag[13] : 0 
 ptl->general_profile_compatibility_flag[14] : 0 
 ptl->general_profile_compatibility_flag[15] : 0 
 ptl->general_profile_compatibility_flag[16] : 0 
 ptl->general_profile_compatibility_flag[17] : 0 
 ptl->general_profile_compatibility_flag[18] : 0 
 ptl->general_profile_compatibility_flag[19] : 0 
 ptl->general_profile_compatibility_flag[20] : 0 
 ptl->general_profile_compatibility_flag[21] : 0 
 ptl->general_profile_compatibility_flag[22] : 0 
 ptl->general_profile_compatibility_flag[23] : 0 
 ptl->general_profile_compatibility_flag[24] : 0 
 ptl->general_profile_compatibility_flag[25] : 0 
 ptl->general_profile_compatibility_flag[26] : 0 
 ptl->general_profile_compatibility_flag[27] : 0 
 ptl->general_profile_compatibility_flag[28] : 0 
 ptl->general_profile_compatibility_flag[29] : 0 
 ptl->general_profile_compatibility_flag[30] : 0 
 ptl->general_profile_compatibility_flag[31] : 0 
 ptl->general_progressive_source_flag : 1 
 ptl->general_interlaced_source_flag : 0 
 ptl->general_non_packet_constrained_flag : 0 
 ptl->general_frame_only_constraint_flag : 1 
 ptl->general_inbld_flag : 0 
 ptl->general_level_idc : 150 
 vps_sub_layer_ordering_info_present_flag : 1 
 vps_max_dec_pic_buffering_minus1[0] : 3 
 vps_max_num_reorder_pics[0] : 0 
 vps_max_latency_increase_plus1[0] : 1 
 vps_max_layer_id : 0 
 vps_num_layer_sets_minus1 : 0 
 layer_id_included_flag[0][0] : 0 
 vps_timing_info_present_flag : 0 
 vps_extension_flag : 0 
 vps_extension_data_flag : 0 
==================== NAL ====================
 forbidden_zero_bit : 0 
 nal_unit_type : 33 
 nuh_layer_id : 0 
 nuh_temporal_id_plus1 : 1 
 ===== SPS ===== 
 sps_video_parameter_set_id : 0 
 sps_max_sub_layers_minus1 : 0 
 sps_temporal_id_nesting_flag : 1 
 ===== profile tier level ===== 
 ptl->general_profile_space : 0 
 ptl->general_tier_flag : 0 
 ptl->general_profile_idc : 1 
 ptl->general_profile_compatibility_flag[0] : 0 
 ptl->general_profile_compatibility_flag[1] : 1 
 ptl->general_profile_compatibility_flag[2] : 1 
 ptl->general_profile_compatibility_flag[3] : 0 
 ptl->general_profile_compatibility_flag[4] : 0 
 ptl->general_profile_compatibility_flag[5] : 0 
 ptl->general_profile_compatibility_flag[6] : 0 
 ptl->general_profile_compatibility_flag[7] : 0 
 ptl->general_profile_compatibility_flag[8] : 0 
 ptl->general_profile_compatibility_flag[9] : 0 
 ptl->general_profile_compatibility_flag[10] : 0 
 ptl->general_profile_compatibility_flag[11] : 0 
 ptl->general_profile_compatibility_flag[12] : 0 
 ptl->general_profile_compatibility_flag[13] : 0 
 ptl->general_profile_compatibility_flag[14] : 0 
 ptl->general_profile_compatibility_flag[15] : 0 
 ptl->general_profile_compatibility_flag[16] : 0 
 ptl->general_profile_compatibility_flag[17] : 0 
 ptl->general_profile_compatibility_flag[18] : 0 
 ptl->general_profile_compatibility_flag[19] : 0 
 ptl->general_profile_compatibility_flag[20] : 0 
 ptl->general_profile_compatibility_flag[21] : 0 
 ptl->general_profile_compatibility_flag[22] : 0 
 ptl->general_profile_compatibility_flag[23] : 0 
 ptl->general_profile_compatibility_flag[24] : 0 
 ptl->general_profile_compatibility_flag[25] : 0 
 ptl->general_profile_compatibility_flag[26] : 0 
 ptl->general_profile_compatibility_flag[27] : 0 
 ptl->general_profile_compatibility_flag[28] : 0 
 ptl->general_profile_compatibility_flag[29] : 0 
 ptl->general_profile_compatibility_flag[30] : 0 
 ptl->general_profile_compatibility_flag[31] : 0 
 ptl->general_progressive_source_flag : 1 
 ptl->general_interlaced_source_flag : 0 
 ptl->general_non_packet_constrained_flag : 0 
 ptl->general_frame_only_constraint_flag : 1 
 ptl->general_inbld_flag : 0 
 ptl->general_level_idc : 150 
 sps_seq_parameter_set_id : 0 
 chroma_format_idc : 1 
 pic_width_in_luma_samples : 1920 
 pic_height_in_luma_samples : 1200 
 conformance_window_flag : 0 
 bit_depth_luma_minus8 : 0 
 bit_depth_chroma_minus8 : 0 
 log2_max_pic_order_cnt_lsb_minus4 : 4 
 sps_sub_layer_ordering_info_present_flag : 1 
 sps_max_dec_pic_buffering_minus1[0] : 3 
 sps_max_num_reorder_pics[0] : 0 
 sps_max_latency_increase_plus1[0] : 1 
 log2_min_luma_coding_block_size_minus3 : 0 
 log2_diff_max_min_luma_coding_block_size : 3 
 log2_min_luma_transform_block_size_minus2 : 0 
 log2_diff_max_min_luma_transform_block_size : 3 
 max_transform_hierarchy_depth_inter : 0 
 max_transform_hierarchy_depth_intra : 0 
 scaling_list_enabled_flag : 0 
 amp_enabled_flag : 0 
 sample_adaptive_offset_enabled_flag : 1 
 pcm_enabled_flag : 0 
 num_short_term_ref_pic_sets : 0 
 long_term_ref_pics_present_flag : 0 
 sps_temporal_mvp_enabled_flag : 1 
 strong_intra_smoothing_enabled_flag : 1 
 vui_parameters_present_flag : 1 
 ===== VUI ===== 
 aspect_ratio_info_present_flag : 0 
 overscan_info_present_flag : 0 
 video_signal_type_present_flag : 1 
 video_format : 5 
 video_full_range_flag : 0 
 colour_description_present_flag : 0 
 chroma_loc_info_present_flag : 0 
 neutral_chroma_indication_flag : 0 
 field_seq_flag : 0 
 frame_field_info_present_flag : 0 
 default_display_window_flag : 0 
 vui_timing_info_present_flag : 1 
 vui_num_units_in_tick : 1 
 vui_time_scale : 25 
 vui_proc_proportioanl_to_timing_flag : 0 
 vui_hrd_parameters_present_flag : 0 
 bitstream_restriction_flag : 0 
 sps_extension_present_flag : 0 
==================== NAL ====================
 forbidden_zero_bit : 0 
 nal_unit_type : 34 
 nuh_layer_id : 0 
 nuh_temporal_id_plus1 : 1 
 pps_pic_parameter_set_id : 0 
 pps_seq_parameter_set_id : 0 
 dependent_slice_segments_enabled_flag : 0 
 output_flag_present_flag : 0 
 num_extra_slice_header_bits : 0 
 sign_data_hiding_enabled_flag : 1 
 cabac_init_present_flag : 0 
 num_ref_idx_l0_default_active_minus1 : 0 
 num_ref_idx_l1_default_active_minus1 : 0 
 init_qp_minus26 : 0 
 constrained_intra_pred_flag : 0 
 transform_skip_enabled_flag : 0 
 cu_qp_delta_enabled_flag : 1 
 diff_cu_qp_delta_depth : 1 
 pps_cb_qp_offset : 0 
 pps_cr_qp_offset : 0 
 pps_slice_chroma_qp_offsets_present_flag : 0 
 weighted_pred_flag : 1 
 weighted_bipred_flag : 0 
 transquant_bypass_enabled_flag : 0 
 tiles_enabled_flag : 0 
 entropy_coding_sync_enabled_flag : 1 
 pps_loop_filter_across_slices_enabled_flag : 1 
 deblocking_filter_control_present_flag : 0 
 pps_scaling_list_data_present_flag : 0 
 lists_modification_present_flag : 0 
 log2_parallel_merge_level_minus2 : 0 
 slice_segment_header_extension_present_flag : 0 
 pps_extension_present_flag : 0 
==================== NAL ====================
 forbidden_zero_bit : 0 
 nal_unit_type : 39 
 nuh_layer_id : 0 
 nuh_temporal_id_plus1 : 1 
======= SEI =======
=== User data unregistered ===
 payloadType : 5 
 payloadSize : 2296 
 payload : //..略去payload打印 
==================== NAL ====================
 forbidden_zero_bit : 0 
 nal_unit_type : 20 
 nuh_layer_id : 0 
 nuh_temporal_id_plus1 : 1 
 first_slice_segment_in_pic_flag : 1 
 no_output_of_prior_pics_flag : 0 
 slice_pic_parameter_set_id : 0 
 slice_type : 2 
 slice_sao_luma_flag : 1 
 slice_sao_chroma_flag : 1 
 slice_qp_delta : 7 
 slice_loop_filter_across_slices_enabled_flag : 1 
 ==================== NAL ====================
 forbidden_zero_bit : 0 
 nal_unit_type : 1 
 nuh_layer_id : 0 
 nuh_temporal_id_plus1 : 1 
 first_slice_segment_in_pic_flag : 1 
 slice_pic_parameter_set_id : 0 
 slice_type : 1 
 slice_pic_order_cnt_lsb : 1 
 short_term_ref_pic_set_sps_flag : 0 
 ===== RPS ===== 
 inter_ref_pic_set_prediction_flag : 0 
 num_negative_pics : 0 
 num_positive_pics : 0 
 delta_poc_s0_minus1[0] : 0 
 used_by_curr_pic_s0_flag[0] : 0 
 delta_poc_s1_minus1[0] : 0 
 used_by_curr_pic_s1_flag[0] : 0 
 slice_temporal_mvp_enabled_flag : 0 
 slice_sao_luma_flag : 1 
 slice_sao_chroma_flag : 0 
 num_ref_idx_active_override_flag : 1 
 num_ref_idx_l0_active_minus1 : 0 
 ===== PWT ===== 
 luma_log2_weight_denom : 0 
 delta_chroma_log2_weight_denom : 0 
 luma_weight_l0_flag[0] : 1 
 chroma_weight_l0_flag[0] : 1 
 delta_luma_weight_l0[0] : 8 
 luma_offset_l0[0] : 0 
 delta_chroma_weight_l0[0][0] : 0 
 delta_chroma_offset_l0[0][0] : 6 
 delta_chroma_weight_l0[0][1] : -1 
 delta_chroma_offset_l0[0][1] : 0 
 five_minus_max_num_merge_cand : 1 
 slice_qp_delta : -4 
 slice_loop_filter_across_slices_enabled_flag : 1 
 //...省略一部分

4.小结

H265码流格式相对而言比较复杂,其中涉及到的语法元素更多,其中互相依赖的关系也更加复杂,可能在实际应用中更多的关注H264标准是比较合适的(对于实时性要求比较高的场景)

CSDN : https://blog.csdn.net/weixin_42877471
Github : https://github.com/DoFulangChen

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值