示例工程:
【视频编码】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