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

📄 h264.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* Append the block */    if( p_frag )        block_ChainAppend( &p_sys->p_frame, p_frag );    *pb_used_ts = false;    if( p_sys->i_frame_dts < 0 && p_sys->i_frame_pts < 0 )    {        p_sys->i_frame_dts = i_frag_dts;        p_sys->i_frame_pts = i_frag_pts;        *pb_used_ts = true;    }    return p_pic;}static block_t *OutputPicture( decoder_t *p_dec ){    decoder_sys_t *p_sys = p_dec->p_sys;    block_t *p_pic;    if( !p_sys->b_header && p_sys->slice.i_frame_type != BLOCK_FLAG_TYPE_I)        return NULL;    if( p_sys->slice.i_frame_type == BLOCK_FLAG_TYPE_I && p_sys->b_sps && p_sys->b_pps )    {        block_t *p_list = NULL;        int i;        for( i = 0; i < SPS_MAX; i++ )        {            if( p_sys->pp_sps[i] )                block_ChainAppend( &p_list, block_Duplicate( p_sys->pp_sps[i] ) );        }        for( i = 0; i < PPS_MAX; i++ )        {            if( p_sys->pp_pps[i] )                block_ChainAppend( &p_list, block_Duplicate( p_sys->pp_pps[i] ) );        }        if( p_list )            p_sys->b_header = true;        block_ChainAppend( &p_list, p_sys->p_frame );        p_pic = block_ChainGather( p_list );    }    else    {        p_pic = block_ChainGather( p_sys->p_frame );    }    p_pic->i_dts = p_sys->i_frame_dts;    p_pic->i_pts = p_sys->i_frame_pts;    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->i_frame_dts = -1;    p_sys->i_frame_pts = -1;    p_sys->b_slice = false;    return p_pic;}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 );    /* Skip profile(8), constraint_set012, reserver(5), level(8) */    bs_skip( &s, 8 + 1+1+1 + 5 + 8 );    /* sps id */    i_sps_id = bs_read_ue( &s );    if( i_sps_id >= SPS_MAX )    {        msg_Warn( p_dec, "invalid SPS (sps_id=%d)", i_sps_id );        free( pb_dec );        block_Release( p_frag );        return;    }    /* 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 );    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[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( h != 0 )                p_dec->fmt_out.video.i_aspect = (int64_t)VOUT_ASPECT_FACTOR *                        ( w * p_dec->fmt_out.video.i_width ) /                        ( h * p_dec->fmt_out.video.i_height);            else                p_dec->fmt_out.video.i_aspect = VOUT_ASPECT_FACTOR;        }    }    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;}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;}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_first_mb, 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 */    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;}

⌨️ 快捷键说明

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