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

📄 ps.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    p_sys->b_lost_sync = false;    if( p_sys->i_length < 0 && p_sys->b_seekable )        FindLength( p_demux );    if( ( p_pkt = ps_pkt_read( p_demux->s, i_code ) ) == NULL )    {        return 0;    }    switch( i_code )    {    case 0x1b9:        block_Release( p_pkt );        break;    case 0x1ba:        if( !ps_pkt_parse_pack( p_pkt, &p_sys->i_scr, &i_mux_rate ) )        {            if( !p_sys->b_have_pack ) p_sys->b_have_pack = true;            /* done later on to work around bad vcd/svcd streams */            /* es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_scr ); */            if( i_mux_rate > 0 ) p_sys->i_mux_rate = i_mux_rate;        }        block_Release( p_pkt );        break;    case 0x1bb:        if( !ps_pkt_parse_system( p_pkt, &p_sys->psm, p_sys->tk ) )        {            int i;            for( i = 0; i < PS_TK_COUNT; i++ )            {                ps_track_t *tk = &p_sys->tk[i];                if( tk->b_seen && !tk->es && tk->fmt.i_cat != UNKNOWN_ES )                {                    tk->es = es_out_Add( p_demux->out, &tk->fmt );                }            }        }        block_Release( p_pkt );        break;    case 0x1bc:        if( p_sys->psm.i_version == 0xFFFF )            msg_Dbg( p_demux, "contains a PSM");        ps_psm_fill( &p_sys->psm, p_pkt, p_sys->tk, p_demux->out );        block_Release( p_pkt );        break;    default:        if( (i_id = ps_pkt_id( p_pkt )) >= 0xc0 )        {            bool b_new = false;            ps_track_t *tk = &p_sys->tk[PS_ID_TO_TK(i_id)];            if( !tk->b_seen )            {                if( !ps_track_fill( tk, &p_sys->psm, i_id ) )                {                    tk->es = es_out_Add( p_demux->out, &tk->fmt );                    b_new = true;                }                else                {                    msg_Dbg( p_demux, "es id=0x%x format unknown", i_id );                }                tk->b_seen = true;            }            /* The popular VCD/SVCD subtitling WinSubMux does not             * renumber the SCRs when merging subtitles into the PES */            if( tk->b_seen &&                ( tk->fmt.i_codec == VLC_FOURCC('o','g','t',' ') ||                  tk->fmt.i_codec == VLC_FOURCC('c','v','d',' ') ) )            {                p_sys->i_scr = -1;            }            if( p_sys->i_scr > 0 )                es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_scr );            p_sys->i_scr = -1;            if( tk->b_seen && tk->es &&                (#ifdef ZVBI_COMPILED /* FIXME!! */                tk->fmt.i_codec == VLC_FOURCC('t','e','l','x') ||#endif                !ps_pkt_parse_pes( p_pkt, tk->i_skip ) ) )            {                if( !b_new && !p_sys->b_have_pack &&                    (tk->fmt.i_cat == AUDIO_ES) &&                    (p_pkt->i_pts > 0) )                {                    /* A hack to sync the A/V on PES files. */                    msg_Dbg( p_demux, "force SCR: %"PRId64, p_pkt->i_pts );                    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_pkt->i_pts );                }                if( (int64_t)p_pkt->i_pts > p_sys->i_current_pts )                {                    p_sys->i_current_pts = (int64_t)p_pkt->i_pts;                }                es_out_Send( p_demux->out, tk->es, p_pkt );            }            else            {                block_Release( p_pkt );            }        }        else        {            block_Release( p_pkt );        }        break;    }    return 1;}/***************************************************************************** * Control: *****************************************************************************/static int Control( demux_t *p_demux, int i_query, va_list args ){    demux_sys_t *p_sys = p_demux->p_sys;    double f, *pf;    int64_t i64, *pi64;    switch( i_query )    {        case DEMUX_GET_POSITION:            pf = (double*) va_arg( args, double* );            i64 = stream_Size( p_demux->s );            if( i64 > 0 )            {                *pf = (double)stream_Tell( p_demux->s ) / (double)i64;            }            else            {                *pf = 0.0;            }            return VLC_SUCCESS;        case DEMUX_SET_POSITION:            f = (double) va_arg( args, double );            i64 = stream_Size( p_demux->s );            p_sys->i_current_pts = 0;            es_out_Control( p_demux->out, ES_OUT_RESET_PCR );            return stream_Seek( p_demux->s, (int64_t)(i64 * f) );        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_time_track >= 0 && p_sys->i_current_pts > 0 )            {                *pi64 = p_sys->i_current_pts - p_sys->tk[p_sys->i_time_track].i_first_pts;                return VLC_SUCCESS;            }            if( p_sys->i_mux_rate > 0 )            {                *pi64 = (int64_t)1000000 * ( stream_Tell( p_demux->s ) / 50 ) /                    p_sys->i_mux_rate;                return VLC_SUCCESS;            }            *pi64 = 0;            return VLC_EGENERIC;        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            if( p_sys->i_length > 0 )            {                *pi64 = p_sys->i_length;                return VLC_SUCCESS;            }            else if( p_sys->i_mux_rate > 0 )            {                *pi64 = (int64_t)1000000 * ( stream_Size( p_demux->s ) / 50 ) /                    p_sys->i_mux_rate;                return VLC_SUCCESS;            }            *pi64 = 0;            return VLC_EGENERIC;        case DEMUX_SET_TIME:            i64 = (int64_t)va_arg( args, int64_t );            if( p_sys->i_time_track >= 0 && p_sys->i_current_pts > 0 )            {                int64_t i_now = p_sys->i_current_pts - p_sys->tk[p_sys->i_time_track].i_first_pts;                int64_t i_pos = stream_Tell( p_demux->s );                int64_t i_offset = i_pos / (i_now / 1000000) * ((i64 - i_now) / 1000000);                stream_Seek( p_demux->s, i_pos + i_offset);                es_out_Control( p_demux->out, ES_OUT_RESET_PCR );                return VLC_SUCCESS;            }            return VLC_EGENERIC;        case DEMUX_GET_FPS:        default:            return VLC_EGENERIC;    }}/***************************************************************************** * Divers: *****************************************************************************//* PSResynch: resynch on a system startcode *  It doesn't skip more than 512 bytes *  -1 -> error, 0 -> not synch, 1 -> ok */static int ps_pkt_resynch( stream_t *s, uint32_t *pi_code ){    const uint8_t *p_peek;    int     i_peek;    int     i_skip;    if( stream_Peek( s, &p_peek, 4 ) < 4 )    {        return -1;    }    if( p_peek[0] == 0 && p_peek[1] == 0 && p_peek[2] == 1 &&        p_peek[3] >= 0xb9 )    {        *pi_code = 0x100 | p_peek[3];        return 1;    }    if( ( i_peek = stream_Peek( s, &p_peek, 512 ) ) < 4 )    {        return -1;    }    i_skip = 0;    for( ;; )    {        if( i_peek < 4 )        {            break;        }        if( p_peek[0] == 0 && p_peek[1] == 0 && p_peek[2] == 1 &&            p_peek[3] >= 0xb9 )        {            *pi_code = 0x100 | p_peek[3];            return stream_Read( s, NULL, i_skip ) == i_skip ? 1 : -1;        }        p_peek++;        i_peek--;        i_skip++;    }    return stream_Read( s, NULL, i_skip ) == i_skip ? 0 : -1;}static block_t *ps_pkt_read( stream_t *s, uint32_t i_code ){    const uint8_t *p_peek;    int      i_peek = stream_Peek( s, &p_peek, 14 );    int      i_size = ps_pkt_size( p_peek, i_peek );    VLC_UNUSED(i_code);    if( i_size <= 6 && p_peek[3] > 0xba )    {        /* Special case, search the next start code */        i_size = 6;        for( ;; )        {            i_peek = stream_Peek( s, &p_peek, i_size + 1024 );            if( i_peek <= i_size + 4 )            {                return NULL;            }            while( i_size <= i_peek - 4 )            {                if( p_peek[i_size] == 0x00 && p_peek[i_size+1] == 0x00 &&                    p_peek[i_size+2] == 0x01 && p_peek[i_size+3] >= 0xb9 )                {                    return stream_Block( s, i_size );                }                i_size++;            }        }    }    else    {        /* Normal case */        return stream_Block( s, i_size );    }    return NULL;}

⌨️ 快捷键说明

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