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

📄 avi.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
                p_sys->i_time = __MAX( AVI_GetPTS( p_stream ),                                        p_sys->i_time );            }        }#if 1        if( p_sys->i_time )        {            i_date = p_sys->i_time;        }        /* seek for bytes based streams */        for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )        {            if( p_stream->b_activated && p_stream->i_samplesize )            {                AVI_TrackSeek( p_demux, i_stream, i_date );/*                p_sys->i_time = __MAX( AVI_GetPTS( p_stream ), p_sys->i_time );*/            }        }        msg_Dbg( p_demux, "seek: "I64Fd" seconds", p_sys->i_time /1000000 );        /* set true movie time */#endif        if( !p_sys->i_time )        {            p_sys->i_time = i_date;        }#undef p_stream        return VLC_SUCCESS;    }    else    {        msg_Err( p_demux, "shouldn't yet be executed" );        return VLC_EGENERIC;    }}/***************************************************************************** * Control: ***************************************************************************** * *****************************************************************************/static double ControlGetPosition( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    if( p_sys->i_length > 0 )    {        return (double)p_sys->i_time / (double)( p_sys->i_length * (mtime_t)1000000 );    }    else if( stream_Size( p_demux->s ) > 0 )    {        unsigned int i;        int64_t i_tmp;        int64_t i64 = 0;        /* search the more advanced selected es */        for( i = 0; i < p_sys->i_track; i++ )        {            avi_track_t *tk = p_sys->track[i];            if( tk->b_activated && tk->i_idxposc < tk->i_idxnb )            {                i_tmp = tk->p_index[tk->i_idxposc].i_pos +                        tk->p_index[tk->i_idxposc].i_length + 8;                if( i_tmp > i64 )                {                    i64 = i_tmp;                }            }        }        return (double)i64 / stream_Size( p_demux->s );    }    return 0.0;}static int    Control( demux_t *p_demux, int i_query, va_list args ){    demux_sys_t *p_sys = p_demux->p_sys;    int i;    double   f, *pf;    int64_t i64, *pi64;    vlc_meta_t **pp_meta;    switch( i_query )    {        case DEMUX_GET_POSITION:            pf = (double*)va_arg( args, double * );            *pf = ControlGetPosition( p_demux );            return VLC_SUCCESS;        case DEMUX_SET_POSITION:            f = (double)va_arg( args, double );            if( p_sys->b_seekable )            {                i64 = (mtime_t)(1000000.0 * p_sys->i_length * f );                return Seek( p_demux, i64, (int)(f * 100) );            }            else            {                int64_t i_pos = stream_Size( p_demux->s ) * f;                return stream_Seek( p_demux->s, i_pos );            }        case DEMUX_GET_TIME:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = p_sys->i_time;            return VLC_SUCCESS;        case DEMUX_SET_TIME:        {            int i_percent = 0;            i64 = (int64_t)va_arg( args, int64_t );            if( p_sys->i_length > 0 )            {                i_percent = 100 * i64 / (p_sys->i_length*1000000);            }            else if( p_sys->i_time > 0 )            {                i_percent = (int)( 100.0 * ControlGetPosition( p_demux ) *                                   (double)i64 / (double)p_sys->i_time );            }            return Seek( p_demux, i64, i_percent );        }        case DEMUX_GET_LENGTH:            pi64 = (int64_t*)va_arg( args, int64_t * );            *pi64 = p_sys->i_length * (mtime_t)1000000;            return VLC_SUCCESS;        case DEMUX_GET_FPS:            pf = (double*)va_arg( args, double * );            *pf = 0.0;            for( i = 0; i < (int)p_sys->i_track; i++ )            {                avi_track_t *tk = p_sys->track[i];                if( tk->i_cat == VIDEO_ES && tk->i_scale > 0)                {                    *pf = (float)tk->i_rate / (float)tk->i_scale;                    break;                }            }            return VLC_SUCCESS;        case DEMUX_GET_META:            pp_meta = (vlc_meta_t**)va_arg( args, vlc_meta_t** );            *pp_meta = vlc_meta_Duplicate( p_sys->meta );            return VLC_SUCCESS;        default:            return VLC_EGENERIC;    }}/***************************************************************************** * Function to convert pts to chunk or byte *****************************************************************************/static mtime_t AVI_PTSToChunk( avi_track_t *tk, mtime_t i_pts ){    if( !tk->i_scale )        return (mtime_t)0;    return (mtime_t)((int64_t)i_pts *                     (int64_t)tk->i_rate /                     (int64_t)tk->i_scale /                     (int64_t)1000000 );}static mtime_t AVI_PTSToByte( avi_track_t *tk, mtime_t i_pts ){    if( !tk->i_scale || !tk->i_samplesize )        return (mtime_t)0;    return (mtime_t)((int64_t)i_pts *                     (int64_t)tk->i_rate /                     (int64_t)tk->i_scale /                     (int64_t)1000000 *                     (int64_t)tk->i_samplesize );}static mtime_t AVI_GetDPTS( avi_track_t *tk, int64_t i_count ){    mtime_t i_dpts = 0;    if( !tk->i_rate )        return i_dpts;    i_dpts = (mtime_t)( (int64_t)1000000 *                        (int64_t)i_count *                        (int64_t)tk->i_scale /                        (int64_t)tk->i_rate );    if( tk->i_samplesize )    {        return i_dpts / tk->i_samplesize;    }    return i_dpts;}static mtime_t AVI_GetPTS( avi_track_t *tk ){    if( tk->i_samplesize )    {        int64_t i_count = 0;        /* we need a valid entry we will emulate one */        if( tk->i_idxposc == tk->i_idxnb )        {            if( tk->i_idxposc )            {                /* use the last entry */                i_count = tk->p_index[tk->i_idxnb - 1].i_lengthtotal                            + tk->p_index[tk->i_idxnb - 1].i_length;            }        }        else        {            i_count = tk->p_index[tk->i_idxposc].i_lengthtotal;        }        return AVI_GetDPTS( tk, i_count + tk->i_idxposb );    }    else    {        if( tk->i_cat == AUDIO_ES )        {            return AVI_GetDPTS( tk, tk->i_blockno );        }        else        {            return AVI_GetDPTS( tk, tk->i_idxposc );        }    }}static int AVI_StreamChunkFind( demux_t *p_demux, unsigned int i_stream ){    demux_sys_t *p_sys = p_demux->p_sys;    avi_packet_t avi_pk;    int i_loop_count = 0;    /* find first chunk of i_stream that isn't in index */    if( p_sys->i_movi_lastchunk_pos >= p_sys->i_movi_begin + 12 )    {        stream_Seek( p_demux->s, p_sys->i_movi_lastchunk_pos );        if( AVI_PacketNext( p_demux ) )        {            return VLC_EGENERIC;        }    }    else    {        stream_Seek( p_demux->s, p_sys->i_movi_begin + 12 );    }    for( ;; )    {        if( p_demux->b_die ) return VLC_EGENERIC;        if( AVI_PacketGetHeader( p_demux, &avi_pk ) )        {            msg_Warn( p_demux, "cannot get packet header" );            return VLC_EGENERIC;        }        if( avi_pk.i_stream >= p_sys->i_track ||            ( avi_pk.i_cat != AUDIO_ES && avi_pk.i_cat != VIDEO_ES ) )        {            if( AVI_PacketNext( p_demux ) )            {                return VLC_EGENERIC;            }            /* Prevents from eating all the CPU with broken files.             * This value should be low enough so that it doesn't             * affect the reading speed too much. */            if( !(++i_loop_count % 1024) )            {                if( p_demux->b_die ) return VLC_EGENERIC;                msleep( 10000 );                if( !(i_loop_count % (1024 * 10)) )                    msg_Warn( p_demux, "don't seem to find any data..." );            }        }        else        {            /* add this chunk to the index */            avi_entry_t index;            index.i_id = avi_pk.i_fourcc;            index.i_flags =               AVI_GetKeyFlag(p_sys->track[avi_pk.i_stream]->i_codec,                              avi_pk.i_peek);            index.i_pos = avi_pk.i_pos;            index.i_length = avi_pk.i_size;            AVI_IndexAddEntry( p_sys, avi_pk.i_stream, &index );            if( avi_pk.i_stream == i_stream  )            {                return VLC_SUCCESS;            }            if( AVI_PacketNext( p_demux ) )            {                return VLC_EGENERIC;            }        }    }}/* be sure that i_ck will be a valid index entry */static int AVI_StreamChunkSet( demux_t *p_demux, unsigned int i_stream,                               unsigned int i_ck ){    demux_sys_t *p_sys = p_demux->p_sys;    avi_track_t *p_stream = p_sys->track[i_stream];    p_stream->i_idxposc = i_ck;    p_stream->i_idxposb = 0;    if(  i_ck >= p_stream->i_idxnb )    {        p_stream->i_idxposc = p_stream->i_idxnb - 1;        do        {            p_stream->i_idxposc++;            if( AVI_StreamChunkFind( p_demux, i_stream ) )            {                return VLC_EGENERIC;            }        } while( p_stream->i_idxposc < i_ck );    }    return VLC_SUCCESS;}/* XXX FIXME up to now, we assume that all chunk are one after one */static int AVI_StreamBytesSet( demux_t    *p_demux,                               unsigned int i_stream,                               off_t   i_byte ){    demux_sys_t *p_sys = p_demux->p_sys;    avi_track_t *p_stream = p_sys->track[i_stream];    if( ( p_stream->i_idxnb > 0 )        &&( i_byte < p_stream->p_index[p_stream->i_idxnb - 1].i_lengthtotal +                p_stream->p_index[p_stream->i_idxnb - 1].i_length ) )    {        /* index is valid to find the ck */        /* uses dichototmie to be fast enougth */        int i_idxposc = __MIN( p_stream->i_idxposc, p_stream->i_idxnb - 1 );        int i_idxmax  = p_stream->i_idxnb;        int i_idxmin  = 0;        for( ;; )        {            if( p_stream->p_index[i_idxposc].i_lengthtotal > i_byte )            {                i_idxmax  = i_idxposc ;                i_idxposc = ( i_idxmin + i_idxposc ) / 2 ;            }            else            {                if( p_stream->p_index[i_idxposc].i_lengthtotal +                        p_stream->p_index[i_idxposc].i_length <= i_byte)                {                    i_idxmin  = i_idxposc ;                    i_idxposc = (i_idxmax + i_idxposc ) / 2 ;                }                else                {                    p_stream->i_idxposc = i_idxposc;                    p_stream->i_idxposb = i_byte -                            p_stream->p_index[i_idxposc].i_lengthtotal;                    return VLC_SUCCESS;                }            }        }    }    else    {        p_stream->i_idxposc = p_stream->i_idxnb - 1;        p_stream->i_idxposb = 0;        do        {            p_stream->i_idxposc++;            if( AVI_StreamChunkFind( p_demux, i_stream ) )            {                return VLC_EGENERIC;            }        } while( p_stream->p_index[p_stream->i_idxposc].i_lengthtotal +                    p_stream->p_index[p_stream->i_idxposc].i_length <= i_byte );        p_stream->i_idxposb = i_byte -                       p_stream->p_index[p_stream->i_idxposc].i_lengthtotal;        return VLC_SUCCESS;    }}static int AVI_TrackSeek( demux_t *p_demux,                           int i_stream,                           mtime_t i_date ){    demux_sys_t  *p_sys = p_demux->p_sys;    avi_track_t  *tk = p_sys->track[i_stream];#define p_stream    p_sys->track[i_stream]    mtime_t i_oldpts;    i_oldpts = AVI_GetPTS( p_stream );    if( !p_stream->i_samplesize )    {        if( AVI_StreamChunkSet( p_demux,                                i_stream,                                AVI_PTSToChunk( p_stream, i_date ) ) )

⌨️ 快捷键说明

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