[vlc-commits] hevc_nal: add profile_tier_level parser
Francois Cartegnie
git at videolan.org
Tue Dec 15 17:23:47 CET 2015
vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | 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;
+}
More information about the vlc-commits
mailing list