Commit d7242887 authored by François Cartegnie's avatar François Cartegnie 🤞

hevc_nal: add profile_tier_level parser

parent 66f3469f
......@@ -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;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment