Exemple #1
0
static void PutPPS( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    bs_t s;
    int i_pps_id;
    int i_sps_id;

    bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 );
    i_pps_id = bs_read_ue( &s ); // pps id
    i_sps_id = bs_read_ue( &s ); // sps id
    if( i_pps_id >= PPS_MAX || i_sps_id >= SPS_MAX )
    {
        msg_Warn( p_dec, "invalid PPS (pps_id=%d sps_id=%d)", i_pps_id, i_sps_id );
        block_Release( p_frag );
        return;
    }
    bs_skip( &s, 1 ); // entropy coding mode flag
    p_sys->i_pic_order_present_flag = bs_read( &s, 1 );
    /* TODO */

    /* We have a new PPS */
    if( !p_sys->b_pps )
        msg_Dbg( p_dec, "found NAL_PPS (pps_id=%d sps_id=%d)", i_pps_id, i_sps_id );
    p_sys->b_pps = true;

    if( p_sys->pp_pps[i_pps_id] )
        block_Release( p_sys->pp_pps[i_pps_id] );
    p_sys->pp_pps[i_pps_id] = p_frag;
}
Exemple #2
0
static int32_t getFPS( demux_t *p_demux, block_t * p_block )
{
    demux_sys_t *p_sys = p_demux->p_sys;

    bs_t bs;
    uint8_t * p_decoded_nal;
    int i_decoded_nal;

    if( p_block->i_buffer < 5 )
        return -1;

    p_decoded_nal = CreateDecodedNAL(&i_decoded_nal,
                                     p_block->p_buffer+4, p_block->i_buffer-4);

    if( !p_decoded_nal )
        return -1;

    bs_init( &bs, p_decoded_nal, i_decoded_nal );
    bs_skip( &bs, 12 );
    int32_t max_sub_layer_minus1 = bs_read( &bs, 3 );
    bs_skip( &bs, 17 );

    hevc_skip_profile_tiers_level( &bs, max_sub_layer_minus1 );

    int32_t vps_sub_layer_ordering_info_present_flag = bs_read1( &bs );
    int32_t i = vps_sub_layer_ordering_info_present_flag? 0 : max_sub_layer_minus1;
    for( ; i <= max_sub_layer_minus1; i++ )
    {
        bs_read_ue( &bs );
        bs_read_ue( &bs );
        bs_read_ue( &bs );
    }
    uint32_t vps_max_layer_id = bs_read( &bs, 6);
    uint32_t vps_num_layer_sets_minus1 = bs_read_ue( &bs );
    bs_skip( &bs, vps_max_layer_id * vps_num_layer_sets_minus1 );

    if( bs_read1( &bs ))
    {
        uint32_t num_units_in_tick = bs_read( &bs, 32 );
        uint32_t time_scale = bs_read( &bs, 32 );
        if( num_units_in_tick )
        {
            p_sys->f_fps = ( (float) time_scale )/( (float) num_units_in_tick );
            msg_Dbg(p_demux,"Using framerate %f fps from VPS",
                    (double) p_sys->f_fps);
        }
        else
        {
            msg_Err( p_demux, "vps_num_units_in_tick null defaulting to 25 fps");
            p_sys->f_fps = 25.0f;
        }
    }
    else
    {
        msg_Err( p_demux, "No timing info in VPS defaulting to 25 fps");
        p_sys->f_fps = 25.0f;
    }
    free(p_decoded_nal);
    return 0;
}
Exemple #3
0
static bool h264_parse_picture_parameter_set_rbsp( bs_t *p_bs,
                                                   h264_picture_parameter_set_t *p_pps )
{
    p_pps->i_id = bs_read_ue( p_bs ); // pps id
    p_pps->i_sps_id = bs_read_ue( p_bs ); // sps id
    if( p_pps->i_id >= H264_PPS_MAX || p_pps->i_sps_id >= H264_SPS_MAX )
        return false;

    bs_skip( p_bs, 1 ); // entropy coding mode flag
    p_pps->i_pic_order_present_flag = bs_read( p_bs, 1 );
    /* TODO */

    return true;
}
Exemple #4
0
// D.1.1 SEI buffering period syntax
static void read_sei_type_0(h264_stream_t* h, sei_t* s) {
    int sched_sel_idx;
    bs_t bs;
    sps_t *sps = h->sps;
    
    sei_type_0 *bp = malloc(sizeof(sei_type_0));
    
    bs_init(&bs, s->payload, s->payloadSize);
    
    bp->seq_parameter_set_id = bs_read_ue(&bs);
    
    if(sps->vui.nal_hrd_parameters_present_flag) {
        for (sched_sel_idx = 0; sched_sel_idx < sps->hrd.cpb_cnt_minus1 + 1; sched_sel_idx++) {
            bp->initial_cbp_removal_delay[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1);
            bp->initial_cbp_removal_delay_offset[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1);
        }
    }
    if (sps->vui.vcl_hrd_parameters_present_flag) {
        for (sched_sel_idx = 0; sched_sel_idx < sps->hrd.cpb_cnt_minus1 + 1; sched_sel_idx++) {
            bp->initial_cbp_removal_delay[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1);
            bp->initial_cbp_removal_delay_offset[sched_sel_idx] = bs_read_u(&bs, sps->hrd.initial_cpb_removal_delay_length_minus1 + 1);
        }
    }
    s->sei_type_struct = bp;
}
Exemple #5
0
static bool hevc_parse_scaling_list_rbsp( bs_t *p_bs )
{
    if( bs_remain( p_bs ) < 16 )
        return false;

    for( int i=0; i<4; i++ )
    {
        for( int j=0; j<6; j += (i == 3) ? 3 : 1 )
        {
            if( bs_read1( p_bs ) == 0 )
                bs_read_ue( p_bs );
            else
            {
                unsigned nextCoef = 8;
                unsigned coefNum = __MIN( 64, (1 << (4 + (i << 1))));
                if( i > 1 )
                {
                    nextCoef = bs_read_se( p_bs ) + 8;
                }
                for( unsigned k=0; k<coefNum; k++ )
                {
                    nextCoef = ( nextCoef + bs_read_se( p_bs ) + 256 ) % 256;
                }
            }
        }
    }

    return true;
}
bool 
h264MediaStream::h264_decode_hrd_parameters(bs_t& s, h264_sps_t* p_sps)
{
	int cpb_count, i;
	cpb_count = bs_read_ue(&s) + 1;
	bs_read(&s, 4); /* bit_rate_scale */
	bs_read(&s, 4); /* cpb_size_scale */
	for(i=0; i<cpb_count; i++){
		bs_read_ue(&s); /* bit_rate_value_minus1 */
		bs_read_ue(&s); /* cpb_size_value_minus1 */
		bs_read(&s, 1);     /* cbr_flag */
	}
	bs_read(&s, 5); /* initial_cpb_removal_delay_length_minus1 */
	bs_read(&s, 5); /* cpb_removal_delay_length_minus1 */
	bs_read(&s, 5); /* dpb_output_delay_length_minus1 */
	bs_read(&s, 5); /* time_offset_length */
	return true;
}
Exemple #7
0
//Appendix E.1.2 HRD parameters syntax
void read_hrd_parameters(sps_t *sps, bs_t* b)
{
	int SchedSelIdx;

	sps->hrd.cpb_cnt_minus1 = bs_read_ue(b);
	sps->hrd.bit_rate_scale = bs_read(b, 4);
	sps->hrd.cpb_size_scale = bs_read(b, 4);
	for (SchedSelIdx = 0; SchedSelIdx <= sps->hrd.cpb_cnt_minus1; SchedSelIdx++)
	{
		sps->hrd.bit_rate_value_minus1[SchedSelIdx] = bs_read_ue(b);
		sps->hrd.cpb_size_value_minus1[SchedSelIdx] = bs_read_ue(b);
		sps->hrd.cbr_flag[SchedSelIdx] = bs_read(b, 1);
	}
	sps->hrd.initial_cpb_removal_delay_length_minus1 = bs_read(b, 5);
	sps->hrd.cpb_removal_delay_length_minus1 = bs_read(b, 5);
	sps->hrd.dpb_output_delay_length_minus1 = bs_read(b, 5);
	sps->hrd.time_offset_length = bs_read(b, 5);
}
Exemple #8
0
int32_t bs_read_se(bs_t* b) 
{
    int32_t r = bs_read_ue(b);
    if (r & 0x01)
    {
        r = (r+1)/2;
    }
    else
    {
        r = -(r/2);
    }
    return r;
}
Exemple #9
0
int h264_parse_pps( const uint8_t *p_pps_buf, int i_pps_size,
                    struct nal_pps *p_pps )
{
    bs_t s;

    if (i_pps_size < 5 || (p_pps_buf[4] & 0x1f) != NAL_PPS)
        return -1;

    memset( p_pps, 0, sizeof(struct nal_pps) );
    bs_init( &s, &p_pps_buf[5], i_pps_size - 5 );
    p_pps->i_id = bs_read_ue( &s ); // pps id
    p_pps->i_sps_id = bs_read_ue( &s ); // sps id
    if( p_pps->i_id >= PPS_MAX || p_pps->i_sps_id >= SPS_MAX )
    {
        return -1;
    }
    bs_skip( &s, 1 ); // entropy coding mode flag
    p_pps->i_pic_order_present_flag = bs_read( &s, 1 );
    /* TODO */

    return 0;
}
Exemple #10
0
/* Shortcut for retrieving vps/sps/pps id */
bool hevc_get_xps_id(const uint8_t *p_buf, size_t i_buf, uint8_t *pi_id)
{
    if(unlikely(!hxxx_strip_AnnexB_startcode(&p_buf, &i_buf) || i_buf < 3))
        return false;
    /* No need to lookup convert from emulation for that data */
    uint8_t i_nal_type = hevc_getNALType(p_buf);
    bs_t bs;
    bs_init(&bs, &p_buf[2], i_buf - 2);
    if(i_nal_type == HEVC_NAL_PPS)
        *pi_id = bs_read_ue( &bs );
    else
        *pi_id = bs_read( &bs, 4 );

    return true;
}
Exemple #11
0
//7.3.2.1 Sequence parameter set RBSP syntax
void read_seq_parameter_set_rbsp(sps_t *sps, bs_t* b)
{
	int i;

	// NOTE can't read directly into sps because seq_parameter_set_id not yet known and so sps is not selected

	int profile_idc = bs_read(b, 8);
	int constraint_set0_flag = bs_read(b, 1);
	int constraint_set1_flag = bs_read(b, 1);
	int constraint_set2_flag = bs_read(b, 1);
	int constraint_set3_flag = bs_read(b, 1);
	int constraint_set4_flag = bs_read(b, 1);
	int constraint_set5_flag = bs_read(b, 1);
	int reserved_zero_2bits = bs_read(b, 2);  /* all 0's */
	int level_idc = bs_read(b, 8);
	int seq_parameter_set_id = bs_read_ue(b);

	memset(sps, 0, sizeof(sps_t));

	sps->chroma_format_idc = 1;

	sps->profile_idc = profile_idc; // bs_read(b, 8);
	sps->constraint_set0_flag = constraint_set0_flag;//bs_read(b, 1);
	sps->constraint_set1_flag = constraint_set1_flag;//bs_read(b, 1);
	sps->constraint_set2_flag = constraint_set2_flag;//bs_read(b, 1);
	sps->constraint_set3_flag = constraint_set3_flag;//bs_read(b, 1);
	sps->constraint_set4_flag = constraint_set4_flag;//bs_read(b, 1);
	sps->constraint_set5_flag = constraint_set5_flag;//bs_read(b, 1);
	sps->reserved_zero_2bits = reserved_zero_2bits;//bs_read(b,2);
	sps->level_idc = level_idc; //bs_read(b, 8);
	sps->seq_parameter_set_id = seq_parameter_set_id; // bs_read_ue(b);
	if (sps->profile_idc == 100 || sps->profile_idc == 110 ||
		sps->profile_idc == 122 || sps->profile_idc == 144)
	{
		sps->chroma_format_idc = bs_read_ue(b);
		if (sps->chroma_format_idc == 3)
		{
			sps->residual_colour_transform_flag = bs_read(b, 1);
		}
		sps->bit_depth_luma_minus8 = bs_read_ue(b);
		sps->bit_depth_chroma_minus8 = bs_read_ue(b);
		sps->qpprime_y_zero_transform_bypass_flag = bs_read(b, 1);
		sps->seq_scaling_matrix_present_flag = bs_read(b, 1);
		if (sps->seq_scaling_matrix_present_flag)
		{
			for (i = 0; i < 8; i++)
			{
				sps->seq_scaling_list_present_flag[i] = bs_read(b, 1);
				if (sps->seq_scaling_list_present_flag[i])
				{
					if (i < 6)
					{
						read_scaling_list(b, sps->ScalingList4x4[i], 16,
							sps->UseDefaultScalingMatrix4x4Flag[i]);
					}
					else
					{
						read_scaling_list(b, sps->ScalingList8x8[i - 6], 64,
							sps->UseDefaultScalingMatrix8x8Flag[i - 6]);
					}
				}
			}
		}
	}
	sps->log2_max_frame_num_minus4 = bs_read_ue(b);
	sps->pic_order_cnt_type = bs_read_ue(b);
	if (sps->pic_order_cnt_type == 0)
	{
		sps->log2_max_pic_order_cnt_lsb_minus4 = bs_read_ue(b);
	}
	else if (sps->pic_order_cnt_type == 1)
	{
		sps->delta_pic_order_always_zero_flag = bs_read(b, 1);
		sps->offset_for_non_ref_pic = bs_read_se(b);
		sps->offset_for_top_to_bottom_field = bs_read_se(b);
		sps->num_ref_frames_in_pic_order_cnt_cycle = bs_read_ue(b);
		for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
		{
			sps->offset_for_ref_frame[i] = bs_read_se(b);
		}
	}
	sps->num_ref_frames = bs_read_ue(b);
	sps->gaps_in_frame_num_value_allowed_flag = bs_read(b, 1);
	sps->pic_width_in_mbs_minus1 = bs_read_ue(b);
	sps->pic_height_in_map_units_minus1 = bs_read_ue(b);
	sps->frame_mbs_only_flag = bs_read(b, 1);
	if (!sps->frame_mbs_only_flag)
	{
		sps->mb_adaptive_frame_field_flag = bs_read(b, 1);
	}
	sps->direct_8x8_inference_flag = bs_read(b, 1);
	sps->frame_cropping_flag = bs_read(b, 1);
	if (sps->frame_cropping_flag)
	{
		sps->frame_crop_left_offset = bs_read_ue(b);
		sps->frame_crop_right_offset = bs_read_ue(b);
		sps->frame_crop_top_offset = bs_read_ue(b);
		sps->frame_crop_bottom_offset = bs_read_ue(b);
	}
	sps->vui_parameters_present_flag = bs_read(b, 1);
	if (sps->vui_parameters_present_flag)
	{
		read_vui_parameters(sps, b);
	}
	//read_rbsp_trailing_bits(h, b);
}
Exemple #12
0
//Appendix E.1.1 VUI parameters syntax
void read_vui_parameters(sps_t *sps, bs_t* b)
{
	sps->vui.aspect_ratio_info_present_flag = bs_read(b, 1);
	if (sps->vui.aspect_ratio_info_present_flag)
	{
		sps->vui.aspect_ratio_idc = bs_read(b, 8);
		if (sps->vui.aspect_ratio_idc == SAR_Extended)
		{
			sps->vui.sar_width = bs_read(b, 16);
			sps->vui.sar_height = bs_read(b, 16);
		}
	}
	sps->vui.overscan_info_present_flag = bs_read(b, 1);
	if (sps->vui.overscan_info_present_flag)
	{
		sps->vui.overscan_appropriate_flag = bs_read(b, 1);
	}
	sps->vui.video_signal_type_present_flag = bs_read(b, 1);
	if (sps->vui.video_signal_type_present_flag)
	{
		sps->vui.video_format = bs_read(b, 3);
		sps->vui.video_full_range_flag = bs_read(b, 1);
		sps->vui.colour_description_present_flag = bs_read(b, 1);
		if (sps->vui.colour_description_present_flag)
		{
			sps->vui.colour_primaries = bs_read(b, 8);
			sps->vui.transfer_characteristics = bs_read(b, 8);
			sps->vui.matrix_coefficients = bs_read(b, 8);
		}
	}
	sps->vui.chroma_loc_info_present_flag = bs_read(b, 1);
	if (sps->vui.chroma_loc_info_present_flag)
	{
		sps->vui.chroma_sample_loc_type_top_field = bs_read_ue(b);
		sps->vui.chroma_sample_loc_type_bottom_field = bs_read_ue(b);
	}
	sps->vui.timing_info_present_flag = bs_read(b, 1);
	if (sps->vui.timing_info_present_flag)
	{
		sps->vui.num_units_in_tick = bs_read(b, 32);
		sps->vui.time_scale = bs_read(b, 32);
		sps->vui.fixed_frame_rate_flag = bs_read(b, 1);
	}
	sps->vui.nal_hrd_parameters_present_flag = bs_read(b, 1);
	if (sps->vui.nal_hrd_parameters_present_flag)
	{
		read_hrd_parameters(sps, b);
	}
	sps->vui.vcl_hrd_parameters_present_flag = bs_read(b, 1);
	if (sps->vui.vcl_hrd_parameters_present_flag)
	{
		read_hrd_parameters(sps, b);
	}
	if (sps->vui.nal_hrd_parameters_present_flag || sps->vui.vcl_hrd_parameters_present_flag)
	{
		sps->vui.low_delay_hrd_flag = bs_read(b, 1);
	}
	sps->vui.pic_struct_present_flag = bs_read(b, 1);
	sps->vui.bitstream_restriction_flag = bs_read(b, 1);
	if (sps->vui.bitstream_restriction_flag)
	{
		sps->vui.motion_vectors_over_pic_boundaries_flag = bs_read(b, 1);
		sps->vui.max_bytes_per_pic_denom = bs_read_ue(b);
		sps->vui.max_bits_per_mb_denom = bs_read_ue(b);
		sps->vui.log2_max_mv_length_horizontal = bs_read_ue(b);
		sps->vui.log2_max_mv_length_vertical = bs_read_ue(b);
		sps->vui.num_reorder_frames = bs_read_ue(b);
		sps->vui.max_dec_frame_buffering = bs_read_ue(b);
	}
}
Exemple #13
0
void Parser::parse(int *pb_nal_start)
{
	h264_t *h = &h264;
    bs_t s;
    *pb_nal_start = 0;

    if( nal.i_type == NAL_SPS || nal.i_type == NAL_PPS )
        *pb_nal_start = 1;

    bs_init( &s, nal.p_payload, nal.i_payload );
    if( nal.i_type == NAL_SPS )
    {
        int i_tmp;

        i_tmp = bs_read( &s, 8 );
        bs_skip( &s, 1+1+1 + 5 + 8 );
        /* sps id */
        bs_read_ue( &s );

        if( i_tmp >= 100 )
        {
            b_hiprofile = 1;
			bs_read_ue( &s ); // chroma_format_idc
            bs_read_ue( &s ); // bit_depth_luma_minus8
            bs_read_ue( &s ); // bit_depth_chroma_minus8
            bs_skip( &s, 1 ); // qpprime_y_zero_transform_bypass_flag
            if( bs_read( &s, 1 ) ) // seq_scaling_matrix_present_flag
            {
                int i, j;
                for( i = 0; i < 8; i++ )
                {
                    if( bs_read( &s, 1 ) ) // seq_scaling_list_present_flag[i]
                    {
                        uint8 i_tmp = 8;
                        for( j = 0; j < (i<6?16:64); j++ )
                        {
                            i_tmp += bs_read_se( &s );
                            if( i_tmp == 0 )
                                break;
                        }
                    }
                }
            }
        }

        /* Skip i_log2_max_frame_num */
        h->i_log2_max_frame_num = bs_read_ue( &s ) + 4;
        /* Read poc_type */
        h->i_poc_type = bs_read_ue( &s );
        if( h->i_poc_type == 0 )
        {
            h->i_log2_max_poc_lsb = bs_read_ue( &s ) + 4;
        }
        else if( h->i_poc_type == 1 )
        {
            int i_cycle;
            /* skip b_delta_pic_order_always_zero */
            bs_skip( &s, 1 );
            /* skip i_offset_for_non_ref_pic */
            bs_read_se( &s );
            /* skip i_offset_for_top_to_bottom_field */
            bs_read_se( &s );
            /* read i_num_ref_frames_in_poc_cycle */
            i_cycle = bs_read_ue( &s ); 
            if( i_cycle > 256 ) i_cycle = 256;
            while( i_cycle > 0 )
            {
                /* skip i_offset_for_ref_frame */
                bs_read_se(&s );
            }
        }
        /* i_num_ref_frames */
        bs_read_ue( &s );
        /* b_gaps_in_frame_num_value_allowed */
        bs_skip( &s, 1 );

        /* Read size */
        h->i_width  = 16 * ( bs_read_ue( &s ) + 1 );
        h->i_height = 32 * ( bs_read_ue( &s ) + 1 );

        /* b_frame_mbs_only */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp == 1 )
        {
			// fix: progressive, half height
			h->i_height /= 2;
		}
		else
		{
			// mb_adaptive_frame_field_flag
            bs_skip( &s, 1 );
        }
        /* b_direct8x8_inference */
        bs_skip( &s, 1 );

        /* crop ? */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
			// fix: no cropping

            /* left */
            //h->i_width -= 2 * bs_read_ue( &s );
            /* right */
            //h->i_width -= 2 * bs_read_ue( &s );
            /* top */
            //h->i_height -= 2 * bs_read_ue( &s );
            /* bottom */
            //h->i_height -= 2 * bs_read_ue( &s );
        }

        /* vui: ignored */
    }
    else if( nal.i_type >= NAL_SLICE && nal.i_type <= NAL_SLICE_IDR )
    {
        int i_tmp;

        /* i_first_mb */
        bs_read_ue( &s );
        /* picture type */
        switch( bs_read_ue( &s ) )
        {
            case 0: case 5: /* P */
            case 1: case 6: /* B */
            case 3: case 8: /* SP */
                h->b_key = 0;
                break;
            case 2: case 7: /* I */
            case 4: case 9: /* SI */
				// fix: key flags in high profile
                h->b_key = (nal.i_type == NAL_SLICE_IDR || (b_hiprofile && nal.i_type == NAL_SLICE));
                break;
        }
        /* pps id */
        bs_read_ue( &s );

        /* frame num */
        i_tmp = bs_read( &s, h->i_log2_max_frame_num );

        if( i_tmp != h->i_frame_num )
            *pb_nal_start = 1;

        h->i_frame_num = i_tmp;

        if( nal.i_type == NAL_SLICE_IDR )
        {
            i_tmp = bs_read_ue( &s );
            if( h->i_nal_type == NAL_SLICE_IDR && h->i_idr_pic_id != i_tmp )
                *pb_nal_start = 1;

            h->i_idr_pic_id = i_tmp;
        }

        if( h->i_poc_type == 0 )
        {
            i_tmp = bs_read( &s, h->i_log2_max_poc_lsb );
            if( i_tmp != h->i_poc )
                *pb_nal_start = 1;
            h->i_poc = i_tmp;
        }
    }
    h->i_nal_type = nal.i_type;
    h->i_ref_idc = nal.i_ref_idc;
}
Exemple #14
0
static bool h264_parse_sequence_parameter_set_rbsp( bs_t *p_bs,
                                                    h264_sequence_parameter_set_t *p_sps )
{
    int i_tmp;

    int i_profile_idc = bs_read( p_bs, 8 );
    p_sps->i_profile = i_profile_idc;
    p_sps->i_constraint_set_flags = bs_read( p_bs, 8 );
    p_sps->i_level = bs_read( p_bs, 8 );
    /* sps id */
    uint32_t i_sps_id = bs_read_ue( p_bs );
    if( i_sps_id > H264_SPS_ID_MAX )
        return false;
    p_sps->i_id = i_sps_id;

    if( i_profile_idc == PROFILE_H264_HIGH ||
        i_profile_idc == PROFILE_H264_HIGH_10 ||
        i_profile_idc == PROFILE_H264_HIGH_422 ||
        i_profile_idc == PROFILE_H264_HIGH_444 || /* Old one, no longer on spec */
        i_profile_idc == PROFILE_H264_HIGH_444_PREDICTIVE ||
        i_profile_idc == PROFILE_H264_CAVLC_INTRA ||
        i_profile_idc == PROFILE_H264_SVC_BASELINE ||
        i_profile_idc == PROFILE_H264_SVC_HIGH ||
        i_profile_idc == PROFILE_H264_MVC_MULTIVIEW_HIGH ||
        i_profile_idc == PROFILE_H264_MVC_STEREO_HIGH ||
        i_profile_idc == PROFILE_H264_MVC_MULTIVIEW_DEPTH_HIGH ||
        i_profile_idc == PROFILE_H264_MVC_ENHANCED_MULTIVIEW_DEPTH_HIGH ||
        i_profile_idc == PROFILE_H264_MFC_HIGH )
    {
        /* chroma_format_idc */
        p_sps->i_chroma_idc = bs_read_ue( p_bs );
        if( p_sps->i_chroma_idc == 3 )
            bs_skip( p_bs, 1 ); /* separate_colour_plane_flag */
        /* bit_depth_luma_minus8 */
        p_sps->i_bit_depth_luma = bs_read_ue( p_bs ) + 8;
        /* bit_depth_chroma_minus8 */
        p_sps->i_bit_depth_chroma = bs_read_ue( p_bs ) + 8;
        /* qpprime_y_zero_transform_bypass_flag */
        bs_skip( p_bs, 1 );
        /* seq_scaling_matrix_present_flag */
        i_tmp = bs_read( p_bs, 1 );
        if( i_tmp )
        {
            for( int i = 0; i < ((3 != p_sps->i_chroma_idc) ? 8 : 12); i++ )
            {
                /* seq_scaling_list_present_flag[i] */
                i_tmp = bs_read( p_bs, 1 );
                if( !i_tmp )
                    continue;
                const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64;
                /* scaling_list (...) */
                int i_lastscale = 8;
                int i_nextscale = 8;
                for( int j = 0; j < i_size_of_scaling_list; j++ )
                {
                    if( i_nextscale != 0 )
                    {
                        /* delta_scale */
                        i_tmp = bs_read_se( p_bs );
                        i_nextscale = ( i_lastscale + i_tmp + 256 ) % 256;
                        /* useDefaultScalingMatrixFlag = ... */
                    }
                    /* scalinglist[j] */
                    i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale;
                }
            }
        }
    }

    /* Skip i_log2_max_frame_num */
    p_sps->i_log2_max_frame_num = bs_read_ue( p_bs );
    if( p_sps->i_log2_max_frame_num > 12)
        p_sps->i_log2_max_frame_num = 12;
    /* Read poc_type */
    p_sps->i_pic_order_cnt_type = bs_read_ue( p_bs );
    if( p_sps->i_pic_order_cnt_type == 0 )
    {
        /* skip i_log2_max_poc_lsb */
        p_sps->i_log2_max_pic_order_cnt_lsb = bs_read_ue( p_bs );
        if( p_sps->i_log2_max_pic_order_cnt_lsb > 12 )
            p_sps->i_log2_max_pic_order_cnt_lsb = 12;
    }
    else if( p_sps->i_pic_order_cnt_type == 1 )
    {
        int i_cycle;
        /* skip b_delta_pic_order_always_zero */
        p_sps->i_delta_pic_order_always_zero_flag = bs_read( p_bs, 1 );
        /* skip i_offset_for_non_ref_pic */
        bs_read_se( p_bs );
        /* skip i_offset_for_top_to_bottom_field */
        bs_read_se( p_bs );
        /* read i_num_ref_frames_in_poc_cycle */
        i_cycle = bs_read_ue( p_bs );
        if( i_cycle > 256 ) i_cycle = 256;
        while( i_cycle > 0 )
        {
            /* skip i_offset_for_ref_frame */
            bs_read_se(p_bs );
            i_cycle--;
        }
    }
    /* i_num_ref_frames */
    bs_read_ue( p_bs );
    /* b_gaps_in_frame_num_value_allowed */
    bs_skip( p_bs, 1 );

    /* Read size */
    p_sps->pic_width_in_mbs_minus1 = bs_read_ue( p_bs );
    p_sps->pic_height_in_map_units_minus1 = bs_read_ue( p_bs );

    /* b_frame_mbs_only */
    p_sps->frame_mbs_only_flag = bs_read( p_bs, 1 );
    if( !p_sps->frame_mbs_only_flag )
        bs_skip( p_bs, 1 );

    /* b_direct8x8_inference */
    bs_skip( p_bs, 1 );

    /* crop */
    if( bs_read1( p_bs ) ) /* frame_cropping_flag */
    {
        p_sps->frame_crop.left_offset = bs_read_ue( p_bs );
        p_sps->frame_crop.right_offset = bs_read_ue( p_bs );
        p_sps->frame_crop.right_offset = bs_read_ue( p_bs );
        p_sps->frame_crop.bottom_offset = bs_read_ue( p_bs );
    }

    /* vui */
    i_tmp = bs_read( p_bs, 1 );
    if( i_tmp )
    {
        p_sps->vui.b_valid = true;
        /* read the aspect ratio part if any */
        i_tmp = bs_read( p_bs, 1 );
        if( i_tmp )
        {
            static const struct { int w, h; } sar[17] =
            {
                { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                { 64, 33 }, { 160,99 }, {  4,  3 }, {  3,  2 },
                {  2,  1 },
            };
            int i_sar = bs_read( p_bs, 8 );
            int w, h;

            if( i_sar < 17 )
            {
                w = sar[i_sar].w;
                h = sar[i_sar].h;
            }
            else if( i_sar == 255 )
            {
                w = bs_read( p_bs, 16 );
                h = bs_read( p_bs, 16 );
            }
            else
            {
                w = 0;
                h = 0;
            }

            if( w != 0 && h != 0 )
            {
                p_sps->vui.i_sar_num = w;
                p_sps->vui.i_sar_den = h;
            }
            else
            {
                p_sps->vui.i_sar_num = 1;
                p_sps->vui.i_sar_den = 1;
            }
        }

        /* overscan */
        i_tmp = bs_read( p_bs, 1 );
        if ( i_tmp )
            bs_read( p_bs, 1 );

        /* video signal type */
        i_tmp = bs_read( p_bs, 1 );
        if( i_tmp )
        {
            bs_read( p_bs, 3 );
            p_sps->vui.colour.b_full_range = bs_read( p_bs, 1 );
            /* colour desc */
            i_tmp = bs_read( p_bs, 1 );
            if ( i_tmp )
            {
                p_sps->vui.colour.i_colour_primaries = bs_read( p_bs, 8 );
                p_sps->vui.colour.i_transfer_characteristics = bs_read( p_bs, 8 );
                p_sps->vui.colour.i_matrix_coefficients = bs_read( p_bs, 8 );
            }
            else
            {
                p_sps->vui.colour.i_colour_primaries = HXXX_PRIMARIES_UNSPECIFIED;
                p_sps->vui.colour.i_transfer_characteristics = HXXX_TRANSFER_UNSPECIFIED;
                p_sps->vui.colour.i_matrix_coefficients = HXXX_MATRIX_UNSPECIFIED;
            }
        }

        /* chroma loc info */
        i_tmp = bs_read( p_bs, 1 );
        if( i_tmp )
        {
            bs_read_ue( p_bs );
            bs_read_ue( p_bs );
        }

        /* timing info */
        p_sps->vui.b_timing_info_present_flag = bs_read( p_bs, 1 );
        if( p_sps->vui.b_timing_info_present_flag )
        {
            p_sps->vui.i_num_units_in_tick = bs_read( p_bs, 32 );
            p_sps->vui.i_time_scale = bs_read( p_bs, 32 );
            p_sps->vui.b_fixed_frame_rate = bs_read( p_bs, 1 );
        }

        /* Nal hrd & VC1 hrd parameters */
        p_sps->vui.b_hrd_parameters_present_flag = false;
        for ( int i=0; i<2; i++ )
        {
            i_tmp = bs_read( p_bs, 1 );
            if( i_tmp )
            {
                p_sps->vui.b_hrd_parameters_present_flag = true;
                uint32_t count = bs_read_ue( p_bs ) + 1;
                if( count > 31 )
                    return false;
                bs_read( p_bs, 4 );
                bs_read( p_bs, 4 );
                for( uint32_t i=0; i<count; i++ )
                {
                    if( bs_remain( p_bs ) < 23 )
                        return false;
                    bs_read_ue( p_bs );
                    bs_read_ue( p_bs );
                    bs_read( p_bs, 1 );
                }
                bs_read( p_bs, 5 );
                p_sps->vui.i_cpb_removal_delay_length_minus1 = bs_read( p_bs, 5 );
                p_sps->vui.i_dpb_output_delay_length_minus1 = bs_read( p_bs, 5 );
                bs_read( p_bs, 5 );
            }
        }

        if( p_sps->vui.b_hrd_parameters_present_flag )
            bs_read( p_bs, 1 );

        /* pic struct info */
        p_sps->vui.b_pic_struct_present_flag = bs_read( p_bs, 1 );

        /* + unparsed remains */
    }

    return true;
}
Exemple #15
0
static void ParseSlice( decoder_t *p_dec, bool *pb_new_picture, slice_t *p_slice,
                        int i_nal_ref_idc, int i_nal_type, const block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    uint8_t *pb_dec;
    int i_dec;
    int i_slice_type;
    slice_t slice;
    bs_t s;

    /* do not convert the whole frame */
    CreateDecodedNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5],
                     __MIN( p_frag->i_buffer - 5, 60 ) );
    bs_init( &s, pb_dec, i_dec );

    /* first_mb_in_slice */
    /* int i_first_mb = */ bs_read_ue( &s );

    /* slice_type */
    switch( (i_slice_type = bs_read_ue( &s )) )
    {
    case 0: case 5:
        slice.i_frame_type = BLOCK_FLAG_TYPE_P;
        break;
    case 1: case 6:
        slice.i_frame_type = BLOCK_FLAG_TYPE_B;
        break;
    case 2: case 7:
        slice.i_frame_type = BLOCK_FLAG_TYPE_I;
        break;
    case 3: case 8: /* SP */
        slice.i_frame_type = BLOCK_FLAG_TYPE_P;
        break;
    case 4: case 9:
        slice.i_frame_type = BLOCK_FLAG_TYPE_I;
        break;
    default:
        slice.i_frame_type = 0;
        break;
    }

    /* */
    slice.i_nal_type = i_nal_type;
    slice.i_nal_ref_idc = i_nal_ref_idc;

    slice.i_pic_parameter_set_id = bs_read_ue( &s );
    slice.i_frame_num = bs_read( &s, p_sys->i_log2_max_frame_num + 4 );

    slice.i_field_pic_flag = 0;
    slice.i_bottom_field_flag = -1;
    if( !p_sys->b_frame_mbs_only )
    {
        /* field_pic_flag */
        slice.i_field_pic_flag = bs_read( &s, 1 );
        if( slice.i_field_pic_flag )
            slice.i_bottom_field_flag = bs_read( &s, 1 );
    }

    slice.i_idr_pic_id = p_sys->slice.i_idr_pic_id;
    if( slice.i_nal_type == NAL_SLICE_IDR )
        slice.i_idr_pic_id = bs_read_ue( &s );

    slice.i_pic_order_cnt_lsb = -1;
    slice.i_delta_pic_order_cnt_bottom = -1;
    slice.i_delta_pic_order_cnt0 = 0;
    slice.i_delta_pic_order_cnt1 = 0;
    if( p_sys->i_pic_order_cnt_type == 0 )
    {
        slice.i_pic_order_cnt_lsb = bs_read( &s, p_sys->i_log2_max_pic_order_cnt_lsb + 4 );
        if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag )
            slice.i_delta_pic_order_cnt_bottom = bs_read_se( &s );
    }
    else if( (p_sys->i_pic_order_cnt_type == 1) &&
             (!p_sys->i_delta_pic_order_always_zero_flag) )
    {
        slice.i_delta_pic_order_cnt0 = bs_read_se( &s );
        if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag )
            slice.i_delta_pic_order_cnt1 = bs_read_se( &s );
    }
    free( pb_dec );

    /* Detection of the first VCL NAL unit of a primary coded picture
     * (cf. 7.4.1.2.4) */
    bool b_pic = false;
    if( slice.i_frame_num != p_sys->slice.i_frame_num ||
        slice.i_pic_parameter_set_id != p_sys->slice.i_pic_parameter_set_id ||
        slice.i_field_pic_flag != p_sys->slice.i_field_pic_flag ||
        slice.i_nal_ref_idc != p_sys->slice.i_nal_ref_idc )
        b_pic = true;
    if( (slice.i_bottom_field_flag != -1) &&
        (p_sys->slice.i_bottom_field_flag != -1) &&
        (slice.i_bottom_field_flag != p_sys->slice.i_bottom_field_flag) )
        b_pic = true;
    if( p_sys->i_pic_order_cnt_type == 0 &&
        ( slice.i_pic_order_cnt_lsb != p_sys->slice.i_pic_order_cnt_lsb ||
          slice.i_delta_pic_order_cnt_bottom != p_sys->slice.i_delta_pic_order_cnt_bottom ) )
        b_pic = true;
    else if( p_sys->i_pic_order_cnt_type == 1 &&
             ( slice.i_delta_pic_order_cnt0 != p_sys->slice.i_delta_pic_order_cnt0 ||
               slice.i_delta_pic_order_cnt1 != p_sys->slice.i_delta_pic_order_cnt1 ) )
        b_pic = true;
    if( ( slice.i_nal_type == NAL_SLICE_IDR || p_sys->slice.i_nal_type == NAL_SLICE_IDR ) &&
        ( slice.i_nal_type != p_sys->slice.i_nal_type || slice.i_idr_pic_id != p_sys->slice.i_idr_pic_id ) )
            b_pic = true;

    /* */
    *pb_new_picture = b_pic;
    *p_slice = slice;
}
void 
h264MediaStream::ParseSlice(uint8_t* p_nal,  int n_nal_size, int i_nal_type)
{	
	
	if(CurSlice == NULL)
		CurSlice = new h264_slice_t;
	//转化00 00 03为00 00
	int icount = 0;
	uint8_t p_slice[64] = {0};
	int parcount = (n_nal_size>64?64:n_nal_size);
	for (int t = 0; t < parcount; t++)
	{
		if (t < parcount-2 && p_nal[t] == 0x00 && p_nal[t + 1] == 0x00 && p_nal[t + 2] == 0x03)
		{
			p_slice[icount++] = 0x00;
			p_slice[icount++] = 0x00;
			t += 2;
			continue;
		}
		p_slice[icount++] = p_nal[t];
	}
	
	


	bs_t s;
	bs_init(&s, p_slice, icount);

	bs_read_ue( &s );	// first_mb_in_slice
	CurSlice->i_slice_type = bs_read_ue( &s );	// slice type

	int i_pic_parameter_set_id = bs_read_ue( &s );
	CurSlice->i_frame_num = bs_read( &s, StreamSps->log2_max_frame_num + 4 );

	int i_field_pic_flag = 0;
	int i_bottom_field_flag = -1;
	if( !StreamSps->frame_mbs_only_flag)
	{
		/* field_pic_flag */
		i_field_pic_flag = bs_read( &s, 1 );
		if( i_field_pic_flag )
			i_bottom_field_flag = bs_read( &s, 1 );
	}

	int i_idr_pic_id;
	if( i_nal_type == 5/*NAL_SLICE_IDR*/ )
		i_idr_pic_id = bs_read_ue( &s );

	int i_delta_pic_order_cnt_bottom = -1;
	int i_delta_pic_order_cnt0 = 0;
	int i_delta_pic_order_cnt1 = 0;

	CurSlice->i_pic_order_cnt_lsb = 0;

	if( StreamSps->poc_type == 0 )
	{
		CurSlice->i_pic_order_cnt_lsb = bs_read( &s, StreamSps->log2_max_poc_lsb + 4 );
		//if( g_pic_order_present_flag && !i_field_pic_flag )
		//	i_delta_pic_order_cnt_bottom = bs_read_se( &s );
	}
	else if( (StreamSps->poc_type == 1) &&
		(!StreamSps->delta_pic_order_always_zero_flag) )
	{
		i_delta_pic_order_cnt0 = bs_read_se( &s );
		//if( g_pic_order_present_flag && !i_field_pic_flag )
		//	i_delta_pic_order_cnt1 = bs_read_se( &s );
	}
}
bool 
h264MediaStream::ParseSqs(const buf_share_ptr SqsNode)
{
	assert(SqsNode);

	if (StreamSps == NULL)
		StreamSps = new h264_sps_t;
	uint8_t *pb_dec = NULL;
	int     i_dec = 0;
	bs_t s;
	int i_sps_id;
	i_dec = SqsNode->GetSizeValue(); 
	int nal_hrd_parameters_present_flag, vcl_hrd_parameters_present_flag;
	pb_dec = const_cast<uint8_t *>(SqsNode->GetBuffer());

	//转化00 00 03为00 00


	uint8_t *p_nal = new uint8_t[i_dec];
	int pcount = 0;
	for (int tmp = 1; tmp < i_dec ; tmp++)
	{
		if (tmp < i_dec - 3 && *(pb_dec + tmp) == 0x00 && 
			*(pb_dec + tmp + 1) == 0x00 && *(pb_dec + tmp + 2) == 0x03)
		{
			p_nal[pcount++] = 0x00;
			p_nal[pcount++] = 0x00;
			//printf("count = %d %2X\n",tmp, *(p_nal + tmp));
			tmp += 2;
			continue;
		}
		p_nal[pcount++] = *(pb_dec + tmp);
	}
	pb_dec = p_nal;

	//以下内容根据H264协议解读,属于直接复制粘贴代码 同parseslice

	bs_init( &s, pb_dec, i_dec );
	// profile(8)
	StreamSps->profile_idc = bs_read( &s, 8);

	/* constraint_set012, reserver(5), level(8) */
	bs_skip( &s, 1+1+1 + 5 + 8 );
	/* sps id */
	i_sps_id = bs_read_ue( &s );
	if( i_sps_id >= 32/*SPS_MAX*/ )
	{
		printf("invalid SPS (sps_id=%d)", i_sps_id );
		delete pb_dec;
		return false;
	}

	StreamSps->scaling_matrix_present = 0;
	if(StreamSps->profile_idc >= 100)		//high profile
	{ 
		if(bs_read_ue(&s) == 3)			//chroma_format_idc
			bs_read(&s, 1);				//residual_color_transform_flag
		bs_read_ue(&s);					//bit_depth_luma_minus8
		bs_read_ue(&s);					//bit_depth_chroma_minus8
		StreamSps->transform_bypass = bs_read(&s, 1);
		bs_skip(&s, 1); //decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8);
	}

	/* Skip i_log2_max_frame_num */
	StreamSps->log2_max_frame_num = bs_read_ue( &s );
	if( StreamSps->log2_max_frame_num > 12)
		StreamSps->log2_max_frame_num = 12;
	/* Read poc_type */
	StreamSps->poc_type/*->i_pic_order_cnt_type*/ = bs_read_ue( &s );
	if( StreamSps->poc_type == 0 )
	{
		/* skip i_log2_max_poc_lsb */
		StreamSps->log2_max_poc_lsb/*->i_log2_max_pic_order_cnt_lsb*/ = bs_read_ue( &s );
		if( StreamSps->log2_max_poc_lsb > 12 )
			StreamSps->log2_max_poc_lsb = 12;
	}
	else if( StreamSps->poc_type/*p_sys->i_pic_order_cnt_type*/ == 1 )
	{
		int i_cycle;
		/* skip b_delta_pic_order_always_zero */
		StreamSps->delta_pic_order_always_zero_flag/*->i_delta_pic_order_always_zero_flag*/ = bs_read( &s, 1 );
		/* skip i_offset_for_non_ref_pic */
		bs_read_se( &s );
		/* skip i_offset_for_top_to_bottom_field */
		bs_read_se( &s );
		/* read i_num_ref_frames_in_poc_cycle */
		i_cycle = bs_read_ue( &s );
		if( i_cycle > 256 ) i_cycle = 256;
		while( i_cycle > 0 )
		{
			/* skip i_offset_for_ref_frame */
			bs_read_se(&s );
			i_cycle--;
		}
	}
	/* i_num_ref_frames */
	bs_read_ue( &s );
	/* b_gaps_in_frame_num_value_allowed */
	bs_skip( &s, 1 );

	/* Read size */
	StreamSps->mb_width/*->fmt_out.video.i_width*/  = 16 * ( bs_read_ue( &s ) + 1 );
	StreamSps->mb_height/*fmt_out.video.i_height*/ = 16 * ( bs_read_ue( &s ) + 1 );

	/* b_frame_mbs_only */
	StreamSps->frame_mbs_only_flag/*->b_frame_mbs_only*/ = bs_read( &s, 1 );
	if( StreamSps->frame_mbs_only_flag == 0 )
	{
		bs_skip( &s, 1 );
	}
	/* b_direct8x8_inference */
	bs_skip( &s, 1 );

	/* crop */
	StreamSps->crop = bs_read( &s, 1 );
	if( StreamSps->crop )
	{
		/* left */
		bs_read_ue( &s );
		/* right */
		bs_read_ue( &s );
		/* top */
		bs_read_ue( &s );
		/* bottom */
		bs_read_ue( &s );
	}

	/* vui */
	StreamSps->vui_parameters_present_flag = bs_read( &s, 1 );
	if( StreamSps->vui_parameters_present_flag )
	{
		int aspect_ratio_info_present_flag = bs_read( &s, 1 );
		if( aspect_ratio_info_present_flag )
		{
			static const struct { int num, den; } sar[17] =
			{
				{ 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
				{ 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
				{ 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
				{ 64, 33 }, { 160,99 }, {  4,  3 }, {  3,  2 },
				{  2,  1 },
			};

			int i_sar = bs_read( &s, 8 );

			if( i_sar < 17 )
			{
				StreamSps->sar.num = sar[i_sar].num;
				StreamSps->sar.den = sar[i_sar].den;
			}
			else if( i_sar == 255 )
			{
				StreamSps->sar.num = bs_read( &s, 16 );
				StreamSps->sar.den = bs_read( &s, 16 );
			}
			else
			{
				StreamSps->sar.num = 0;
				StreamSps->sar.den = 0;
			}

			//if( den != 0 )
			//	p_dec->fmt_out.video.i_aspect = (int64_t)VOUT_ASPECT_FACTOR *
			//	( num * p_dec->fmt_out.video.i_width ) /
			//	( den * p_dec->fmt_out.video.i_height);
			//else
			//	p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR;
		}
		else
		{
			StreamSps->sar.num = 0;
			StreamSps->sar.den = 0;
		}

		if(bs_read(&s, 1))		/* overscan_info_present_flag */
		{
			bs_read(&s, 1);     /* overscan_appropriate_flag */
		}

		if(bs_read(&s, 1))		/* video_signal_type_present_flag */
		{      
			bs_read(&s, 3);		/* video_format */
			bs_read(&s, 1);     /* video_full_range_flag */

			if(bs_read(&s, 1))  /* colour_description_present_flag */
			{
				bs_read(&s, 8);	/* colour_primaries */
				bs_read(&s, 8); /* transfer_characteristics */
				bs_read(&s, 8); /* matrix_coefficients */
			}
		}

		if(bs_read(&s, 1))		/* chroma_location_info_present_flag */
		{
			bs_read_ue(&s);		/* chroma_sample_location_type_top_field */
			bs_read_ue(&s);		/* chroma_sample_location_type_bottom_field */
		}

		StreamSps->timing_info_present_flag = bs_read(&s, 1);
		if(StreamSps->timing_info_present_flag)
		{
			StreamSps->num_units_in_tick = bs_read(&s, 32);
			StreamSps->time_scale = bs_read(&s, 32);
			StreamSps->fixed_frame_rate_flag = bs_read(&s, 1);
		}

		nal_hrd_parameters_present_flag = bs_read(&s, 1);
		if(nal_hrd_parameters_present_flag)
			h264_decode_hrd_parameters(s, StreamSps);
		vcl_hrd_parameters_present_flag = bs_read(&s, 1);
		if(vcl_hrd_parameters_present_flag)
			h264_decode_hrd_parameters(s, StreamSps);
		if(nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag)
			bs_read(&s, 1);     /* low_delay_hrd_flag */
		bs_read(&s, 1);         /* pic_struct_present_flag */

		StreamSps->bitstream_restriction_flag = bs_read(&s, 1);
		if(StreamSps->bitstream_restriction_flag)
		{
			unsigned int num_reorder_frames;
			bs_read(&s, 1);     /* motion_vectors_over_pic_boundaries_flag */
			bs_read_ue(&s); /* max_bytes_per_pic_denom */
			bs_read_ue(&s); /* max_bits_per_mb_denom */
			bs_read_ue(&s); /* log2_max_mv_length_horizontal */
			bs_read_ue(&s); /* log2_max_mv_length_vertical */
			num_reorder_frames= bs_read_ue(&s);
			bs_read_ue(&s); /*max_dec_frame_buffering*/

			if(num_reorder_frames > 16 /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){
				printf("illegal num_reorder_frames %d\n", num_reorder_frames);
				delete pb_dec;
				return true;
			}

			StreamSps->num_reorder_frames= num_reorder_frames;
		}
	}
	delete pb_dec;
	return true;
}
Exemple #18
0
static block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_pic = NULL;

    const int i_nal_ref_idc = (p_frag->p_buffer[3] >> 5)&0x03;
    const int i_nal_type = p_frag->p_buffer[3]&0x1f;

    if( p_sys->b_slice && !p_sys->b_sps )
    {
        block_ChainRelease( p_sys->p_frame );
        msg_Warn( p_dec, "waiting for SPS" );

        /* Reset context */
        p_sys->p_frame = NULL;
        p_sys->b_slice = VLC_FALSE;
    }

    if( !p_sys->b_sps &&
            i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
    {
        p_sys->b_slice = VLC_TRUE;
        /* Fragment will be discarded later on */
    }
    else if( i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
    {
        uint8_t *dec;
        int i_dec, i_first_mb, i_slice_type, i_frame_num, i_pic_flags = 0;
        vlc_bool_t b_pic = VLC_FALSE;
        bs_t s;

        /* do not convert the whole frame */
        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4],
                         __MIN( p_frag->i_buffer - 4, 60 ) );
        bs_init( &s, dec, i_dec );

        /* first_mb_in_slice */
        i_first_mb = bs_read_ue( &s );

        /* slice_type */
        switch( (i_slice_type = bs_read_ue( &s )) )
        {
        case 0:
        case 5:
            i_pic_flags = BLOCK_FLAG_TYPE_P;
            break;
        case 1:
        case 6:
            i_pic_flags = BLOCK_FLAG_TYPE_B;
            break;
        case 2:
        case 7:
            i_pic_flags = BLOCK_FLAG_TYPE_I;
            break;
        case 3:
        case 8: /* SP */
            i_pic_flags = BLOCK_FLAG_TYPE_P;
            break;
        case 4:
        case 9:
            i_pic_flags = BLOCK_FLAG_TYPE_I;
            break;
        }

        /* pic_parameter_set_id */
        bs_read_ue( &s );
        /* frame_num */
        i_frame_num = bs_read( &s, p_sys->i_log2_max_frame_num + 4 );

        /* Detection of the first VCL NAL unit of a primary coded picture
         * (cf. 7.4.1.2.4) */
        if( i_frame_num != p_sys->i_frame_num ||
                ( (i_nal_ref_idc != p_sys->i_nal_ref_idc) &&
                  (!i_nal_ref_idc || !p_sys->i_nal_ref_idc) ) )
        {
            b_pic = VLC_TRUE;
        }
        p_sys->i_frame_num = i_frame_num;
        p_sys->i_nal_ref_idc = i_nal_ref_idc;

        if( !p_sys->b_frame_mbs_only )
        {
            /* field_pic_flag */
            if( bs_read( &s, 1 ) )
            {
                /* bottom_field_flag */
                bs_read( &s, 1 );
            }
        }

        if( i_nal_type == NAL_SLICE_IDR )
        {
            /* id_pic_id */
            int i_idr_pic_id = bs_read_ue( &s );
            if( p_sys->i_nal_type != i_nal_type ) b_pic = VLC_TRUE;
            if( p_sys->i_idr_pic_id != i_idr_pic_id ) b_pic = VLC_TRUE;
            p_sys->i_idr_pic_id = i_idr_pic_id;
        }
        p_sys->i_nal_type = i_nal_type;

        if( b_pic && p_sys->b_slice )
        {
            p_pic = block_ChainGather( p_sys->p_frame );
            p_pic->i_dts = p_sys->i_dts;
            p_pic->i_pts = p_sys->i_pts;
            p_pic->i_length = 0;    /* FIXME */
            p_pic->i_flags = p_sys->i_flags;

            /* Reset context */
            p_sys->p_frame = NULL;
            p_sys->b_slice = VLC_FALSE;
        }

        p_sys->b_slice = VLC_TRUE;
        p_sys->i_flags = i_pic_flags;
        p_sys->i_dts   = p_frag->i_dts;
        p_sys->i_pts   = p_frag->i_pts;

        free( dec );
    }
    else if( i_nal_type == NAL_SPS )
    {
        uint8_t *dec;
        int     i_dec;
        bs_t s;
        int i_tmp;

        msg_Dbg( p_dec, "found NAL_SPS" );

        p_sys->b_sps = VLC_TRUE;

        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[4],
                         p_frag->i_buffer - 4 );

        bs_init( &s, dec, i_dec );
        /* Skip profile(8), constraint_set012, reserver(5), level(8) */
        bs_skip( &s, 8 + 1+1+1 + 5 + 8 );
        /* sps id */
        bs_read_ue( &s );
        /* Skip i_log2_max_frame_num */
        p_sys->i_log2_max_frame_num = bs_read_ue( &s );
        /* Read poc_type */
        i_tmp = bs_read_ue( &s );
        if( i_tmp == 0 )
        {
            /* skip i_log2_max_poc_lsb */
            bs_read_ue( &s );
        }
        else if( i_tmp == 1 )
        {
            int i_cycle;
            /* skip b_delta_pic_order_always_zero */
            bs_skip( &s, 1 );
            /* skip i_offset_for_non_ref_pic */
            bs_read_se( &s );
            /* skip i_offset_for_top_to_bottom_field */
            bs_read_se( &s );
            /* read i_num_ref_frames_in_poc_cycle */
            i_cycle = bs_read_ue( &s );
            if( i_cycle > 256 ) i_cycle = 256;
            while( i_cycle > 0 )
            {
                /* skip i_offset_for_ref_frame */
                bs_read_se(&s );
            }
        }
        /* i_num_ref_frames */
        bs_read_ue( &s );
        /* b_gaps_in_frame_num_value_allowed */
        bs_skip( &s, 1 );

        /* Read size */
        p_dec->fmt_out.video.i_width  = 16 * ( bs_read_ue( &s ) + 1 );
        p_dec->fmt_out.video.i_height = 16 * ( bs_read_ue( &s ) + 1 );

        /* b_frame_mbs_only */
        p_sys->b_frame_mbs_only = bs_read( &s, 1 );
        if( p_sys->b_frame_mbs_only == 0 )
        {
            bs_skip( &s, 1 );
        }
        /* b_direct8x8_inference */
        bs_skip( &s, 1 );

        /* crop */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            /* left */
            bs_read_ue( &s );
            /* right */
            bs_read_ue( &s );
            /* top */
            bs_read_ue( &s );
            /* bottom */
            bs_read_ue( &s );
        }

        /* vui */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            /* read the aspect ratio part if any FIXME check it */
            i_tmp = bs_read( &s, 1 );
            if( i_tmp )
            {
                static const struct {
                    int w, h;
                } sar[14] =
                {
                    { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                    { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                    { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                    { 64, 33 }, { 160,99 },
                };
                int i_sar = bs_read( &s, 8 );
                int w, h;

                if( i_sar < 14 )
                {
                    w = sar[i_sar].w;
                    h = sar[i_sar].h;
                }
                else
                {
                    w = bs_read( &s, 16 );
                    h = bs_read( &s, 16 );
                }
                p_dec->fmt_out.video.i_aspect =
                    VOUT_ASPECT_FACTOR * w / h * p_dec->fmt_out.video.i_width /
                    p_dec->fmt_out.video.i_height;
            }
        }

        free( dec );
    }
    else if( i_nal_type == NAL_PPS )
    {
        bs_t s;
        bs_init( &s, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );

        /* TODO */
        msg_Dbg( p_dec, "found NAL_PPS" );
    }

    /* Append the block */
    block_ChainAppend( &p_sys->p_frame, p_frag );

    return p_pic;
}
Exemple #19
0
static void PutSPS( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    uint8_t *pb_dec = NULL;
    int     i_dec = 0;
    bs_t s;
    int i_tmp;
    int i_sps_id;

    CreateDecodedNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5],
                     p_frag->i_buffer - 5 );

    bs_init( &s, pb_dec, i_dec );
    int i_profile_idc = bs_read( &s, 8 );
    p_dec->fmt_out.i_profile = i_profile_idc;
    /* Skip constraint_set0123, reserved(4) */
    bs_skip( &s, 1+1+1+1 + 4 );
    p_dec->fmt_out.i_level = bs_read( &s, 8 );
    /* sps id */
    i_sps_id = bs_read_ue( &s );
    if( i_sps_id >= SPS_MAX || i_sps_id < 0 )
    {
        msg_Warn( p_dec, "invalid SPS (sps_id=%d)", i_sps_id );
        free( pb_dec );
        block_Release( p_frag );
        return;
    }

    if( i_profile_idc == 100 || i_profile_idc == 110 ||
        i_profile_idc == 122 || i_profile_idc == 244 ||
        i_profile_idc ==  44 || i_profile_idc ==  83 ||
        i_profile_idc ==  86 )
    {
        /* chroma_format_idc */
        const int i_chroma_format_idc = bs_read_ue( &s );
        if( i_chroma_format_idc == 3 )
            bs_skip( &s, 1 ); /* separate_colour_plane_flag */
        /* bit_depth_luma_minus8 */
        bs_read_ue( &s );
        /* bit_depth_chroma_minus8 */
        bs_read_ue( &s );
        /* qpprime_y_zero_transform_bypass_flag */
        bs_skip( &s, 1 );
        /* seq_scaling_matrix_present_flag */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            for( int i = 0; i < ((3 != i_chroma_format_idc) ? 8 : 12); i++ )
            {
                /* seq_scaling_list_present_flag[i] */
                i_tmp = bs_read( &s, 1 );
                if( !i_tmp )
                    continue;
                const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64;
                /* scaling_list (...) */
                int i_lastscale = 8;
                int i_nextscale = 8;
                for( int j = 0; j < i_size_of_scaling_list; j++ )
                {
                    if( i_nextscale != 0 )
                    {
                        /* delta_scale */
                        i_tmp = bs_read_se( &s );
                        i_nextscale = ( i_lastscale + i_tmp + 256 ) % 256;
                        /* useDefaultScalingMatrixFlag = ... */
                    }
                    /* scalinglist[j] */
                    i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale;
                }
            }
        }
    }

    /* Skip i_log2_max_frame_num */
    p_sys->i_log2_max_frame_num = bs_read_ue( &s );
    if( p_sys->i_log2_max_frame_num > 12)
        p_sys->i_log2_max_frame_num = 12;
    /* Read poc_type */
    p_sys->i_pic_order_cnt_type = bs_read_ue( &s );
    if( p_sys->i_pic_order_cnt_type == 0 )
    {
        /* skip i_log2_max_poc_lsb */
        p_sys->i_log2_max_pic_order_cnt_lsb = bs_read_ue( &s );
        if( p_sys->i_log2_max_pic_order_cnt_lsb > 12 )
            p_sys->i_log2_max_pic_order_cnt_lsb = 12;
    }
    else if( p_sys->i_pic_order_cnt_type == 1 )
    {
        int i_cycle;
        /* skip b_delta_pic_order_always_zero */
        p_sys->i_delta_pic_order_always_zero_flag = bs_read( &s, 1 );
        /* skip i_offset_for_non_ref_pic */
        bs_read_se( &s );
        /* skip i_offset_for_top_to_bottom_field */
        bs_read_se( &s );
        /* read i_num_ref_frames_in_poc_cycle */
        i_cycle = bs_read_ue( &s );
        if( i_cycle > 256 ) i_cycle = 256;
        while( i_cycle > 0 )
        {
            /* skip i_offset_for_ref_frame */
            bs_read_se(&s );
            i_cycle--;
        }
    }
    /* i_num_ref_frames */
    bs_read_ue( &s );
    /* b_gaps_in_frame_num_value_allowed */
    bs_skip( &s, 1 );

    /* Read size */
    p_dec->fmt_out.video.i_width  = 16 * ( bs_read_ue( &s ) + 1 );
    p_dec->fmt_out.video.i_height = 16 * ( bs_read_ue( &s ) + 1 );

    /* b_frame_mbs_only */
    p_sys->b_frame_mbs_only = bs_read( &s, 1 );
    p_dec->fmt_out.video.i_height *=  ( 2 - p_sys->b_frame_mbs_only );
    if( p_sys->b_frame_mbs_only == 0 )
    {
        bs_skip( &s, 1 );
    }
    /* b_direct8x8_inference */
    bs_skip( &s, 1 );

    /* crop */
    i_tmp = bs_read( &s, 1 );
    if( i_tmp )
    {
        /* left */
        bs_read_ue( &s );
        /* right */
        bs_read_ue( &s );
        /* top */
        bs_read_ue( &s );
        /* bottom */
        bs_read_ue( &s );
    }

    /* vui */
    i_tmp = bs_read( &s, 1 );
    if( i_tmp )
    {
        /* read the aspect ratio part if any */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            static const struct { int w, h; } sar[17] =
            {
                { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                { 64, 33 }, { 160,99 }, {  4,  3 }, {  3,  2 },
                {  2,  1 },
            };
            int i_sar = bs_read( &s, 8 );
            int w, h;

            if( i_sar < 17 )
            {
                w = sar[i_sar].w;
                h = sar[i_sar].h;
            }
            else if( i_sar == 255 )
            {
                w = bs_read( &s, 16 );
                h = bs_read( &s, 16 );
            }
            else
            {
                w = 0;
                h = 0;
            }

            if( w != 0 && h != 0 )
            {
                p_dec->fmt_out.video.i_sar_num = w;
                p_dec->fmt_out.video.i_sar_den = h;
            }
            else
            {
                p_dec->fmt_out.video.i_sar_num = 1;
                p_dec->fmt_out.video.i_sar_den = 1;
            }
        }
    }

    free( pb_dec );

    /* We have a new SPS */
    if( !p_sys->b_sps )
        msg_Dbg( p_dec, "found NAL_SPS (sps_id=%d)", i_sps_id );
    p_sys->b_sps = true;

    if( p_sys->pp_sps[i_sps_id] )
        block_Release( p_sys->pp_sps[i_sps_id] );
    p_sys->pp_sps[i_sps_id] = p_frag;
}
Exemple #20
0
static void ParseSei( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    uint8_t *pb_dec;
    int i_dec;

    /* */
    CreateDecodedNAL( &pb_dec, &i_dec, &p_frag->p_buffer[5], p_frag->i_buffer - 5 );
    if( !pb_dec )
        return;

    /* The +1 is for rbsp trailing bits */
    for( int i_used = 0; i_used+1 < i_dec; )
    {
        /* Read type */
        int i_type = 0;
        while( i_used+1 < i_dec )
        {
            const int i_byte = pb_dec[i_used++];
            i_type += i_byte;
            if( i_byte != 0xff )
                break;
        }
        /* Read size */
        int i_size = 0;
        while( i_used+1 < i_dec )
        {
            const int i_byte = pb_dec[i_used++];
            i_size += i_byte;
            if( i_byte != 0xff )
                break;
        }
        /* Check room */
        if( i_used + i_size + 1 > i_dec )
            break;

        /* Look for user_data_registered_itu_t_t35 */
        if( i_type == 4 )
        {
            static const uint8_t p_dvb1_data_start_code[] = {
                0xb5,
                0x00, 0x31,
                0x47, 0x41, 0x39, 0x34
            };
            const int      i_t35 = i_size;
            const uint8_t *p_t35 = &pb_dec[i_used];

            /* Check for we have DVB1_data() */
            if( i_t35 >= 5 &&
                !memcmp( p_t35, p_dvb1_data_start_code, sizeof(p_dvb1_data_start_code) ) )
            {
                cc_Extract( &p_sys->cc_next, true, &p_t35[3], i_t35 - 3 );
            }
        }

        /* Look for SEI recovery point */
        if( i_type == 6 )
        {
            bs_t s;
            const int      i_rec = i_size;
            const uint8_t *p_rec = &pb_dec[i_used];

            bs_init( &s, p_rec, i_rec );
            int i_recovery_frames = bs_read_ue( &s );
            //bool b_exact_match = bs_read( &s, 1 );
            //bool b_broken_link = bs_read( &s, 1 );
            //int i_changing_slice_group = bs_read( &s, 2 );
            if( !p_sys->b_header )
            {
                msg_Dbg( p_dec, "Seen SEI recovery point, %d recovery frames", i_recovery_frames );
                if ( p_sys->i_recovery_frames == -1 || i_recovery_frames < p_sys->i_recovery_frames )
                    p_sys->i_recovery_frames = i_recovery_frames;
            }
        }

        i_used += i_size;
    }

    free( pb_dec );
}
Exemple #21
0
static inline int bs_read_se( bs_t *s )
{
    int val = bs_read_ue( s );

    return val&0x01 ? (val+1)/2 : -(val/2);
}
Exemple #22
0
int h264_parse_sps( const uint8_t *p_sps_buf, int i_sps_size,
                    struct nal_sps *p_sps )
{
    uint8_t *pb_dec = NULL;
    int     i_dec = 0;
    bs_t s;
    int i_tmp;

    if (i_sps_size < 5 || (p_sps_buf[4] & 0x1f) != NAL_SPS)
        return -1;

    memset( p_sps, 0, sizeof(struct nal_sps) );
    CreateRbspFromNAL( &pb_dec, &i_dec, &p_sps_buf[5],
                      i_sps_size - 5 );

    bs_init( &s, pb_dec, i_dec );
    int i_profile_idc = bs_read( &s, 8 );
    p_sps->i_profile = i_profile_idc;
    p_sps->i_profile_compatibility = bs_read( &s, 8 );
    p_sps->i_level = bs_read( &s, 8 );
    /* sps id */
    p_sps->i_id = bs_read_ue( &s );
    if( p_sps->i_id >= SPS_MAX || p_sps->i_id < 0 )
    {
        free( pb_dec );
        return -1;
    }

    if( i_profile_idc == PROFILE_H264_HIGH || i_profile_idc == PROFILE_H264_HIGH_10 ||
        i_profile_idc == PROFILE_H264_HIGH_422 || i_profile_idc == PROFILE_H264_HIGH_444_PREDICTIVE ||
        i_profile_idc ==  PROFILE_H264_CAVLC_INTRA || i_profile_idc ==  PROFILE_H264_SVC_BASELINE ||
        i_profile_idc ==  PROFILE_H264_SVC_HIGH )
    {
        /* chroma_format_idc */
        const int i_chroma_format_idc = bs_read_ue( &s );
        if( i_chroma_format_idc == 3 )
            bs_skip( &s, 1 ); /* separate_colour_plane_flag */
        /* bit_depth_luma_minus8 */
        bs_read_ue( &s );
        /* bit_depth_chroma_minus8 */
        bs_read_ue( &s );
        /* qpprime_y_zero_transform_bypass_flag */
        bs_skip( &s, 1 );
        /* seq_scaling_matrix_present_flag */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            for( int i = 0; i < ((3 != i_chroma_format_idc) ? 8 : 12); i++ )
            {
                /* seq_scaling_list_present_flag[i] */
                i_tmp = bs_read( &s, 1 );
                if( !i_tmp )
                    continue;
                const int i_size_of_scaling_list = (i < 6 ) ? 16 : 64;
                /* scaling_list (...) */
                int i_lastscale = 8;
                int i_nextscale = 8;
                for( int j = 0; j < i_size_of_scaling_list; j++ )
                {
                    if( i_nextscale != 0 )
                    {
                        /* delta_scale */
                        i_tmp = bs_read_se( &s );
                        i_nextscale = ( i_lastscale + i_tmp + 256 ) % 256;
                        /* useDefaultScalingMatrixFlag = ... */
                    }
                    /* scalinglist[j] */
                    i_lastscale = ( i_nextscale == 0 ) ? i_lastscale : i_nextscale;
                }
            }
        }
    }

    /* Skip i_log2_max_frame_num */
    p_sps->i_log2_max_frame_num = bs_read_ue( &s );
    if( p_sps->i_log2_max_frame_num > 12)
        p_sps->i_log2_max_frame_num = 12;
    /* Read poc_type */
    p_sps->i_pic_order_cnt_type = bs_read_ue( &s );
    if( p_sps->i_pic_order_cnt_type == 0 )
    {
        /* skip i_log2_max_poc_lsb */
        p_sps->i_log2_max_pic_order_cnt_lsb = bs_read_ue( &s );
        if( p_sps->i_log2_max_pic_order_cnt_lsb > 12 )
            p_sps->i_log2_max_pic_order_cnt_lsb = 12;
    }
    else if( p_sps->i_pic_order_cnt_type == 1 )
    {
        int i_cycle;
        /* skip b_delta_pic_order_always_zero */
        p_sps->i_delta_pic_order_always_zero_flag = bs_read( &s, 1 );
        /* skip i_offset_for_non_ref_pic */
        bs_read_se( &s );
        /* skip i_offset_for_top_to_bottom_field */
        bs_read_se( &s );
        /* read i_num_ref_frames_in_poc_cycle */
        i_cycle = bs_read_ue( &s );
        if( i_cycle > 256 ) i_cycle = 256;
        while( i_cycle > 0 )
        {
            /* skip i_offset_for_ref_frame */
            bs_read_se(&s );
            i_cycle--;
        }
    }
    /* i_num_ref_frames */
    bs_read_ue( &s );
    /* b_gaps_in_frame_num_value_allowed */
    bs_skip( &s, 1 );

    /* Read size */
    p_sps->i_width  = 16 * ( bs_read_ue( &s ) + 1 );
    p_sps->i_height = 16 * ( bs_read_ue( &s ) + 1 );

    /* b_frame_mbs_only */
    p_sps->b_frame_mbs_only = bs_read( &s, 1 );
    p_sps->i_height *=  ( 2 - p_sps->b_frame_mbs_only );
    if( p_sps->b_frame_mbs_only == 0 )
    {
        bs_skip( &s, 1 );
    }
    /* b_direct8x8_inference */
    bs_skip( &s, 1 );

    /* crop */
    i_tmp = bs_read( &s, 1 );
    if( i_tmp )
    {
        /* left */
        bs_read_ue( &s );
        /* right */
        bs_read_ue( &s );
        /* top */
        bs_read_ue( &s );
        /* bottom */
        bs_read_ue( &s );
    }

    /* vui */
    i_tmp = bs_read( &s, 1 );
    if( i_tmp )
    {
        p_sps->vui.b_valid = true;
        /* read the aspect ratio part if any */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            static const struct { int w, h; } sar[17] =
            {
                { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                { 64, 33 }, { 160,99 }, {  4,  3 }, {  3,  2 },
                {  2,  1 },
            };
            int i_sar = bs_read( &s, 8 );
            int w, h;

            if( i_sar < 17 )
            {
                w = sar[i_sar].w;
                h = sar[i_sar].h;
            }
            else if( i_sar == 255 )
            {
                w = bs_read( &s, 16 );
                h = bs_read( &s, 16 );
            }
            else
            {
                w = 0;
                h = 0;
            }

            if( w != 0 && h != 0 )
            {
                p_sps->vui.i_sar_num = w;
                p_sps->vui.i_sar_den = h;
            }
            else
            {
                p_sps->vui.i_sar_num = 1;
                p_sps->vui.i_sar_den = 1;
            }
        }

        /* overscan */
        i_tmp = bs_read( &s, 1 );
        if ( i_tmp )
            bs_read( &s, 1 );

        /* video signal type */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            bs_read( &s, 4 );
            /* colour desc */
            bs_read( &s, 1 );
            if ( i_tmp )
                bs_read( &s, 24 );
        }

        /* chroma loc info */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            bs_read_ue( &s );
            bs_read_ue( &s );
        }

        /* timing info */
        p_sps->vui.b_timing_info_present_flag = bs_read( &s, 1 );
        if( p_sps->vui.b_timing_info_present_flag )
        {
            p_sps->vui.i_num_units_in_tick = bs_read( &s, 32 );
            p_sps->vui.i_time_scale = bs_read( &s, 32 );
            p_sps->vui.b_fixed_frame_rate = bs_read( &s, 1 );
        }

        /* Nal hrd & VC1 hrd parameters */
        p_sps->vui.b_cpb_dpb_delays_present_flag = false;
        for ( int i=0; i<2; i++ )
        {
            i_tmp = bs_read( &s, 1 );
            if( i_tmp )
            {
                p_sps->vui.b_cpb_dpb_delays_present_flag = true;
                uint32_t count = bs_read_ue( &s ) + 1;
                bs_read( &s, 4 );
                bs_read( &s, 4 );
                for( uint32_t i=0; i<count; i++ )
                {
                    bs_read_ue( &s );
                    bs_read_ue( &s );
                    bs_read( &s, 1 );
                }
                bs_read( &s, 5 );
                p_sps->vui.i_cpb_removal_delay_length_minus1 = bs_read( &s, 5 );
                p_sps->vui.i_dpb_output_delay_length_minus1 = bs_read( &s, 5 );
                bs_read( &s, 5 );
            }
        }

        if( p_sps->vui.b_cpb_dpb_delays_present_flag )
            bs_read( &s, 1 );

        /* pic struct info */
        p_sps->vui.b_pic_struct_present_flag = bs_read( &s, 1 );

        /* + unparsed remains */
    }

    free( pb_dec );

    return 0;
}
Exemple #23
0
/*****************************************************************************
 * ParseNALBlock: parses annexB type NALs
 * All p_frag blocks are required to start with 0 0 0 1 4-byte startcode 
 *****************************************************************************/
static block_t *ParseNALBlock( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_pic = NULL;

    const int i_nal_ref_idc = (p_frag->p_buffer[4] >> 5)&0x03;
    const int i_nal_type = p_frag->p_buffer[4]&0x1f;

#define OUTPUT \
    do {                                                      \
        if( !p_sys->b_header && p_sys->slice.i_frame_type != BLOCK_FLAG_TYPE_I) \
            break;                                            \
                                                              \
        if( p_sys->slice.i_frame_type == BLOCK_FLAG_TYPE_I && p_sys->p_sps && p_sys->p_pps && !p_sys->b_header ) \
        { \
            block_t *p_sps = block_Duplicate( p_sys->p_sps ); \
            block_t *p_pps = block_Duplicate( p_sys->p_pps ); \
            p_sps->i_dts = p_sys->p_frame->i_dts;           \
            p_sps->i_pts = p_sys->p_frame->i_pts;           \
            block_ChainAppend( &p_sps, p_pps );               \
            block_ChainAppend( &p_sps, p_sys->p_frame );      \
            p_sys->b_header = VLC_TRUE;                       \
            p_pic = block_ChainGather( p_sps );               \
        } else { \
            p_pic = block_ChainGather( p_sys->p_frame ); \
        } \
        p_pic->i_length = 0;    /* FIXME */                   \
        p_pic->i_flags |= p_sys->slice.i_frame_type;          \
            \
        p_sys->slice.i_frame_type = 0;                        \
        p_sys->p_frame = NULL;                                \
        p_sys->b_slice = VLC_FALSE;                           \
    } while(0)

    if( p_sys->b_slice && ( !p_sys->b_sps || !p_sys->b_pps ) )
    {
        block_ChainRelease( p_sys->p_frame );
        msg_Warn( p_dec, "waiting for SPS/PPS" );

        /* Reset context */
        p_sys->slice.i_frame_type = 0;
        p_sys->p_frame = NULL;
        p_sys->b_slice = VLC_FALSE;
    }

    if( ( !p_sys->b_sps || !p_sys->b_pps ) &&
        i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
    {
        p_sys->b_slice = VLC_TRUE;
        /* Fragment will be discarded later on */
    }
    else if( i_nal_type >= NAL_SLICE && i_nal_type <= NAL_SLICE_IDR )
    {
        uint8_t *dec;
        int i_dec, i_first_mb, i_slice_type;
        slice_t slice;
        vlc_bool_t b_pic;
        bs_t s;

        /* do not convert the whole frame */
        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5],
                         __MIN( p_frag->i_buffer - 5, 60 ) );
        bs_init( &s, dec, i_dec );

        /* first_mb_in_slice */
        i_first_mb = bs_read_ue( &s );

        /* slice_type */
        switch( (i_slice_type = bs_read_ue( &s )) )
        {
        case 0: case 5:
            slice.i_frame_type = BLOCK_FLAG_TYPE_P;
            break;
        case 1: case 6:
            slice.i_frame_type = BLOCK_FLAG_TYPE_B;
            break;
        case 2: case 7:
            slice.i_frame_type = BLOCK_FLAG_TYPE_I;
            break;
        case 3: case 8: /* SP */
            slice.i_frame_type = BLOCK_FLAG_TYPE_P;
            break;
        case 4: case 9:
            slice.i_frame_type = BLOCK_FLAG_TYPE_I;
            break;
        default:
            slice.i_frame_type = 0;
            break;
        }

        /* */
        slice.i_nal_type = i_nal_type;
        slice.i_nal_ref_idc = i_nal_ref_idc;

        slice.i_pic_parameter_set_id = bs_read_ue( &s );
        slice.i_frame_num = bs_read( &s, p_sys->i_log2_max_frame_num + 4 );

        slice.i_field_pic_flag = 0;
        slice.i_bottom_field_flag = -1;
        if( !p_sys->b_frame_mbs_only )
        {
            /* field_pic_flag */
            slice.i_field_pic_flag = bs_read( &s, 1 );
            if( slice.i_field_pic_flag )
                slice.i_bottom_field_flag = bs_read( &s, 1 );
        }

        slice.i_idr_pic_id = p_sys->slice.i_idr_pic_id;
        if( slice.i_nal_type == NAL_SLICE_IDR )
            slice.i_idr_pic_id = bs_read_ue( &s );

        slice.i_pic_order_cnt_lsb = -1;
        slice.i_delta_pic_order_cnt_bottom = -1;
        slice.i_delta_pic_order_cnt0 = 0;
        slice.i_delta_pic_order_cnt1 = 0;
        if( p_sys->i_pic_order_cnt_type == 0 )
        {
            slice.i_pic_order_cnt_lsb = bs_read( &s, p_sys->i_log2_max_pic_order_cnt_lsb + 4 );
            if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag )
                slice.i_delta_pic_order_cnt_bottom = bs_read_se( &s );
        }
        else if( p_sys->i_pic_order_cnt_type == 1 && !p_sys->i_delta_pic_order_always_zero_flag )
        {
            slice.i_delta_pic_order_cnt0 = bs_read_se( &s );
            if( p_sys->i_pic_order_present_flag && !slice.i_field_pic_flag )
                slice.i_delta_pic_order_cnt1 = bs_read_se( &s );
        }

        /* Detection of the first VCL NAL unit of a primary coded picture
         * (cf. 7.4.1.2.4) */
        b_pic = VLC_FALSE;
        if( slice.i_frame_num != p_sys->slice.i_frame_num ||
            slice.i_pic_parameter_set_id != p_sys->slice.i_pic_parameter_set_id ||
            slice.i_field_pic_flag != p_sys->slice.i_field_pic_flag ||
            slice.i_nal_ref_idc != p_sys->slice.i_nal_ref_idc )
            b_pic = VLC_TRUE;
        if( slice.i_bottom_field_flag != -1 && p_sys->slice.i_bottom_field_flag != -1 && slice.i_bottom_field_flag != p_sys->slice.i_bottom_field_flag )
            b_pic = VLC_TRUE;
        if( p_sys->i_pic_order_cnt_type == 0 &&
            ( slice.i_pic_order_cnt_lsb != p_sys->slice.i_pic_order_cnt_lsb ||
              slice.i_delta_pic_order_cnt_bottom != p_sys->slice.i_delta_pic_order_cnt_bottom ) )
            b_pic = VLC_TRUE;
        else if( p_sys->i_pic_order_cnt_type == 1 &&
                 ( slice.i_delta_pic_order_cnt0 != p_sys->slice.i_delta_pic_order_cnt0 ||
                   slice.i_delta_pic_order_cnt1 != p_sys->slice.i_delta_pic_order_cnt1 ) )
            b_pic = VLC_TRUE;
        if( ( slice.i_nal_type == NAL_SLICE_IDR || p_sys->slice.i_nal_type == NAL_SLICE_IDR ) &&
            ( slice.i_nal_type != p_sys->slice.i_nal_type || slice.i_idr_pic_id != p_sys->slice.i_idr_pic_id ) )
                b_pic = VLC_TRUE;

        /* */
        p_sys->slice = slice;

        if( b_pic && p_sys->b_slice )
            OUTPUT;

        p_sys->b_slice = VLC_TRUE;

        free( dec );
    }
    else if( i_nal_type == NAL_SPS )
    {
        uint8_t *dec;
        int     i_dec;
        bs_t s;
        int i_tmp;

        if( !p_sys->b_sps ) msg_Dbg( p_dec, "found NAL_SPS" );

        p_sys->b_sps = VLC_TRUE;

        nal_get_decoded( &dec, &i_dec, &p_frag->p_buffer[5],
                         p_frag->i_buffer - 5 );

        bs_init( &s, dec, i_dec );
        /* Skip profile(8), constraint_set012, reserver(5), level(8) */
        bs_skip( &s, 8 + 1+1+1 + 5 + 8 );
        /* sps id */
        bs_read_ue( &s );
        /* Skip i_log2_max_frame_num */
        p_sys->i_log2_max_frame_num = bs_read_ue( &s );
        if( p_sys->i_log2_max_frame_num > 12)
            p_sys->i_log2_max_frame_num = 12;
        /* Read poc_type */
        p_sys->i_pic_order_cnt_type = bs_read_ue( &s );
        if( p_sys->i_pic_order_cnt_type == 0 )
        {
            /* skip i_log2_max_poc_lsb */
            p_sys->i_log2_max_pic_order_cnt_lsb = bs_read_ue( &s );
            if( p_sys->i_log2_max_pic_order_cnt_lsb > 12 )
                p_sys->i_log2_max_pic_order_cnt_lsb = 12;
        }
        else if( p_sys->i_pic_order_cnt_type == 1 )
        {
            int i_cycle;
            /* skip b_delta_pic_order_always_zero */
            p_sys->i_delta_pic_order_always_zero_flag = bs_read( &s, 1 );
            /* skip i_offset_for_non_ref_pic */
            bs_read_se( &s );
            /* skip i_offset_for_top_to_bottom_field */
            bs_read_se( &s );
            /* read i_num_ref_frames_in_poc_cycle */
            i_cycle = bs_read_ue( &s );
            if( i_cycle > 256 ) i_cycle = 256;
            while( i_cycle > 0 )
            {
                /* skip i_offset_for_ref_frame */
                bs_read_se(&s );
            }
        }
        /* i_num_ref_frames */
        bs_read_ue( &s );
        /* b_gaps_in_frame_num_value_allowed */
        bs_skip( &s, 1 );

        /* Read size */
        p_dec->fmt_out.video.i_width  = 16 * ( bs_read_ue( &s ) + 1 );
        p_dec->fmt_out.video.i_height = 16 * ( bs_read_ue( &s ) + 1 );

        /* b_frame_mbs_only */
        p_sys->b_frame_mbs_only = bs_read( &s, 1 );
        if( p_sys->b_frame_mbs_only == 0 )
        {
            bs_skip( &s, 1 );
        }
        /* b_direct8x8_inference */
        bs_skip( &s, 1 );

        /* crop */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            /* left */
            bs_read_ue( &s );
            /* right */
            bs_read_ue( &s );
            /* top */
            bs_read_ue( &s );
            /* bottom */
            bs_read_ue( &s );
        }

        /* vui */
        i_tmp = bs_read( &s, 1 );
        if( i_tmp )
        {
            /* read the aspect ratio part if any FIXME check it */
            i_tmp = bs_read( &s, 1 );
            if( i_tmp )
            {
                static const struct { int w, h; } sar[14] =
                {
                    { 0,   0 }, { 1,   1 }, { 12, 11 }, { 10, 11 },
                    { 16, 11 }, { 40, 33 }, { 24, 11 }, { 20, 11 },
                    { 32, 11 }, { 80, 33 }, { 18, 11 }, { 15, 11 },
                    { 64, 33 }, { 160,99 },
                };
                int i_sar = bs_read( &s, 8 );
                int w, h;

                if( i_sar < 14 )
                {
                    w = sar[i_sar].w;
                    h = sar[i_sar].h;
                }
                else
                {
                    w = bs_read( &s, 16 );
                    h = bs_read( &s, 16 );
                }
                if( h != 0 )
                    p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR * w /
                        h * p_dec->fmt_out.video.i_width /
                        p_dec->fmt_out.video.i_height;
                else
                    p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR;
            }
        }

        free( dec );

        if( p_sys->b_slice ) OUTPUT;

        /* We have a new SPS */
        if( p_sys->p_sps ) block_Release( p_sys->p_sps );
        p_sys->p_sps = p_frag;

        /* Do not append the SPS because we will insert it on keyframes */
        return p_pic;
    }
    else if( i_nal_type == NAL_PPS )
    {
        bs_t s;

        bs_init( &s, &p_frag->p_buffer[5], p_frag->i_buffer - 5 );
        bs_read_ue( &s ); // pps id
        bs_read_ue( &s ); // sps id
        bs_skip( &s, 1 ); // entropy coding mode flag
        p_sys->i_pic_order_present_flag = bs_read( &s, 1 );

        if( !p_sys->b_pps ) msg_Dbg( p_dec, "found NAL_PPS" );
        p_sys->b_pps = VLC_TRUE;

        /* TODO */

        if( p_sys->b_slice ) OUTPUT;

        /* We have a new PPS */
        if( p_sys->p_pps ) block_Release( p_sys->p_pps );
        p_sys->p_pps = p_frag;

        /* Do not append the PPS because we will insert it on keyframes */
        return p_pic;
    }
    else if( i_nal_type == NAL_AU_DELIMITER ||
             i_nal_type == NAL_SEI ||
             ( i_nal_type >= 13 && i_nal_type <= 18 ) )
    {
        if( p_sys->b_slice ) OUTPUT;
    }

#undef OUTPUT

    /* Append the block */
    block_ChainAppend( &p_sys->p_frame, p_frag );

    return p_pic;
}
Exemple #24
0
static bool hevc_parse_vui_parameters_rbsp( bs_t *p_bs, hevc_vui_parameters_t *p_vui )
{
    if( bs_remain( p_bs ) < 10 )
        return false;

    p_vui->aspect_ratio_info_present_flag = bs_read1( p_bs );
    if( p_vui->aspect_ratio_info_present_flag )
    {
        p_vui->ar.aspect_ratio_idc = bs_read( p_bs, 8 );
        if( p_vui->ar.aspect_ratio_idc == 0xFF ) //HEVC_SAR__IDC_EXTENDED_SAR )
        {
            p_vui->ar.sar_width = bs_read( p_bs, 16 );
            p_vui->ar.sar_height = bs_read( p_bs, 16 );
        }
    }

    p_vui->overscan_info_present_flag = bs_read1( p_bs );
    if( p_vui->overscan_info_present_flag )
        p_vui->overscan_appropriate_flag = bs_read1( p_bs );

    p_vui->video_signal_type_present_flag = bs_read1( p_bs );
    if( p_vui->video_signal_type_present_flag )
    {
        p_vui->vs.video_format = bs_read( p_bs, 3 );
        p_vui->vs.video_full_range_flag = bs_read1( p_bs );
        p_vui->vs.colour_description_present_flag = bs_read1( p_bs );
        if( p_vui->vs.colour_description_present_flag )
        {
            p_vui->vs.colour.colour_primaries = bs_read( p_bs, 8 );
            p_vui->vs.colour.transfer_characteristics = bs_read( p_bs, 8 );
            p_vui->vs.colour.matrix_coeffs = bs_read( p_bs, 8 );
        }
    }

    p_vui->chroma_loc_info_present_flag = bs_read1( p_bs );
    if( p_vui->chroma_loc_info_present_flag )
    {
        p_vui->chroma.sample_loc_type_top_field = bs_read_ue( p_bs );
        p_vui->chroma.sample_loc_type_bottom_field = bs_read_ue( p_bs );
    }

    p_vui->neutral_chroma_indication_flag = bs_read1( p_bs );
    p_vui->field_seq_flag = bs_read1( p_bs );
    p_vui->frame_field_info_present_flag = bs_read1( p_bs );

    p_vui->default_display_window_flag = bs_read1( p_bs );
    if( p_vui->default_display_window_flag )
    {
        p_vui->def_disp.win_left_offset = bs_read_ue( p_bs );
        p_vui->def_disp.win_right_offset = bs_read_ue( p_bs );
        p_vui->def_disp.win_top_offset = bs_read_ue( p_bs );
        p_vui->def_disp.win_bottom_offset = bs_read_ue( p_bs );
    }

    p_vui->vui_timing_info_present_flag = bs_read1( p_bs );
    if( p_vui->vui_timing_info_present_flag )
    {
        p_vui->timing.vui_num_units_in_tick =  bs_read( p_bs, 32 );
        p_vui->timing.vui_time_scale =  bs_read( p_bs, 32 );

        if( bs_remain( p_bs ) < 3 )
            return false;
    }
    /* incomplete */

    if( bs_remain( p_bs ) < 1 ) /* late fail */
        return false;

    return true;
}
Exemple #25
0
// Appendix G.13.1.1 Scalability information SEI message syntax
void read_sei_scalability_info( h264_stream_t* h, bs_t* b )
{
    sei_scalability_info_t* sei_svc = h->sei->sei_svc;
    
    sei_svc->temporal_id_nesting_flag = bs_read_u1(b);
    sei_svc->priority_layer_info_present_flag = bs_read_u1(b);
    sei_svc->priority_id_setting_flag = bs_read_u1(b);
    sei_svc->num_layers_minus1 = bs_read_ue(b);
    
    for( int i = 0; i <= sei_svc->num_layers_minus1; i++ ) {
        sei_svc->layers[i].layer_id = bs_read_ue(b);
        sei_svc->layers[i].priority_id = bs_read_u(b, 6);
        sei_svc->layers[i].discardable_flag = bs_read_u1(b);
        sei_svc->layers[i].dependency_id = bs_read_u(b, 3);
        sei_svc->layers[i].quality_id = bs_read_u(b, 4);
        sei_svc->layers[i].temporal_id = bs_read_u(b, 3);
        sei_svc->layers[i].sub_pic_layer_flag = bs_read_u1(b);
        sei_svc->layers[i].sub_region_layer_flag = bs_read_u1(b);
        sei_svc->layers[i].iroi_division_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].profile_level_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].bitrate_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].frm_rate_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].frm_size_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].layer_dependency_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].parameter_sets_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].bitstream_restriction_info_present_flag = bs_read_u1(b);
        sei_svc->layers[i].exact_inter_layer_pred_flag = bs_read_u1(b);
        if( sei_svc->layers[i].sub_pic_layer_flag ||
            sei_svc->layers[i].iroi_division_info_present_flag )
        {
            sei_svc->layers[i].exact_sample_value_match_flag = bs_read_u1(b);
        }
        sei_svc->layers[i].layer_conversion_flag = bs_read_u1(b);
        sei_svc->layers[i].layer_output_flag = bs_read_u1(b);
        if( sei_svc->layers[i].profile_level_info_present_flag )
        {
            sei_svc->layers[i].layer_profile_level_idc = bs_read_u(b, 24);
        }
        if( sei_svc->layers[i].bitrate_info_present_flag )
        {
            sei_svc->layers[i].avg_bitrate = bs_read_u(b, 16);
            sei_svc->layers[i].max_bitrate_layer = bs_read_u(b, 16);
            sei_svc->layers[i].max_bitrate_layer_representation = bs_read_u(b, 16);
            sei_svc->layers[i].max_bitrate_calc_window = bs_read_u(b, 16);
        }
        if( sei_svc->layers[i].frm_rate_info_present_flag )
        {
            sei_svc->layers[i].constant_frm_rate_idc = bs_read_u(b, 2);
            sei_svc->layers[i].avg_frm_rate = bs_read_u(b, 16);
        }
        if( sei_svc->layers[i].frm_size_info_present_flag ||
            sei_svc->layers[i].iroi_division_info_present_flag )
        {
            sei_svc->layers[i].frm_width_in_mbs_minus1 = bs_read_ue(b);
            sei_svc->layers[i].frm_height_in_mbs_minus1 = bs_read_ue(b);
        }
        if( sei_svc->layers[i].sub_region_layer_flag )
        {
            sei_svc->layers[i].base_region_layer_id = bs_read_ue(b);
            sei_svc->layers[i].dynamic_rect_flag = bs_read_u1(b);
            if( sei_svc->layers[i].dynamic_rect_flag )
            {
                sei_svc->layers[i].horizontal_offset = bs_read_u(b, 16);
                sei_svc->layers[i].vertical_offset = bs_read_u(b, 16);
                sei_svc->layers[i].region_width = bs_read_u(b, 16);
                sei_svc->layers[i].region_height = bs_read_u(b, 16);
            }
        }
        if( sei_svc->layers[i].sub_pic_layer_flag )
        {
            sei_svc->layers[i].roi_id = bs_read_ue(b);
        }
        if( sei_svc->layers[i].iroi_division_info_present_flag )
        {
            sei_svc->layers[i].iroi_grid_flag = bs_read_u1(b);
            if( sei_svc->layers[i].iroi_grid_flag )
            {
                sei_svc->layers[i].grid_width_in_mbs_minus1 = bs_read_ue(b);
                sei_svc->layers[i].grid_height_in_mbs_minus1 = bs_read_ue(b);
            }
            else
            {
                sei_svc->layers[i].num_rois_minus1 = bs_read_ue(b);
                
                for( int j = 0; j <= sei_svc->layers[i].num_rois_minus1; j++ )
                {
                    sei_svc->layers[i].roi[j].first_mb_in_roi = bs_read_ue(b);
                    sei_svc->layers[i].roi[j].roi_width_in_mbs_minus1 = bs_read_ue(b);
                    sei_svc->layers[i].roi[j].roi_height_in_mbs_minus1 = bs_read_ue(b);
                }
            }
        }
        if( sei_svc->layers[i].layer_dependency_info_present_flag )
        {
            sei_svc->layers[i].num_directly_dependent_layers = bs_read_ue(b);
            for( int j = 0; j < sei_svc->layers[i].num_directly_dependent_layers; j++ )
            {
                sei_svc->layers[i].directly_dependent_layer_id_delta_minus1[j] = bs_read_ue(b);
            }
        }
        else
        {
            sei_svc->layers[i].layer_dependency_info_src_layer_id_delta = bs_read_ue(b);
        }
        if( sei_svc->layers[i].parameter_sets_info_present_flag )
        {
            sei_svc->layers[i].num_seq_parameter_sets = bs_read_ue(b);
            for( int j = 0; j < sei_svc->layers[i].num_seq_parameter_sets; j++ )
            {
                sei_svc->layers[i].seq_parameter_set_id_delta[j] = bs_read_ue(b);
            }
            sei_svc->layers[i].num_subset_seq_parameter_sets = bs_read_ue(b);
            for( int j = 0; j < sei_svc->layers[i].num_subset_seq_parameter_sets; j++ )
            {
                sei_svc->layers[i].subset_seq_parameter_set_id_delta[j] = bs_read_ue(b);
            }
            sei_svc->layers[i].num_pic_parameter_sets_minus1 = bs_read_ue(b);
            for( int j = 0; j < sei_svc->layers[i].num_pic_parameter_sets_minus1; j++ )
            {
                sei_svc->layers[i].pic_parameter_set_id_delta[j] = bs_read_ue(b);
            }
        }
        else
        {
            sei_svc->layers[i].parameter_sets_info_src_layer_id_delta = bs_read_ue(b);
        }
        if( sei_svc->layers[i].bitstream_restriction_info_present_flag )
        {
            sei_svc->layers[i].motion_vectors_over_pic_boundaries_flag = bs_read_u1(b);
            sei_svc->layers[i].max_bytes_per_pic_denom = bs_read_ue(b);
            sei_svc->layers[i].max_bits_per_mb_denom = bs_read_ue(b);
            sei_svc->layers[i].log2_max_mv_length_horizontal = bs_read_ue(b);
            sei_svc->layers[i].log2_max_mv_length_vertical = bs_read_ue(b);
            sei_svc->layers[i].max_num_reorder_frames = bs_read_ue(b);
            sei_svc->layers[i].max_dec_frame_buffering = bs_read_ue(b);
        }
        if( sei_svc->layers[i].layer_conversion_flag )
        {
            sei_svc->layers[i].conversion_type_idc = bs_read_ue(b);
            for( int j = 0; j < 2; j++ )
            {
                sei_svc->layers[i].rewriting_info_flag[j] = bs_read_u(b, 1);
                if( sei_svc->layers[i].rewriting_info_flag[j] )
                {
                    sei_svc->layers[i].rewriting_profile_level_idc[j] = bs_read_u(b, 24);
                    sei_svc->layers[i].rewriting_avg_bitrate[j] = bs_read_u(b, 16);
                    sei_svc->layers[i].rewriting_max_bitrate[j] = bs_read_u(b, 16);
                }
            }
        }
    }

    if( sei_svc->priority_layer_info_present_flag )
    {
        sei_svc->pr_num_dIds_minus1 = bs_read_ue(b);
        
        for( int i = 0; i <= sei_svc->pr_num_dIds_minus1; i++ ) {
            sei_svc->pr[i].pr_dependency_id = bs_read_u(b, 3);
            sei_svc->pr[i].pr_num_minus1 = bs_read_ue(b);
            for( int j = 0; j <= sei_svc->pr[i].pr_num_minus1; j++ )
            {
                sei_svc->pr[i].pr_info[j].pr_id = bs_read_ue(b);
                sei_svc->pr[i].pr_info[j].pr_profile_level_idc = bs_read_u(b, 24);
                sei_svc->pr[i].pr_info[j].pr_avg_bitrate = bs_read_u(b, 16);
                sei_svc->pr[i].pr_info[j].pr_max_bitrate = bs_read_u(b, 16);
            }
        }
        
    }

}