Skip to content
Snippets Groups Projects
avidec.c 37 KiB
Newer Older
  • Learn to ignore specific revisions
  • static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
        AVIContext *avi = s->priv_data;
        AVStream *st;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        int64_t pos;
    
        if (!avi->index_loaded) {
            /* we only load the index on demand */
            avi_load_index(s);
            avi->index_loaded = 1;
        }
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    
        st = s->streams[stream_index];
    
        index= av_index_search_timestamp(st, timestamp, flags);
        if(index<0)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
            return -1;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* find the position */
    
        pos = st->index_entries[index].pos;
        timestamp = st->index_entries[index].timestamp;
    
    
    //    av_log(s, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp);
    
        if (CONFIG_DV_DEMUXER && avi->dv_demux) {
    
            /* One and only one real stream for DV in AVI, and it has video  */
    
            /* offsets. Calling with other stream indexes should have failed */
    
            /* the av_index_search_timestamp call above.                     */
            assert(stream_index == 0);
    
            /* Feed the DV video stream version of the timestamp to the */
    
    Diego Biurrun's avatar
    Diego Biurrun committed
            /* DV demux so it can synthesize correct timestamps.        */
    
            dv_offset_reset(avi->dv_demux, timestamp);
    
    
            url_fseek(s->pb, pos, SEEK_SET);
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        for(i = 0; i < s->nb_streams; i++) {
    
            AVStream *st2 = s->streams[i];
            AVIStream *ast2 = st2->priv_data;
    
    
            ast2->packet_size=
            ast2->remaining= 0;
    
    
    //        assert(st2->codec->block_align);
    
            assert((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
    
                    av_rescale(timestamp, st2->time_base.den*(int64_t)st->time_base.num, st->time_base.den * (int64_t)st2->time_base.num),
                    flags | AVSEEK_FLAG_BACKWARD);
            if(index<0)
                index=0;
    
            if(!avi->non_interleaved){
                while(index>0 && st2->index_entries[index].pos > pos)
                    index--;
                while(index+1 < st2->nb_index_entries && st2->index_entries[index].pos < pos)
                    index++;
            }
    
    
    //        av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp);
    
            /* extract the current frame number */
            ast2->frame_offset = st2->index_entries[index].timestamp;
            if(ast2->sample_size)
                ast2->frame_offset *=ast2->sample_size;
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* do the seek */
    
        url_fseek(s->pb, pos, SEEK_SET);
    
        avi->stream_index= -1;
    
    static int avi_read_close(AVFormatContext *s)
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    {
    
    Michael Niedermayer's avatar
    Michael Niedermayer committed
        int i;
        AVIContext *avi = s->priv_data;
    
        for(i=0;i<s->nb_streams;i++) {
            AVStream *st = s->streams[i];
    
        if (avi->dv_demux)
            av_free(avi->dv_demux);
    
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        return 0;
    }
    
    static int avi_probe(AVProbeData *p)
    {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        /* check file header */
    
        for(i=0; avi_headers[i][0]; i++)
            if(!memcmp(p->buf  , avi_headers[i]  , 4) &&
               !memcmp(p->buf+8, avi_headers[i]+4, 4))
                return AVPROBE_SCORE_MAX;
    
        return 0;
    
    AVInputFormat avi_demuxer = {
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        "avi",
    
        NULL_IF_CONFIG_SMALL("AVI format"),
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        sizeof(AVIContext),
        avi_probe,
        avi_read_header,
        avi_read_packet,
        avi_read_close,
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
        avi_read_seek,
    
    Fabrice Bellard's avatar
    Fabrice Bellard committed
    };