⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 h264.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        if( i_size > 0 )        {            block_t *p_part = nal_get_annexeb( p_dec, p, i_size );            p_part->i_dts = p_block->i_dts;            p_part->i_pts = p_block->i_pts;            /* Parse the NAL */            if( ( p_pic = ParseNALBlock( p_dec, p_part ) ) )            {                block_ChainAppend( &p_ret, p_pic );            }        }        p += i_size;    }    block_Release( p_block );    return p_ret;}static block_t *nal_get_annexeb( decoder_t *p_dec, uint8_t *p, int i_size ){    block_t *p_nal;    p_nal = block_New( p_dec, 4 + i_size );    /* Add start code */    p_nal->p_buffer[0] = 0x00;    p_nal->p_buffer[1] = 0x00;    p_nal->p_buffer[2] = 0x00;    p_nal->p_buffer[3] = 0x01;    /* Copy nalu */    memcpy( &p_nal->p_buffer[4], p, i_size );    return p_nal;}static void nal_get_decoded( uint8_t **pp_ret, int *pi_ret,                             uint8_t *src, int i_src ){    uint8_t *end = &src[i_src];    uint8_t *dst = malloc( i_src );    *pp_ret = dst;    while( src < end )    {        if( src < end - 3 && src[0] == 0x00 && src[1] == 0x00 &&            src[2] == 0x03 )        {            *dst++ = 0x00;            *dst++ = 0x00;            src += 3;            continue;        }        *dst++ = *src++;    }    *pi_ret = dst - *pp_ret;}static inline int bs_read_ue( bs_t *s ){    int i = 0;    while( bs_read1( s ) == 0 && s->p < s->p_end && i < 32 )    {        i++;    }    return( ( 1 << i) - 1 + bs_read( s, i ) );}static inline int bs_read_se( bs_t *s ){    int val = bs_read_ue( s );    return val&0x01 ? (val+1)/2 : -(val/2);}/***************************************************************************** * 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;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -