示例#1
0
文件: h264_nal.c 项目: robUx4/vlc
block_t *h264_AnnexB_NAL_to_avcC( uint8_t i_nal_length_size,
                                  const uint8_t *p_sps_buf,
                                  size_t i_sps_size,
                                  const uint8_t *p_pps_buf,
                                  size_t i_pps_size )
{
    if( !hxxx_strip_AnnexB_startcode( &p_sps_buf, &i_sps_size ) ||
        !hxxx_strip_AnnexB_startcode( &p_pps_buf, &i_pps_size ) )
        return NULL;
    return h264_NAL_to_avcC( i_nal_length_size,
                             p_sps_buf, i_sps_size,
                             p_pps_buf, i_pps_size );
}
示例#2
0
文件: h264.c 项目: IAPark/vlc
static void PutPPS( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    const uint8_t *p_buffer = p_frag->p_buffer;
    size_t i_buffer = p_frag->i_buffer;

    if( !hxxx_strip_AnnexB_startcode( &p_buffer, &i_buffer ) )
    {
        block_Release( p_frag );
        return;
    }

    h264_picture_parameter_set_t *p_pps = h264_decode_pps( p_buffer, i_buffer, true );
    if( !p_pps )
    {
        msg_Warn( p_dec, "invalid PPS" );
        block_Release( p_frag );
        return;
    }

    /* We have a new PPS */
    if( !p_sys->pps[p_pps->i_id].p_pps )
        msg_Dbg( p_dec, "found NAL_PPS (pps_id=%d sps_id=%d)", p_pps->i_id, p_pps->i_sps_id );

    StorePPS( p_sys, p_pps->i_id, p_frag, p_pps );
}
示例#3
0
文件: h264_nal.c 项目: maniacs-m/vlc
block_t *h264_AnnexB_NAL_to_avcC( uint8_t i_nal_length_size,
                                           const uint8_t *p_sps_buf,
                                           size_t i_sps_size,
                                           const uint8_t *p_pps_buf,
                                           size_t i_pps_size )
{
    if( i_pps_size > UINT16_MAX || i_sps_size > UINT16_MAX )
        return NULL;

    if( !hxxx_strip_AnnexB_startcode( &p_sps_buf, &i_sps_size ) ||
        !hxxx_strip_AnnexB_startcode( &p_pps_buf, &i_pps_size ) )
        return NULL;

    /* The length of the NAL size is encoded using 1, 2 or 4 bytes */
    if( i_nal_length_size != 1 && i_nal_length_size != 2
     && i_nal_length_size != 4 )
        return NULL;

    bo_t bo;
    /* 6 * int(8), i_sps_size, 1 * int(8), i_pps_size */
    if( bo_init( &bo, 7 + i_sps_size + i_pps_size ) != true )
        return NULL;

    bo_add_8( &bo, 1 ); /* configuration version */
    bo_add_mem( &bo, 3, &p_sps_buf[1] ); /* i_profile/profile_compatibility/level */
    bo_add_8( &bo, 0xfc | (i_nal_length_size - 1) ); /* 0b11111100 | lengthsize - 1*/

    bo_add_8( &bo, 0xe0 | (i_sps_size > 0 ? 1 : 0) ); /* 0b11100000 | sps_count */
    if( i_sps_size )
    {
        bo_add_16be( &bo, i_sps_size );
        bo_add_mem( &bo, i_sps_size, p_sps_buf );
    }

    bo_add_8( &bo, (i_pps_size > 0 ? 1 : 0) ); /* pps_count */
    if( i_pps_size )
    {
        bo_add_16be( &bo, i_pps_size );
        bo_add_mem( &bo, i_pps_size, p_pps_buf );
    }

    return bo.b;
}
示例#4
0
文件: h264.c 项目: r1k/vlc
static void PutSPS( decoder_t *p_dec, block_t *p_frag )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    const uint8_t *p_buffer = p_frag->p_buffer;
    size_t i_buffer = p_frag->i_buffer;

    if( !hxxx_strip_AnnexB_startcode( &p_buffer, &i_buffer ) )
        return;

    h264_sequence_parameter_set_t *p_sps = h264_decode_sps( p_buffer, i_buffer, true );
    if( !p_sps )
    {
        msg_Warn( p_dec, "invalid SPS" );
        block_Release( p_frag );
        return;
    }

    p_dec->fmt_out.i_profile = p_sps->i_profile;
    p_dec->fmt_out.i_level = p_sps->i_level;

    (void) h264_get_picture_size( p_sps, &p_dec->fmt_out.video.i_width,
                                         &p_dec->fmt_out.video.i_height,
                                         &p_dec->fmt_out.video.i_visible_width,
                                         &p_dec->fmt_out.video.i_visible_height );

    if( p_sps->vui.i_sar_num != 0 && p_sps->vui.i_sar_den != 0 )
    {
        p_dec->fmt_out.video.i_sar_num = p_sps->vui.i_sar_num;
        p_dec->fmt_out.video.i_sar_den = p_sps->vui.i_sar_den;
    }

    p_sys->i_log2_max_frame_num = p_sps->i_log2_max_frame_num;
    p_sys->b_frame_mbs_only = p_sps->frame_mbs_only_flag;
    p_sys->i_pic_order_cnt_type = p_sps->i_pic_order_cnt_type;
    p_sys->i_delta_pic_order_always_zero_flag = p_sps->i_delta_pic_order_always_zero_flag;
    p_sys->i_log2_max_pic_order_cnt_lsb = p_sps->i_log2_max_pic_order_cnt_lsb;

    if( p_sps->vui.b_valid )
    {
        p_sys->b_timing_info_present_flag = p_sps->vui.b_timing_info_present_flag;
        p_sys->i_num_units_in_tick =  p_sps->vui.i_num_units_in_tick;
        p_sys->i_time_scale = p_sps->vui.i_time_scale;
        p_sys->b_fixed_frame_rate = p_sps->vui.b_fixed_frame_rate;
        p_sys->b_pic_struct_present_flag = p_sps->vui.b_pic_struct_present_flag;
        p_sys->b_cpb_dpb_delays_present_flag = p_sps->vui.b_hrd_parameters_present_flag;
        p_sys->i_cpb_removal_delay_length_minus1 = p_sps->vui.i_cpb_removal_delay_length_minus1;
        p_sys->i_dpb_output_delay_length_minus1 = p_sps->vui.i_dpb_output_delay_length_minus1;

        if( p_sps->vui.b_fixed_frame_rate && !p_dec->fmt_out.video.i_frame_rate_base )
        {
            p_dec->fmt_out.video.i_frame_rate_base = p_sps->vui.i_num_units_in_tick;
            p_dec->fmt_out.video.i_frame_rate = p_sps->vui.i_time_scale >> 1 /* num_clock_ts == 2 */;
        }
示例#5
0
文件: hevc_nal.c 项目: Akilklk/vlc
/* 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;
}
示例#6
0
文件: h264.c 项目: IAPark/vlc
static bool ParseSliceHeader( decoder_t *p_dec, const block_t *p_frag, h264_slice_t *p_slice )
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    const uint8_t *p_stripped = p_frag->p_buffer;
    size_t i_stripped = p_frag->i_buffer;

    if( !hxxx_strip_AnnexB_startcode( &p_stripped, &i_stripped ) || i_stripped < 2 )
        return false;

    if( !h264_decode_slice( p_stripped, i_stripped, GetSPSPPS, p_sys, p_slice ) )
        return false;

    const h264_sequence_parameter_set_t *p_sps;
    const h264_picture_parameter_set_t *p_pps;
    GetSPSPPS( p_slice->i_pic_parameter_set_id, p_sys, &p_sps, &p_pps );
    if( unlikely( !p_sps || !p_pps) )
        return false;

    ActivateSets( p_dec, p_sps, p_pps );

    return true;
}
示例#7
0
文件: hevc.c 项目: Akilklk/vlc
static block_t *ParseVCL(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag)
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_frame = NULL;

    const uint8_t *p_buffer = p_frag->p_buffer;
    size_t i_buffer = p_frag->i_buffer;

    if(unlikely(!hxxx_strip_AnnexB_startcode(&p_buffer, &i_buffer) || i_buffer < 3))
    {
        block_ChainAppend(&p_sys->p_frame, p_frag); /* might corrupt */
        return NULL;
    }

    bool b_first_slice_in_pic = p_buffer[2] & 0x80;
    if (b_first_slice_in_pic)
    {
        if(p_sys->p_frame)
        {
            /* Starting new frame, gather and return previous frame data */
            p_frame = block_ChainGather(p_sys->p_frame);
            p_sys->p_frame = NULL;
            p_sys->pp_frame_last = &p_sys->p_frame;
        }

        switch(i_nal_type)
        {
            case HEVC_NAL_BLA_W_LP:
            case HEVC_NAL_BLA_W_RADL:
            case HEVC_NAL_BLA_N_LP:
            case HEVC_NAL_IDR_W_RADL:
            case HEVC_NAL_IDR_N_LP:
            case HEVC_NAL_CRA:
                p_frag->i_flags |= BLOCK_FLAG_TYPE_I;
                break;

            default:
            {
                hevc_slice_segment_header_t *p_sli = hevc_decode_slice_header( p_buffer, i_buffer, true,
                                                                               p_sys->rgi_p_decsps, p_sys->rgi_p_decpps );
                if( p_sli )
                {
                    enum hevc_slice_type_e type;
                    if( hevc_get_slice_type( p_sli, &type ) )
                    {
                        if( type == HEVC_SLICE_TYPE_P )
                            p_frag->i_flags |= BLOCK_FLAG_TYPE_P;
                        else
                            p_frag->i_flags |= BLOCK_FLAG_TYPE_B;
                    }
                    hevc_rbsp_release_slice_header( p_sli );
                }
                else p_frag->i_flags |= BLOCK_FLAG_TYPE_B;
            }
            break;
        }
    }

    block_ChainLastAppend(&p_sys->pp_frame_last, p_frag);

    return p_frame;
}
示例#8
0
文件: hevc.c 项目: Akilklk/vlc
static bool InsertXPS(decoder_t *p_dec, uint8_t i_nal_type, uint8_t i_id,
                      block_t *p_nalb)
{
    decoder_sys_t *p_sys = p_dec->p_sys;

    switch(i_nal_type)
    {
        case HEVC_NAL_VPS:
            if(i_id >= HEVC_VPS_MAX)
                return false;
            break;
        case HEVC_NAL_SPS:
            if(i_id >= HEVC_SPS_MAX)
                return false;
            break;
        case HEVC_NAL_PPS:
            if(i_id >= HEVC_PPS_MAX)
                return false;
            break;
        default:
            return false;
    }

    /* Free associated decoded version */
    if(i_nal_type == HEVC_NAL_SPS && p_sys->rgi_p_decsps[i_id])
    {
        hevc_rbsp_release_sps(p_sys->rgi_p_decsps[i_id]);
        p_sys->rgi_p_decsps[i_id] = NULL;
    }
    else if(i_nal_type == HEVC_NAL_PPS && p_sys->rgi_p_decpps[i_id])
    {
        hevc_rbsp_release_pps(p_sys->rgi_p_decpps[i_id]);
        p_sys->rgi_p_decpps[i_id] = NULL;
    }
    else if(i_nal_type == HEVC_NAL_VPS && p_sys->rgi_p_decvps[i_id])
    {
        hevc_rbsp_release_vps(p_sys->rgi_p_decvps[i_id]);
        p_sys->rgi_p_decvps[i_id] = NULL;
    }

    const uint8_t *p_buffer = p_nalb->p_buffer;
    size_t i_buffer = p_nalb->i_buffer;
    if( hxxx_strip_AnnexB_startcode( &p_buffer, &i_buffer ) )
    {
        /* Create decoded entries */
        if(i_nal_type == HEVC_NAL_SPS)
        {
            p_sys->rgi_p_decsps[i_id] = hevc_decode_sps(p_buffer, i_buffer, true);
            if(!p_sys->rgi_p_decsps[i_id])
            {
                msg_Err(p_dec, "Failed decoding SPS id %d", i_id);
                return false;
            }
        }
        else if(i_nal_type == HEVC_NAL_PPS)
        {
            p_sys->rgi_p_decpps[i_id] = hevc_decode_pps(p_buffer, i_buffer, true);
            if(!p_sys->rgi_p_decpps[i_id])
            {
                msg_Err(p_dec, "Failed decoding PPS id %d", i_id);
                return false;
            }
        }
        else if(i_nal_type == HEVC_NAL_VPS)
        {
            p_sys->rgi_p_decvps[i_id] = hevc_decode_vps(p_buffer, i_buffer, true);
            if(!p_sys->rgi_p_decvps[i_id])
            {
                msg_Err(p_dec, "Failed decoding VPS id %d", i_id);
                return false;
            }
        }
        return true;

    }

    return false;
}
示例#9
0
文件: hevc.c 项目: etix/vlc
static block_t *ParseVCL(decoder_t *p_dec, uint8_t i_nal_type, block_t *p_frag)
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    block_t *p_outputchain = NULL;

    const uint8_t *p_buffer = p_frag->p_buffer;
    size_t i_buffer = p_frag->i_buffer;

    if(unlikely(!hxxx_strip_AnnexB_startcode(&p_buffer, &i_buffer) || i_buffer < 3))
    {
        block_ChainLastAppend(&p_sys->frame.pp_chain_last, p_frag); /* might be corrupted */
        return NULL;
    }

    const uint8_t i_layer = hevc_getNALLayer( p_buffer );
    bool b_first_slice_in_pic = p_buffer[2] & 0x80;
    if (b_first_slice_in_pic)
    {
        if(p_sys->frame.p_chain)
        {
            /* Starting new frame: return previous frame data for output */
            p_outputchain = OutputQueues(p_sys, p_sys->b_init_sequence_complete);
        }

        switch(i_nal_type)
        {
            case HEVC_NAL_BLA_W_LP:
            case HEVC_NAL_BLA_W_RADL:
            case HEVC_NAL_BLA_N_LP:
            case HEVC_NAL_IDR_W_RADL:
            case HEVC_NAL_IDR_N_LP:
            case HEVC_NAL_CRA:
                p_frag->i_flags |= BLOCK_FLAG_TYPE_I;
                break;

            default:
            {
                hevc_slice_segment_header_t *p_sli = hevc_decode_slice_header( p_buffer, i_buffer, true,
                                                                               p_sys->rgi_p_decsps, p_sys->rgi_p_decpps );
                if( p_sli )
                {
                    enum hevc_slice_type_e type;
                    if( hevc_get_slice_type( p_sli, &type ) )
                    {
                        if( type == HEVC_SLICE_TYPE_P )
                            p_frag->i_flags |= BLOCK_FLAG_TYPE_P;
                        else
                            p_frag->i_flags |= BLOCK_FLAG_TYPE_B;
                    }
                    hevc_rbsp_release_slice_header( p_sli );
                }
                else p_frag->i_flags |= BLOCK_FLAG_TYPE_B;
            }
            break;
        }
    }

    if(!p_sys->b_init_sequence_complete && i_layer == 0 &&
       (p_frag->i_flags & BLOCK_FLAG_TYPE_I) && XPSReady(p_sys))
    {
        p_sys->b_init_sequence_complete = true;
    }

    if( !p_sys->b_init_sequence_complete )
        cc_storage_reset( p_sys->p_ccs );

    block_ChainLastAppend(&p_sys->frame.pp_chain_last, p_frag);

    return p_outputchain;
}