vlc | branch: master | Francois Cartegnie <[email protected]> | Fri Dec 11 14:50:54 2015 +0100| [d72428878ccd5d47b7ce9c05efb2a8f084930681] | committer: Francois Cartegnie
hevc_nal: add profile_tier_level parser > http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=d72428878ccd5d47b7ce9c05efb2a8f084930681 --- modules/packetizer/hevc_nal.c | 188 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 188 insertions(+) diff --git a/modules/packetizer/hevc_nal.c b/modules/packetizer/hevc_nal.c index 9e301f1..7fd87db 100644 --- a/modules/packetizer/hevc_nal.c +++ b/modules/packetizer/hevc_nal.c @@ -21,8 +21,104 @@ #include "hevc_nal.h" #include "hxxx_nal.h" +#include <vlc_bits.h> + #include <limits.h> +typedef uint8_t nal_u1_t; +typedef uint8_t nal_u2_t; +typedef uint8_t nal_u3_t; +typedef uint8_t nal_u4_t; +typedef uint8_t nal_u5_t; +typedef uint8_t nal_u6_t; +typedef uint8_t nal_u7_t; +typedef uint8_t nal_u8_t; +typedef int32_t nal_se_t; +typedef uint32_t nal_ue_t; + +typedef struct +{ + nal_u2_t profile_space; + nal_u1_t tier_flag; + nal_u5_t profile_idc; + uint32_t profile_compatibility_flag; /* nal_u1_t * 32 */ + nal_u1_t progressive_source_flag; + nal_u1_t interlaced_source_flag; + nal_u1_t non_packed_constraint_flag; + nal_u1_t frame_only_constraint_flag; + struct + { + nal_u1_t max_12bit_constraint_flag; + nal_u1_t max_10bit_constraint_flag; + nal_u1_t max_8bit_constraint_flag; + nal_u1_t max_422chroma_constraint_flag; + nal_u1_t max_420chroma_constraint_flag; + nal_u1_t max_monochrome_constraint_flag; + nal_u1_t intra_constraint_flag; + nal_u1_t one_picture_only_constraint_flag; + nal_u1_t lower_bit_rate_constraint_flag; + } idc4to7; + struct + { + nal_u1_t inbld_flag; + } idc1to5; +} hevc_inner_profile_tier_level_t; + +#define HEVC_MAX_SUBLAYERS 8 +typedef struct +{ + hevc_inner_profile_tier_level_t general; + nal_u8_t general_level_idc; + uint8_t sublayer_profile_present_flag; /* nal_u1_t * 8 */ + uint8_t sublayer_level_present_flag; /* nal_u1_t * 8 */ + hevc_inner_profile_tier_level_t sub_layer[HEVC_MAX_SUBLAYERS]; + nal_u8_t sub_layer_level_idc[HEVC_MAX_SUBLAYERS]; +} hevc_profile_tier_level_t; + +typedef struct +{ + nal_u4_t sps_video_parameter_set_id; + nal_u3_t sps_max_sub_layers_minus1; + nal_u1_t sps_temporal_id_nesting_flag; + + hevc_profile_tier_level_t profile_tier_level; + + nal_ue_t sps_seq_parameter_set_id; + nal_ue_t chroma_format_idc; + nal_u1_t separate_colour_plane_flag; + + nal_ue_t pic_width_in_luma_samples; + nal_ue_t pic_height_in_luma_samples; + + nal_u1_t conformance_window_flag; + struct + { + nal_ue_t left_offset; + nal_ue_t right_offset; + nal_ue_t top_offset; + nal_ue_t bottom_offset; + } conf_win; + + nal_ue_t bit_depth_luma_minus8; + nal_ue_t bit_depth_chroma_minus8; + nal_ue_t log2_max_pic_order_cnt_lsb_minus4; + + nal_u1_t sps_sub_layer_ordering_info_present_flag; + struct + { + nal_ue_t dec_pic_buffering_minus1; + nal_ue_t num_reorder_pics; + nal_ue_t latency_increase_plus1; + } sps_max[1 + HEVC_MAX_SUBLAYERS]; + + nal_ue_t log2_min_luma_coding_block_size_minus3; + nal_ue_t log2_diff_max_min_luma_coding_block_size; + nal_ue_t log2_min_luma_transform_block_size_minus2; + nal_ue_t log2_diff_max_min_luma_transform_block_size; + + /* incomplete */ +} hevc_sequence_parameter_set_t; + /* Computes size and does check the whole struct integrity */ static size_t get_hvcC_to_AnnexB_NAL_size( const uint8_t *p_buf, size_t i_buf ) { @@ -104,3 +200,95 @@ uint8_t * hevc_hvcC_to_AnnexB_NAL( const uint8_t *p_buf, size_t i_buf, return p_ret; } + +static bool hevc_parse_inner_profile_tier_level_rbsp( bs_t *p_bs, + hevc_inner_profile_tier_level_t *p_in ) +{ + if( bs_remain( p_bs ) < 88 ) + return false; + + p_in->profile_space = bs_read( p_bs, 2 ); + p_in->tier_flag = bs_read1( p_bs ); + p_in->profile_idc = bs_read( p_bs, 5 ); + p_in->profile_compatibility_flag = bs_read( p_bs, 32 ); + p_in->progressive_source_flag = bs_read1( p_bs ); + p_in->interlaced_source_flag = bs_read1( p_bs ); + p_in->non_packed_constraint_flag = bs_read1( p_bs ); + p_in->frame_only_constraint_flag = bs_read1( p_bs ); + + if( ( p_in->profile_idc >= 4 && p_in->profile_idc <= 7 ) || + ( p_in->profile_compatibility_flag & 0x0F000000 ) ) + { + p_in->idc4to7.max_12bit_constraint_flag = bs_read1( p_bs ); + p_in->idc4to7.max_10bit_constraint_flag = bs_read1( p_bs ); + p_in->idc4to7.max_8bit_constraint_flag = bs_read1( p_bs ); + p_in->idc4to7.max_422chroma_constraint_flag = bs_read1( p_bs ); + p_in->idc4to7.max_420chroma_constraint_flag = bs_read1( p_bs ); + p_in->idc4to7.max_monochrome_constraint_flag = bs_read1( p_bs ); + p_in->idc4to7.intra_constraint_flag = bs_read1( p_bs ); + p_in->idc4to7.one_picture_only_constraint_flag = bs_read1( p_bs ); + p_in->idc4to7.lower_bit_rate_constraint_flag = bs_read1( p_bs ); + (void) bs_read( p_bs, 2 ); + } + else + { + (void) bs_read( p_bs, 11 ); + } + (void) bs_read( p_bs, 32 ); + + if( ( p_in->profile_idc >= 1 && p_in->profile_idc <= 5 ) || + ( p_in->profile_compatibility_flag & 0x7C000000 ) ) + p_in->idc1to5.inbld_flag = bs_read1( p_bs ); + else + (void) bs_read1( p_bs ); + + return true; +} + +static bool hevc_parse_profile_tier_level_rbsp( bs_t *p_bs, bool profile_present, + uint8_t max_num_sub_layers_minus1, + hevc_profile_tier_level_t *p_ptl ) +{ + if( profile_present && !hevc_parse_inner_profile_tier_level_rbsp( p_bs, &p_ptl->general ) ) + return false; + + if( bs_remain( p_bs ) < 8) + return false; + + p_ptl->general_level_idc = bs_read( p_bs, 8 ); + + if( max_num_sub_layers_minus1 > 0 ) + { + if( bs_remain( p_bs ) < 16 ) + return false; + + for( uint8_t i=0; i< 8; i++ ) + { + if( i < max_num_sub_layers_minus1 ) + { + if( bs_read1( p_bs ) ) + p_ptl->sublayer_profile_present_flag |= (0x80 >> i); + if( bs_read1( p_bs ) ) + p_ptl->sublayer_level_present_flag |= (0x80 >> i); + } + else + bs_read( p_bs, 2 ); + } + + for( uint8_t i=0; i < max_num_sub_layers_minus1; i++ ) + { + if( ( p_ptl->sublayer_profile_present_flag & (0x80 >> i) ) && + ! hevc_parse_inner_profile_tier_level_rbsp( p_bs, &p_ptl->sub_layer[i] ) ) + return false; + + if( p_ptl->sublayer_profile_present_flag & (0x80 >> i) ) + { + if( bs_remain( p_bs ) < 8 ) + return false; + p_ptl->sub_layer_level_idc[i] = bs_read( p_bs, 8 ); + } + } + } + + return true; +} _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
