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

📄 h264.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
            /* Parse the NAL */            if( ( p_pic = ParseNALBlock( p_dec, p_part ) ) )            {                block_ChainAppend( &p_ret, p_pic );            }        }        p += i_size;    }    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, 3 + i_size );    /* Add start code */    p_nal->p_buffer[0] = 0x00;    p_nal->p_buffer[1] = 0x00;    p_nal->p_buffer[2] = 0x01;    /* Copy nalu */    memcpy( &p_nal->p_buffer[3], 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);}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;#define OUTPUT \    do {                                                \        p_pic = block_ChainGather( p_sys->p_frame );    \        p_pic->i_length = 0;    /* FIXME */             \                                                        \        p_sys->p_frame = NULL;                          \        p_sys->b_slice = VLC_FALSE;                     \    } while(0)    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 )            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[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 );                }                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;    }    else if( i_nal_type == NAL_PPS )    {        bs_t s;        bs_init( &s, &p_frag->p_buffer[4], p_frag->i_buffer - 4 );        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;    }    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 + -