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

📄 avi.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
                   else : point on data directly */} avi_track_toread_t;static int Demux_Seekable( demux_t *p_demux ){    demux_sys_t *p_sys = p_demux->p_sys;    unsigned int i_track_count = 0;    unsigned int i_track;    bool b_stream;    /* cannot be more than 100 stream (dcXX or wbXX) */    avi_track_toread_t toread[100];    /* detect new selected/unselected streams */    for( i_track = 0; i_track < p_sys->i_track; i_track++ )    {        avi_track_t *tk = p_sys->track[i_track];        bool  b;        if( p_sys->b_muxed && tk->p_out_muxed )        {            i_track_count++;            tk->b_activated = true;            continue;        }        es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );        if( b && !tk->b_activated )        {            if( p_sys->b_seekable)            {                AVI_TrackSeek( p_demux, i_track, p_sys->i_time );            }            tk->b_activated = true;        }        else if( !b && tk->b_activated )        {            tk->b_activated = false;        }        if( b )        {            i_track_count++;        }    }    if( i_track_count <= 0 )    {        int64_t i_length = p_sys->i_length * (mtime_t)1000000;        p_sys->i_time += 25*1000;  /* read 25ms */        if( i_length > 0 )        {            if( p_sys->i_time >= i_length )                return 0;            return 1;        }        msg_Warn( p_demux, "no track selected, exiting..." );        return 0;    }    /* wait for the good time */    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time + 1 );    p_sys->i_time += 25*1000;  /* read 25ms */    /* init toread */    for( i_track = 0; i_track < p_sys->i_track; i_track++ )    {        avi_track_t *tk = p_sys->track[i_track];        mtime_t i_dpts;        toread[i_track].b_ok = tk->b_activated;        if( tk->i_idxposc < tk->i_idxnb )        {            toread[i_track].i_posf = tk->p_index[tk->i_idxposc].i_pos;           if( tk->i_idxposb > 0 )           {                toread[i_track].i_posf += 8 + tk->i_idxposb;           }        }        else        {            toread[i_track].i_posf = -1;        }        i_dpts = p_sys->i_time - AVI_GetPTS( tk  );        if( tk->i_samplesize )        {            toread[i_track].i_toread = AVI_PTSToByte( tk, __ABS( i_dpts ) );        }        else        {            toread[i_track].i_toread = AVI_PTSToChunk( tk, __ABS( i_dpts ) );        }        if( i_dpts < 0 )        {            toread[i_track].i_toread *= -1;        }    }    b_stream = false;    for( ;; )    {        avi_track_t     *tk;        bool       b_done;        block_t         *p_frame;        off_t i_pos;        unsigned int i;        size_t i_size;        /* search for first chunk to be read */        for( i = 0, b_done = true, i_pos = -1; i < p_sys->i_track; i++ )        {            if( !toread[i].b_ok ||                AVI_GetDPTS( p_sys->track[i],                             toread[i].i_toread ) <= -25 * 1000 )            {                continue;            }            if( toread[i].i_toread > 0 )            {                b_done = false; /* not yet finished */            }            if( toread[i].i_posf > 0 )            {                if( i_pos == -1 || i_pos > toread[i].i_posf )                {                    i_track = i;                    i_pos = toread[i].i_posf;                }            }        }        if( b_done )        {            return( 1 );        }        if( i_pos == -1 )        {            int i_loop_count = 0;            /* no valid index, we will parse directly the stream             * in case we fail we will disable all finished stream */            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( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );                }            }            else            {                stream_Seek( p_demux->s, p_sys->i_movi_begin + 12 );            }            for( ;; )            {                avi_packet_t avi_pk;                if( AVI_PacketGetHeader( p_demux, &avi_pk ) )                {                    msg_Warn( p_demux,                             "cannot get packet header, track disabled" );                    return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );                }                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 ) )                    {                        msg_Warn( p_demux,                                  "cannot skip packet, track disabled" );                        return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );                    }                    /* 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( !vlc_object_alive (p_demux) ) return -1;                        msleep( 10000 );                        if( !(i_loop_count % (1024 * 10)) )                            msg_Warn( p_demux,                                      "don't seem to find any data..." );                    }                    continue;                }                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 );                    i_track = avi_pk.i_stream;                    tk = p_sys->track[i_track];                    /* do we will read this data ? */                    if( AVI_GetDPTS( tk, toread[i_track].i_toread ) > -25*1000 )                    {                        break;                    }                    else                    {                        if( AVI_PacketNext( p_demux ) )                        {                            msg_Warn( p_demux,                                      "cannot skip packet, track disabled" );                            return( AVI_TrackStopFinishedStreams( p_demux ) ? 0 : 1 );                        }                    }                }            }        }        else        {            stream_Seek( p_demux->s, i_pos );        }        /* Set the track to use */        tk = p_sys->track[i_track];        /* read thoses data */        if( tk->i_samplesize )        {            unsigned int i_toread;            if( ( i_toread = toread[i_track].i_toread ) <= 0 )            {                if( tk->i_samplesize > 1 )                {                    i_toread = tk->i_samplesize;                }                else                {                    i_toread = AVI_PTSToByte( tk, 20 * 1000 );                    i_toread = __MAX( i_toread, 100 );                }            }            i_size = __MIN( tk->p_index[tk->i_idxposc].i_length -                                tk->i_idxposb,                            i_toread );        }        else        {            i_size = tk->p_index[tk->i_idxposc].i_length;        }        if( tk->i_idxposb == 0 )        {            i_size += 8; /* need to read and skip header */        }        if( ( p_frame = stream_Block( p_demux->s, __EVEN( i_size ) ) )==NULL )        {            msg_Warn( p_demux, "failed reading data" );            tk->b_activated = false;            toread[i_track].b_ok = false;            continue;        }        if( i_size % 2 )    /* read was padded on word boundary */        {            p_frame->i_buffer--;        }        /* skip header */        if( tk->i_idxposb == 0 )        {            p_frame->p_buffer += 8;            p_frame->i_buffer -= 8;        }        p_frame->i_pts = AVI_GetPTS( tk ) + 1;        if( tk->p_index[tk->i_idxposc].i_flags&AVIIF_KEYFRAME )        {            p_frame->i_flags = BLOCK_FLAG_TYPE_I;        }        else        {            p_frame->i_flags = BLOCK_FLAG_TYPE_PB;        }        /* read data */        if( tk->i_samplesize )        {            if( tk->i_idxposb == 0 )            {                i_size -= 8;            }            toread[i_track].i_toread -= i_size;            tk->i_idxposb += i_size;            if( tk->i_idxposb >=                    tk->p_index[tk->i_idxposc].i_length )            {                tk->i_idxposb = 0;                tk->i_idxposc++;            }        }        else        {            int i_length = tk->p_index[tk->i_idxposc].i_length;            tk->i_idxposc++;            if( tk->i_cat == AUDIO_ES )            {                tk->i_blockno += tk->i_blocksize > 0 ? ( i_length + tk->i_blocksize - 1 ) / tk->i_blocksize : 1;            }            toread[i_track].i_toread--;        }        if( tk->i_idxposc < tk->i_idxnb)        {            toread[i_track].i_posf =                tk->p_index[tk->i_idxposc].i_pos;            if( tk->i_idxposb > 0 )            {                toread[i_track].i_posf += 8 + tk->i_idxposb;            }        }        else        {            toread[i_track].i_posf = -1;        }        b_stream = true; /* at least one read succeed */        if( tk->i_cat != VIDEO_ES )            p_frame->i_dts = p_frame->i_pts;        else        {            p_frame->i_dts = p_frame->i_pts;            p_frame->i_pts = 0;        }        //p_pes->i_rate = p_demux->stream.control.i_rate;        if( tk->p_out_muxed )            stream_DemuxSend( tk->p_out_muxed, p_frame );        else            es_out_Send( p_demux->out, tk->p_es, p_frame );    }}/***************************************************************************** * Demux_UnSeekable: reads and demuxes data packets for unseekable file ***************************************************************************** * Returns -1 in case of error, 0 in case of EOF, 1 otherwise *****************************************************************************/static int Demux_UnSeekable( demux_t *p_demux ){    demux_sys_t     *p_sys = p_demux->p_sys;    avi_track_t *p_stream_master = NULL;    unsigned int i_stream;    unsigned int i_packet;    if( p_sys->b_muxed )    {        msg_Err( p_demux, "Can not yet process muxed avi substreams without seeking" );        return VLC_EGENERIC;    }    es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_sys->i_time + 1 );    /* *** find master stream for data packet skipping algo *** */    /* *** -> first video, if any, or first audio ES *** */    for( i_stream = 0; i_stream < p_sys->i_track; i_stream++ )    {        avi_track_t *tk = p_sys->track[i_stream];        bool  b;        es_out_Control( p_demux->out, ES_OUT_GET_ES_STATE, tk->p_es, &b );        if( b && tk->i_cat == VIDEO_ES )        {            p_stream_master = tk;        }        else if( b )        {            p_stream_master = tk;        }    }    if( !p_stream_master )    {        msg_Warn( p_demux, "no more stream selected" );        return( 0 );

⌨️ 快捷键说明

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