Statistics
| Branch: | Revision:

ffmpeg / libavformat / avidec.c @ ded3c7da

History | View | Annotate | Download (32.7 KB)

1 de6d9b64 Fabrice Bellard
/*
2 7fbde343 Aurelien Jacobs
 * AVI demuxer
3 19720f15 Fabrice Bellard
 * Copyright (c) 2001 Fabrice Bellard.
4 de6d9b64 Fabrice Bellard
 *
5 b78e7197 Diego Biurrun
 * This file is part of FFmpeg.
6
 *
7
 * FFmpeg is free software; you can redistribute it and/or
8 19720f15 Fabrice Bellard
 * modify it under the terms of the GNU Lesser General Public
9
 * License as published by the Free Software Foundation; either
10 b78e7197 Diego Biurrun
 * version 2.1 of the License, or (at your option) any later version.
11 de6d9b64 Fabrice Bellard
 *
12 b78e7197 Diego Biurrun
 * FFmpeg is distributed in the hope that it will be useful,
13 de6d9b64 Fabrice Bellard
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 19720f15 Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
 * Lesser General Public License for more details.
16 de6d9b64 Fabrice Bellard
 *
17 19720f15 Fabrice Bellard
 * You should have received a copy of the GNU Lesser General Public
18 b78e7197 Diego Biurrun
 * License along with FFmpeg; if not, write to the Free Software
19 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 de6d9b64 Fabrice Bellard
 */
21
#include "avformat.h"
22
#include "avi.h"
23 7458ccbb Roman Shaposhnik
#include "dv.h"
24 9d9f4119 Måns Rullgård
#include "riff.h"
25 de6d9b64 Fabrice Bellard
26 52a0bbff Michael Niedermayer
#undef NDEBUG
27
#include <assert.h>
28
29 de6d9b64 Fabrice Bellard
//#define DEBUG
30 155e9ee9 Fabrice Bellard
//#define DEBUG_SEEK
31
32
typedef struct AVIStream {
33 7c7f3866 Michael Niedermayer
    int64_t frame_offset; /* current frame (video) or byte (audio) counter
34 155e9ee9 Fabrice Bellard
                         (used to compute the pts) */
35 7c7f3866 Michael Niedermayer
    int remaining;
36
    int packet_size;
37
38 155e9ee9 Fabrice Bellard
    int scale;
39 115329f1 Diego Biurrun
    int rate;
40 8223bca5 Michael Niedermayer
    int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
41 115329f1 Diego Biurrun
42 94d1d6c0 Michael Niedermayer
    int64_t cum_len; /* temporary storage (used during seek) */
43 115329f1 Diego Biurrun
44 d2c5f0a4 Michael Niedermayer
    int prefix;                       ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
45
    int prefix_count;
46 155e9ee9 Fabrice Bellard
} AVIStream;
47 de6d9b64 Fabrice Bellard
48
typedef struct {
49 7458ccbb Roman Shaposhnik
    int64_t  riff_end;
50
    int64_t  movi_end;
51 de6d9b64 Fabrice Bellard
    offset_t movi_list;
52 155e9ee9 Fabrice Bellard
    int index_loaded;
53 8f9298f8 Roman Shaposhnik
    int is_odml;
54 7c7f3866 Michael Niedermayer
    int non_interleaved;
55
    int stream_index;
56 ddaae6a9 Roman Shaposhnik
    DVDemuxContext* dv_demux;
57 de6d9b64 Fabrice Bellard
} AVIContext;
58
59 42feef6b Michael Niedermayer
static int avi_load_index(AVFormatContext *s);
60 30a43f2d Michael Niedermayer
static int guess_ni_flag(AVFormatContext *s);
61 42feef6b Michael Niedermayer
62 de6d9b64 Fabrice Bellard
#ifdef DEBUG
63 1101abfe Zdenek Kabelac
static void print_tag(const char *str, unsigned int tag, int size)
64 de6d9b64 Fabrice Bellard
{
65
    printf("%s: tag=%c%c%c%c size=0x%x\n",
66
           str, tag & 0xff,
67
           (tag >> 8) & 0xff,
68
           (tag >> 16) & 0xff,
69
           (tag >> 24) & 0xff,
70
           size);
71
}
72
#endif
73
74 06219cb1 Roman Shaposhnik
static int get_riff(AVIContext *avi, ByteIOContext *pb)
75
{
76 115329f1 Diego Biurrun
    uint32_t tag;
77 06219cb1 Roman Shaposhnik
    /* check RIFF header */
78
    tag = get_le32(pb);
79
80
    if (tag != MKTAG('R', 'I', 'F', 'F'))
81
        return -1;
82
    avi->riff_end = get_le32(pb);   /* RIFF chunk size */
83
    avi->riff_end += url_ftell(pb); /* RIFF chunk end */
84
    tag = get_le32(pb);
85
    if (tag != MKTAG('A', 'V', 'I', ' ') && tag != MKTAG('A', 'V', 'I', 'X'))
86
        return -1;
87 115329f1 Diego Biurrun
88 06219cb1 Roman Shaposhnik
    return 0;
89
}
90
91 94d1d6c0 Michael Niedermayer
static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
92 8945ebb9 Michael Niedermayer
    AVIContext *avi = s->priv_data;
93 94d1d6c0 Michael Niedermayer
    ByteIOContext *pb = &s->pb;
94
    int longs_pre_entry= get_le16(pb);
95
    int index_sub_type = get_byte(pb);
96
    int index_type     = get_byte(pb);
97
    int entries_in_use = get_le32(pb);
98
    int chunk_id       = get_le32(pb);
99
    int64_t base       = get_le64(pb);
100
    int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
101
    AVStream *st;
102
    AVIStream *ast;
103
    int i;
104 8945ebb9 Michael Niedermayer
    int64_t last_pos= -1;
105 965a63af Michael Niedermayer
    int64_t filesize= url_fsize(&s->pb);
106 94d1d6c0 Michael Niedermayer
107 965a63af Michael Niedermayer
#ifdef DEBUG_SEEK
108 949b1a13 Steve L'Homme
    av_log(s, AV_LOG_ERROR, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
109 965a63af Michael Niedermayer
        longs_pre_entry,index_type, entries_in_use, chunk_id, base);
110
#endif
111 94d1d6c0 Michael Niedermayer
112
    if(stream_id > s->nb_streams || stream_id < 0)
113
        return -1;
114
    st= s->streams[stream_id];
115
    ast = st->priv_data;
116
117
    if(index_sub_type)
118
        return -1;
119
120
    get_le32(pb);
121
122
    if(index_type && longs_pre_entry != 2)
123
        return -1;
124
    if(index_type>1)
125
        return -1;
126
127 965a63af Michael Niedermayer
    if(filesize > 0 && base >= filesize){
128
        av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
129
        if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
130
            base &= 0xFFFFFFFF;
131
        else
132
            return -1;
133
    }
134
135 94d1d6c0 Michael Niedermayer
    for(i=0; i<entries_in_use; i++){
136
        if(index_type){
137 30a43f2d Michael Niedermayer
            int64_t pos= get_le32(pb) + base - 8;
138 94d1d6c0 Michael Niedermayer
            int len    = get_le32(pb);
139 30a43f2d Michael Niedermayer
            int key= len >= 0;
140 94d1d6c0 Michael Niedermayer
            len &= 0x7FFFFFFF;
141
142 965a63af Michael Niedermayer
#ifdef DEBUG_SEEK
143 949b1a13 Steve L'Homme
            av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
144 965a63af Michael Niedermayer
#endif
145 8945ebb9 Michael Niedermayer
            if(last_pos == pos || pos == base - 8)
146
                avi->non_interleaved= 1;
147
            else
148 2b70eb2b Michael Niedermayer
                av_add_index_entry(st, pos, ast->cum_len / FFMAX(1, ast->sample_size), len, 0, key ? AVINDEX_KEYFRAME : 0);
149 30a43f2d Michael Niedermayer
150 94d1d6c0 Michael Niedermayer
            if(ast->sample_size)
151 2b70eb2b Michael Niedermayer
                ast->cum_len += len;
152 94d1d6c0 Michael Niedermayer
            else
153
                ast->cum_len ++;
154 8945ebb9 Michael Niedermayer
            last_pos= pos;
155 94d1d6c0 Michael Niedermayer
        }else{
156 26b89135 Måns Rullgård
            int64_t offset, pos;
157
            int duration;
158
            offset = get_le64(pb);
159
            get_le32(pb);       /* size */
160
            duration = get_le32(pb);
161
            pos = url_ftell(pb);
162 94d1d6c0 Michael Niedermayer
163
            url_fseek(pb, offset+8, SEEK_SET);
164
            read_braindead_odml_indx(s, frame_num);
165
            frame_num += duration;
166
167
            url_fseek(pb, pos, SEEK_SET);
168
        }
169
    }
170 965a63af Michael Niedermayer
    avi->index_loaded=1;
171 94d1d6c0 Michael Niedermayer
    return 0;
172
}
173
174 115e8ae5 Michael Niedermayer
static void clean_index(AVFormatContext *s){
175 965a63af Michael Niedermayer
    int i;
176
    int64_t j;
177 115e8ae5 Michael Niedermayer
178
    for(i=0; i<s->nb_streams; i++){
179
        AVStream *st = s->streams[i];
180
        AVIStream *ast = st->priv_data;
181
        int n= st->nb_index_entries;
182
        int max= ast->sample_size;
183
        int64_t pos, size, ts;
184
185
        if(n != 1 || ast->sample_size==0)
186
            continue;
187
188
        while(max < 1024) max+=max;
189
190
        pos= st->index_entries[0].pos;
191
        size= st->index_entries[0].size;
192
        ts= st->index_entries[0].timestamp;
193
194
        for(j=0; j<size; j+=max){
195
            av_add_index_entry(st, pos+j, ts + j/ast->sample_size, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
196
        }
197
    }
198
}
199
200 57060f89 David Conrad
static int avi_read_tag(ByteIOContext *pb, char *buf, int maxlen,  unsigned int size)
201
{
202
    offset_t i = url_ftell(pb);
203
    size += (size & 1);
204
    get_strz(pb, buf, maxlen);
205
    url_fseek(pb, i+size, SEEK_SET);
206
    return 0;
207
}
208
209 1101abfe Zdenek Kabelac
static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
210 de6d9b64 Fabrice Bellard
{
211 c9a65ca8 Fabrice Bellard
    AVIContext *avi = s->priv_data;
212 de6d9b64 Fabrice Bellard
    ByteIOContext *pb = &s->pb;
213 deb0a292 Roman Shaposhnik
    uint32_t tag, tag1, handler;
214 b53f1064 Michael Niedermayer
    int codec_type, stream_index, frame_period, bit_rate;
215 247eadca Fabrice Bellard
    unsigned int size, nb_frames;
216
    int i, n;
217 de6d9b64 Fabrice Bellard
    AVStream *st;
218 26b89135 Måns Rullgård
    AVIStream *ast = NULL;
219 2ad4648f Panagiotis Issaris
    char str_track[4];
220 de6d9b64 Fabrice Bellard
221 7c7f3866 Michael Niedermayer
    avi->stream_index= -1;
222 115329f1 Diego Biurrun
223 06219cb1 Roman Shaposhnik
    if (get_riff(avi, pb) < 0)
224 de6d9b64 Fabrice Bellard
        return -1;
225 1101abfe Zdenek Kabelac
226 de6d9b64 Fabrice Bellard
    /* first list tag */
227
    stream_index = -1;
228
    codec_type = -1;
229
    frame_period = 0;
230
    for(;;) {
231
        if (url_feof(pb))
232
            goto fail;
233
        tag = get_le32(pb);
234
        size = get_le32(pb);
235
#ifdef DEBUG
236
        print_tag("tag", tag, size);
237
#endif
238
239
        switch(tag) {
240
        case MKTAG('L', 'I', 'S', 'T'):
241
            /* ignored, except when start of video packets */
242
            tag1 = get_le32(pb);
243
#ifdef DEBUG
244
            print_tag("list", tag1, 0);
245
#endif
246
            if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
247 155e9ee9 Fabrice Bellard
                avi->movi_list = url_ftell(pb) - 4;
248 2064c77a David Conrad
                if(size) avi->movi_end = avi->movi_list + size + (size & 1);
249 a965c478 Aurelien Jacobs
                else     avi->movi_end = url_fsize(pb);
250 de6d9b64 Fabrice Bellard
#ifdef DEBUG
251 949b1a13 Steve L'Homme
                printf("movi end=%"PRIx64"\n", avi->movi_end);
252 de6d9b64 Fabrice Bellard
#endif
253
                goto end_of_header;
254
            }
255
            break;
256 8f9298f8 Roman Shaposhnik
        case MKTAG('d', 'm', 'l', 'h'):
257 bb270c08 Diego Biurrun
            avi->is_odml = 1;
258
            url_fskip(pb, size + (size & 1));
259
            break;
260 de6d9b64 Fabrice Bellard
        case MKTAG('a', 'v', 'i', 'h'):
261 bb270c08 Diego Biurrun
            /* avi header */
262 1101abfe Zdenek Kabelac
            /* using frame_period is bad idea */
263 de6d9b64 Fabrice Bellard
            frame_period = get_le32(pb);
264
            bit_rate = get_le32(pb) * 8;
265 1894edeb Michael Niedermayer
            get_le32(pb);
266
            avi->non_interleaved |= get_le32(pb) & AVIF_MUSTUSEINDEX;
267
268
            url_fskip(pb, 2 * 4);
269 247eadca Fabrice Bellard
            n = get_le32(pb);
270
            for(i=0;i<n;i++) {
271 155e9ee9 Fabrice Bellard
                AVIStream *ast;
272 7458ccbb Roman Shaposhnik
                st = av_new_stream(s, i);
273 de6d9b64 Fabrice Bellard
                if (!st)
274
                    goto fail;
275 9ee91c2f Michael Niedermayer
276 155e9ee9 Fabrice Bellard
                ast = av_mallocz(sizeof(AVIStream));
277
                if (!ast)
278
                    goto fail;
279
                st->priv_data = ast;
280 bb270c08 Diego Biurrun
            }
281 de6d9b64 Fabrice Bellard
            url_fskip(pb, size - 7 * 4);
282
            break;
283
        case MKTAG('s', 't', 'r', 'h'):
284
            /* stream header */
285
            stream_index++;
286
            tag1 = get_le32(pb);
287 7458ccbb Roman Shaposhnik
            handler = get_le32(pb); /* codec tag */
288 cc11e2b3 Michael Niedermayer
#ifdef DEBUG
289 e344c1ea Steve L'Homme
            print_tag("strh", tag1, -1);
290 cc11e2b3 Michael Niedermayer
#endif
291 b53f1064 Michael Niedermayer
            if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){
292 6eb2de74 Roman Shaposhnik
                int64_t dv_dur;
293
294 115329f1 Diego Biurrun
                /*
295 bb270c08 Diego Biurrun
                 * After some consideration -- I don't think we
296
                 * have to support anything but DV in a type1 AVIs.
297
                 */
298
                if (s->nb_streams != 1)
299
                    goto fail;
300
301
                if (handler != MKTAG('d', 'v', 's', 'd') &&
302
                    handler != MKTAG('d', 'v', 'h', 'd') &&
303
                    handler != MKTAG('d', 'v', 's', 'l'))
304
                   goto fail;
305
306
                ast = s->streams[0]->priv_data;
307
                av_freep(&s->streams[0]->codec->extradata);
308
                av_freep(&s->streams[0]);
309
                s->nb_streams = 0;
310 a2a6332b Aurelien Jacobs
                if (ENABLE_DV_DEMUXER) {
311 38ca53da Aurelien Jacobs
                    avi->dv_demux = dv_init_demux(s);
312
                    if (!avi->dv_demux)
313
                        goto fail;
314 a2a6332b Aurelien Jacobs
                }
315 bb270c08 Diego Biurrun
                s->streams[0]->priv_data = ast;
316
                url_fskip(pb, 3 * 4);
317
                ast->scale = get_le32(pb);
318
                ast->rate = get_le32(pb);
319 6eb2de74 Roman Shaposhnik
                url_fskip(pb, 4);  /* start time */
320
321
                dv_dur = get_le32(pb);
322
                if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
323
                    dv_dur *= AV_TIME_BASE;
324
                    s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
325
                }
326
                /*
327
                 * else, leave duration alone; timing estimation in utils.c
328
                 *      will make a guess based on bit rate.
329
                 */
330
331 bb270c08 Diego Biurrun
                stream_index = s->nb_streams - 1;
332 6eb2de74 Roman Shaposhnik
                url_fskip(pb, size - 9*4);
333 b53f1064 Michael Niedermayer
                break;
334
            }
335 b559b29b Michael Niedermayer
336 b53f1064 Michael Niedermayer
            if (stream_index >= s->nb_streams) {
337
                url_fskip(pb, size - 8);
338 1c6606e2 Kostya Shishkov
                /* ignore padding stream */
339
                if (tag1 == MKTAG('p', 'a', 'd', 's'))
340
                    stream_index--;
341 b53f1064 Michael Niedermayer
                break;
342 115329f1 Diego Biurrun
            }
343 b53f1064 Michael Niedermayer
            st = s->streams[stream_index];
344
            ast = st->priv_data;
345 01f4895c Michael Niedermayer
            st->codec->stream_codec_tag= handler;
346 b559b29b Michael Niedermayer
347 b53f1064 Michael Niedermayer
            get_le32(pb); /* flags */
348
            get_le16(pb); /* priority */
349
            get_le16(pb); /* language */
350
            get_le32(pb); /* initial frame */
351
            ast->scale = get_le32(pb);
352
            ast->rate = get_le32(pb);
353
            if(ast->scale && ast->rate){
354
            }else if(frame_period){
355
                ast->rate = 1000000;
356
                ast->scale = frame_period;
357
            }else{
358
                ast->rate = 25;
359
                ast->scale = 1;
360
            }
361
            av_set_pts_info(st, 64, ast->scale, ast->rate);
362 115329f1 Diego Biurrun
363 b72a2bc8 Michael Niedermayer
            ast->cum_len=get_le32(pb); /* start */
364 b53f1064 Michael Niedermayer
            nb_frames = get_le32(pb);
365 b559b29b Michael Niedermayer
366 b53f1064 Michael Niedermayer
            st->start_time = 0;
367 c0df9d75 Michael Niedermayer
            st->duration = nb_frames;
368 b53f1064 Michael Niedermayer
            get_le32(pb); /* buffer size */
369
            get_le32(pb); /* quality */
370
            ast->sample_size = get_le32(pb); /* sample ssize */
371 2b70eb2b Michael Niedermayer
            ast->cum_len *= FFMAX(1, ast->sample_size);
372 b53f1064 Michael Niedermayer
//            av_log(NULL, AV_LOG_DEBUG, "%d %d %d %d\n", ast->rate, ast->scale, ast->start, ast->sample_size);
373 247eadca Fabrice Bellard
374 b53f1064 Michael Niedermayer
            switch(tag1) {
375 bb270c08 Diego Biurrun
            case MKTAG('v', 'i', 'd', 's'):
376 b53f1064 Michael Niedermayer
                codec_type = CODEC_TYPE_VIDEO;
377 247eadca Fabrice Bellard
378 b53f1064 Michael Niedermayer
                ast->sample_size = 0;
379
                break;
380
            case MKTAG('a', 'u', 'd', 's'):
381
                codec_type = CODEC_TYPE_AUDIO;
382 9bf9a5fc Michael Niedermayer
                break;
383 cc11e2b3 Michael Niedermayer
            case MKTAG('t', 'x', 't', 's'):
384 115329f1 Diego Biurrun
                //FIXME
385 cc11e2b3 Michael Niedermayer
                codec_type = CODEC_TYPE_DATA; //CODEC_TYPE_SUB ?  FIXME
386
                break;
387 30667f42 Michael Niedermayer
            case MKTAG('p', 'a', 'd', 's'):
388
                codec_type = CODEC_TYPE_UNKNOWN;
389
                stream_index--;
390
                break;
391 9bf9a5fc Michael Niedermayer
            default:
392 30667f42 Michael Niedermayer
                av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1);
393 9bf9a5fc Michael Niedermayer
                goto fail;
394 de6d9b64 Fabrice Bellard
            }
395 2b70eb2b Michael Niedermayer
            ast->frame_offset= ast->cum_len;
396 b53f1064 Michael Niedermayer
            url_fskip(pb, size - 12 * 4);
397 de6d9b64 Fabrice Bellard
            break;
398
        case MKTAG('s', 't', 'r', 'f'):
399
            /* stream header */
400 db69c2e5 Diego Biurrun
            if (stream_index >= s->nb_streams || avi->dv_demux) {
401 de6d9b64 Fabrice Bellard
                url_fskip(pb, size);
402
            } else {
403
                st = s->streams[stream_index];
404
                switch(codec_type) {
405
                case CODEC_TYPE_VIDEO:
406
                    get_le32(pb); /* size */
407 01f4895c Michael Niedermayer
                    st->codec->width = get_le32(pb);
408
                    st->codec->height = get_le32(pb);
409 de6d9b64 Fabrice Bellard
                    get_le16(pb); /* panes */
410 01f4895c Michael Niedermayer
                    st->codec->bits_per_sample= get_le16(pb); /* depth */
411 de6d9b64 Fabrice Bellard
                    tag1 = get_le32(pb);
412 b559b29b Michael Niedermayer
                    get_le32(pb); /* ImageSize */
413
                    get_le32(pb); /* XPelsPerMeter */
414
                    get_le32(pb); /* YPelsPerMeter */
415
                    get_le32(pb); /* ClrUsed */
416
                    get_le32(pb); /* ClrImportant */
417
418 e344c1ea Steve L'Homme
                    if(size > 10*4 && size<(1<<30)){
419
                        st->codec->extradata_size= size - 10*4;
420
                        st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
421
                        get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
422
                    }
423 115329f1 Diego Biurrun
424 01f4895c Michael Niedermayer
                    if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
425 952c69c4 Michael Niedermayer
                        get_byte(pb);
426 b559b29b Michael Niedermayer
427 5e29abf8 Roberto Togni
                    /* Extract palette from extradata if bpp <= 8 */
428
                    /* This code assumes that extradata contains only palette */
429
                    /* This is true for all paletted codecs implemented in ffmpeg */
430 01f4895c Michael Niedermayer
                    if (st->codec->extradata_size && (st->codec->bits_per_sample <= 8)) {
431
                        st->codec->palctrl = av_mallocz(sizeof(AVPaletteControl));
432 5e29abf8 Roberto Togni
#ifdef WORDS_BIGENDIAN
433 01f4895c Michael Niedermayer
                        for (i = 0; i < FFMIN(st->codec->extradata_size, AVPALETTE_SIZE)/4; i++)
434
                            st->codec->palctrl->palette[i] = bswap_32(((uint32_t*)st->codec->extradata)[i]);
435 5e29abf8 Roberto Togni
#else
436 01f4895c Michael Niedermayer
                        memcpy(st->codec->palctrl->palette, st->codec->extradata,
437
                               FFMIN(st->codec->extradata_size, AVPALETTE_SIZE));
438 5e29abf8 Roberto Togni
#endif
439 01f4895c Michael Niedermayer
                        st->codec->palctrl->palette_changed = 1;
440 5e29abf8 Roberto Togni
                    }
441
442 de6d9b64 Fabrice Bellard
#ifdef DEBUG
443
                    print_tag("video", tag1, 0);
444
#endif
445 01f4895c Michael Niedermayer
                    st->codec->codec_type = CODEC_TYPE_VIDEO;
446
                    st->codec->codec_tag = tag1;
447
                    st->codec->codec_id = codec_get_id(codec_bmp_tags, tag1);
448 7cbaa7ba Michael Niedermayer
                    st->need_parsing = 2; //only parse headers dont do slower repacketization, this is needed to get the pict type which is needed for generating correct pts
449 b559b29b Michael Niedermayer
//                    url_fskip(pb, size - 5 * 4);
450 de6d9b64 Fabrice Bellard
                    break;
451 9bf9a5fc Michael Niedermayer
                case CODEC_TYPE_AUDIO:
452 01f4895c Michael Niedermayer
                    get_wav_header(pb, st->codec, size);
453 e84dab5f Michael Niedermayer
                    if(ast->sample_size && st->codec->block_align && ast->sample_size % st->codec->block_align)
454
                        av_log(s, AV_LOG_DEBUG, "invalid sample size or block align detected\n");
455 1cef9527 François Revol
                    if (size%2) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
456
                        url_fskip(pb, 1);
457 5836d158 Diego Biurrun
                    /* Force parsing as several audio frames can be in
458
                     * one packet. */
459 155e9ee9 Fabrice Bellard
                    st->need_parsing = 1;
460 cbee7a69 Baptiste Coudurier
                    /* ADTS header is in extradata, AAC without header must be stored as exact frames, parser not needed and it will fail */
461
                    if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size)
462
                        st->need_parsing = 0;
463 8662900b Diego Biurrun
                    /* AVI files with Xan DPCM audio (wrongly) declare PCM
464
                     * audio in the header but have Axan as stream_code_tag. */
465
                    if (st->codec->stream_codec_tag == ff_get_fourcc("Axan")){
466
                        st->codec->codec_id  = CODEC_ID_XAN_DPCM;
467
                        st->codec->codec_tag = 0;
468
                    }
469 de6d9b64 Fabrice Bellard
                    break;
470
                default:
471 01f4895c Michael Niedermayer
                    st->codec->codec_type = CODEC_TYPE_DATA;
472
                    st->codec->codec_id= CODEC_ID_NONE;
473
                    st->codec->codec_tag= 0;
474 de6d9b64 Fabrice Bellard
                    url_fskip(pb, size);
475
                    break;
476
                }
477
            }
478
            break;
479 94d1d6c0 Michael Niedermayer
        case MKTAG('i', 'n', 'd', 'x'):
480
            i= url_ftell(pb);
481 2c00106c Michael Niedermayer
            if(!url_is_streamed(pb) && !(s->flags & AVFMT_FLAG_IGNIDX)){
482 b7b22558 Michael Niedermayer
                read_braindead_odml_indx(s, 0);
483
            }
484 94d1d6c0 Michael Niedermayer
            url_fseek(pb, i+size, SEEK_SET);
485
            break;
486 57060f89 David Conrad
        case MKTAG('I', 'N', 'A', 'M'):
487
            avi_read_tag(pb, s->title, sizeof(s->title), size);
488
            break;
489
        case MKTAG('I', 'A', 'R', 'T'):
490
            avi_read_tag(pb, s->author, sizeof(s->author), size);
491
            break;
492
        case MKTAG('I', 'C', 'O', 'P'):
493
            avi_read_tag(pb, s->copyright, sizeof(s->copyright), size);
494
            break;
495
        case MKTAG('I', 'C', 'M', 'T'):
496
            avi_read_tag(pb, s->comment, sizeof(s->comment), size);
497
            break;
498
        case MKTAG('I', 'G', 'N', 'R'):
499
            avi_read_tag(pb, s->genre, sizeof(s->genre), size);
500
            break;
501 f0861f46 Panagiotis Issaris
        case MKTAG('I', 'P', 'R', 'D'):
502
            avi_read_tag(pb, s->album, sizeof(s->album), size);
503
            break;
504 2ad4648f Panagiotis Issaris
        case MKTAG('I', 'P', 'R', 'T'):
505
            avi_read_tag(pb, str_track, sizeof(str_track), size);
506
            sscanf(str_track, "%d", &s->track);
507
            break;
508 de6d9b64 Fabrice Bellard
        default:
509
            /* skip tag */
510
            size += (size & 1);
511
            url_fskip(pb, size);
512
            break;
513
        }
514
    }
515
 end_of_header:
516
    /* check stream number */
517
    if (stream_index != s->nb_streams - 1) {
518
    fail:
519
        for(i=0;i<s->nb_streams;i++) {
520 01f4895c Michael Niedermayer
            av_freep(&s->streams[i]->codec->extradata);
521 9145f8b3 Michael Niedermayer
            av_freep(&s->streams[i]);
522 de6d9b64 Fabrice Bellard
        }
523
        return -1;
524
    }
525 1101abfe Zdenek Kabelac
526 b7b22558 Michael Niedermayer
    if(!avi->index_loaded && !url_is_streamed(pb))
527 94d1d6c0 Michael Niedermayer
        avi_load_index(s);
528 42feef6b Michael Niedermayer
    avi->index_loaded = 1;
529 30a43f2d Michael Niedermayer
    avi->non_interleaved |= guess_ni_flag(s);
530 115e8ae5 Michael Niedermayer
    if(avi->non_interleaved)
531
        clean_index(s);
532 115329f1 Diego Biurrun
533 de6d9b64 Fabrice Bellard
    return 0;
534
}
535
536 1101abfe Zdenek Kabelac
static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
537 de6d9b64 Fabrice Bellard
{
538
    AVIContext *avi = s->priv_data;
539
    ByteIOContext *pb = &s->pb;
540 8f9298f8 Roman Shaposhnik
    int n, d[8], size;
541 4a8d5135 Michael Niedermayer
    offset_t i, sync;
542 7458ccbb Roman Shaposhnik
    void* dstr;
543 115329f1 Diego Biurrun
544 a2a6332b Aurelien Jacobs
    if (ENABLE_DV_DEMUXER && avi->dv_demux) {
545 7458ccbb Roman Shaposhnik
        size = dv_get_packet(avi->dv_demux, pkt);
546 bb270c08 Diego Biurrun
        if (size >= 0)
547
            return size;
548 2af7e610 Fabrice Bellard
    }
549 115329f1 Diego Biurrun
550 7c7f3866 Michael Niedermayer
    if(avi->non_interleaved){
551 79396ac6 Måns Rullgård
        int best_stream_index = 0;
552 7c7f3866 Michael Niedermayer
        AVStream *best_st= NULL;
553
        AVIStream *best_ast;
554
        int64_t best_ts= INT64_MAX;
555
        int i;
556 115329f1 Diego Biurrun
557 7c7f3866 Michael Niedermayer
        for(i=0; i<s->nb_streams; i++){
558
            AVStream *st = s->streams[i];
559
            AVIStream *ast = st->priv_data;
560
            int64_t ts= ast->frame_offset;
561
562
            if(ast->sample_size)
563
                ts /= ast->sample_size;
564
            ts= av_rescale(ts, AV_TIME_BASE * (int64_t)st->time_base.num, st->time_base.den);
565
566 949b1a13 Steve L'Homme
//            av_log(NULL, AV_LOG_DEBUG, "%"PRId64" %d/%d %"PRId64"\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset);
567 7c7f3866 Michael Niedermayer
            if(ts < best_ts){
568
                best_ts= ts;
569
                best_st= st;
570
                best_stream_index= i;
571
            }
572
        }
573
        best_ast = best_st->priv_data;
574
        best_ts= av_rescale(best_ts, best_st->time_base.den, AV_TIME_BASE * (int64_t)best_st->time_base.num); //FIXME a little ugly
575
        if(best_ast->remaining)
576
            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
577
        else
578
            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
579
580
//        av_log(NULL, AV_LOG_DEBUG, "%d\n", i);
581
        if(i>=0){
582
            int64_t pos= best_st->index_entries[i].pos;
583 5c89153e Michael Niedermayer
            pos += best_ast->packet_size - best_ast->remaining;
584 1894edeb Michael Niedermayer
            url_fseek(&s->pb, pos + 8, SEEK_SET);
585 949b1a13 Steve L'Homme
//        av_log(NULL, AV_LOG_DEBUG, "pos=%"PRId64"\n", pos);
586 115329f1 Diego Biurrun
587 8223bca5 Michael Niedermayer
            assert(best_ast->remaining <= best_ast->packet_size);
588
589 1894edeb Michael Niedermayer
            avi->stream_index= best_stream_index;
590
            if(!best_ast->remaining)
591 8223bca5 Michael Niedermayer
                best_ast->packet_size=
592 1894edeb Michael Niedermayer
                best_ast->remaining= best_st->index_entries[i].size;
593 7c7f3866 Michael Niedermayer
        }
594
    }
595 115329f1 Diego Biurrun
596 4a8d5135 Michael Niedermayer
resync:
597 7c7f3866 Michael Niedermayer
    if(avi->stream_index >= 0){
598
        AVStream *st= s->streams[ avi->stream_index ];
599
        AVIStream *ast= st->priv_data;
600
        int size;
601 115329f1 Diego Biurrun
602 e84dab5f Michael Niedermayer
        if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
603 7c7f3866 Michael Niedermayer
            size= INT_MAX;
604 115329f1 Diego Biurrun
        else if(ast->sample_size < 32)
605 7c7f3866 Michael Niedermayer
            size= 64*ast->sample_size;
606
        else
607
            size= ast->sample_size;
608
609
        if(size > ast->remaining)
610
            size= ast->remaining;
611 2692067a Michael Niedermayer
        av_get_packet(pb, pkt, size);
612 115329f1 Diego Biurrun
613 a2a6332b Aurelien Jacobs
        if (ENABLE_DV_DEMUXER && avi->dv_demux) {
614 7c7f3866 Michael Niedermayer
            dstr = pkt->destruct;
615
            size = dv_produce_packet(avi->dv_demux, pkt,
616
                                    pkt->data, pkt->size);
617
            pkt->destruct = dstr;
618
            pkt->flags |= PKT_FLAG_KEY;
619
        } else {
620
            /* XXX: how to handle B frames in avi ? */
621
            pkt->dts = ast->frame_offset;
622
//                pkt->dts += ast->start;
623
            if(ast->sample_size)
624
                pkt->dts /= ast->sample_size;
625 949b1a13 Steve L'Homme
//av_log(NULL, AV_LOG_DEBUG, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n", pkt->dts, ast->frame_offset, ast->scale, ast->rate, ast->sample_size, AV_TIME_BASE, avi->stream_index, size);
626 7c7f3866 Michael Niedermayer
            pkt->stream_index = avi->stream_index;
627
628 01f4895c Michael Niedermayer
            if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
629 7c7f3866 Michael Niedermayer
                    AVIndexEntry *e;
630
                    int index;
631 ded3c7da Michael Niedermayer
                assert(st->index_entries);
632 7c7f3866 Michael Niedermayer
633
                    index= av_index_search_timestamp(st, pkt->dts, 0);
634
                    e= &st->index_entries[index];
635 115329f1 Diego Biurrun
636 d46db490 Michael Niedermayer
                    if(index >= 0 && e->timestamp == ast->frame_offset){
637 7c7f3866 Michael Niedermayer
                        if (e->flags & AVINDEX_KEYFRAME)
638
                            pkt->flags |= PKT_FLAG_KEY;
639
                    }
640
            } else {
641 115329f1 Diego Biurrun
                pkt->flags |= PKT_FLAG_KEY;
642 7c7f3866 Michael Niedermayer
            }
643
            if(ast->sample_size)
644
                ast->frame_offset += pkt->size;
645
            else
646
                ast->frame_offset++;
647
        }
648
        ast->remaining -= size;
649
        if(!ast->remaining){
650
            avi->stream_index= -1;
651
            ast->packet_size= 0;
652
        }
653
654
        return size;
655
    }
656
657 4a8d5135 Michael Niedermayer
    memset(d, -1, sizeof(int)*8);
658
    for(i=sync=url_ftell(pb); !url_feof(pb); i++) {
659 df99755b Michael Niedermayer
        int j;
660 1101abfe Zdenek Kabelac
661 bb270c08 Diego Biurrun
        if (i >= avi->movi_end) {
662
            if (avi->is_odml) {
663
                url_fskip(pb, avi->riff_end - i);
664
                avi->riff_end = avi->movi_end = url_fsize(pb);
665
            } else
666
                break;
667
        }
668 06219cb1 Roman Shaposhnik
669 df99755b Michael Niedermayer
        for(j=0; j<7; j++)
670
            d[j]= d[j+1];
671
        d[7]= get_byte(pb);
672 115329f1 Diego Biurrun
673 df99755b Michael Niedermayer
        size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);
674 115329f1 Diego Biurrun
675 df99755b Michael Niedermayer
        if(    d[2] >= '0' && d[2] <= '9'
676 d2c5f0a4 Michael Niedermayer
            && d[3] >= '0' && d[3] <= '9'){
677
            n= (d[2] - '0') * 10 + (d[3] - '0');
678
        }else{
679
            n= 100; //invalid stream id
680 df99755b Michael Niedermayer
        }
681 949b1a13 Steve L'Homme
//av_log(NULL, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
682 d2c5f0a4 Michael Niedermayer
        if(i + size > avi->movi_end || d[0]<0)
683
            continue;
684 115329f1 Diego Biurrun
685 d2c5f0a4 Michael Niedermayer
        //parse ix##
686
        if(  (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
687 bb270c08 Diego Biurrun
        //parse JUNK
688 d2c5f0a4 Michael Niedermayer
           ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')){
689 8f9298f8 Roman Shaposhnik
            url_fskip(pb, size);
690 d2c5f0a4 Michael Niedermayer
//av_log(NULL, AV_LOG_DEBUG, "SKIP\n");
691 4a8d5135 Michael Niedermayer
            goto resync;
692 8f9298f8 Roman Shaposhnik
        }
693 d2c5f0a4 Michael Niedermayer
694 df99755b Michael Niedermayer
        if(    d[0] >= '0' && d[0] <= '9'
695 d2c5f0a4 Michael Niedermayer
            && d[1] >= '0' && d[1] <= '9'){
696
            n= (d[0] - '0') * 10 + (d[1] - '0');
697
        }else{
698
            n= 100; //invalid stream id
699
        }
700 115329f1 Diego Biurrun
701 d2c5f0a4 Michael Niedermayer
        //parse ##dc/##wb
702 80e3a08c Michael Niedermayer
        if(n < s->nb_streams){
703 d2c5f0a4 Michael Niedermayer
          AVStream *st;
704
          AVIStream *ast;
705
          st = s->streams[n];
706
          ast = st->priv_data;
707 115329f1 Diego Biurrun
708 f3356e9c Michael Niedermayer
          if(   (st->discard >= AVDISCARD_DEFAULT && size==0)
709
             /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & PKT_FLAG_KEY))*/ //FIXME needs a little reordering
710
             || st->discard >= AVDISCARD_ALL){
711
                if(ast->sample_size) ast->frame_offset += pkt->size;
712
                else                 ast->frame_offset++;
713 b4aea108 Michael Niedermayer
                url_fskip(pb, size);
714
                goto resync;
715
          }
716 d2c5f0a4 Michael Niedermayer
717 115329f1 Diego Biurrun
          if(   ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
718 d2c5f0a4 Michael Niedermayer
                d[2]*256+d[3] == ast->prefix /*||
719 115329f1 Diego Biurrun
                (d[2] == 'd' && d[3] == 'c') ||
720 bb270c08 Diego Biurrun
                (d[2] == 'w' && d[3] == 'b')*/) {
721 d2c5f0a4 Michael Niedermayer
722
//av_log(NULL, AV_LOG_DEBUG, "OK\n");
723
            if(d[2]*256+d[3] == ast->prefix)
724
                ast->prefix_count++;
725
            else{
726
                ast->prefix= d[2]*256+d[3];
727
                ast->prefix_count= 0;
728
            }
729
730 7c7f3866 Michael Niedermayer
            avi->stream_index= n;
731
            ast->packet_size= size + 8;
732
            ast->remaining= size;
733 ded3c7da Michael Niedermayer
734
            {
735
                uint64_t pos= url_ftell(pb) - 8;
736
                if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
737
                    av_add_index_entry(st, pos, ast->frame_offset / FFMAX(1, ast->sample_size), size, 0, AVINDEX_KEYFRAME);
738
                }
739
            }
740 7c7f3866 Michael Niedermayer
            goto resync;
741 d2c5f0a4 Michael Niedermayer
          }
742 df99755b Michael Niedermayer
        }
743 69bde0b2 Mike Melanson
        /* palette changed chunk */
744
        if (   d[0] >= '0' && d[0] <= '9'
745
            && d[1] >= '0' && d[1] <= '9'
746
            && ((d[2] == 'p' && d[3] == 'c'))
747
            && n < s->nb_streams && i + size <= avi->movi_end) {
748
749
            AVStream *st;
750
            int first, clr, flags, k, p;
751
752
            st = s->streams[n];
753
754
            first = get_byte(pb);
755
            clr = get_byte(pb);
756 bb270c08 Diego Biurrun
            if(!clr) /* all 256 colors used */
757
                clr = 256;
758 69bde0b2 Mike Melanson
            flags = get_le16(pb);
759
            p = 4;
760
            for (k = first; k < clr + first; k++) {
761
                int r, g, b;
762
                r = get_byte(pb);
763
                g = get_byte(pb);
764
                b = get_byte(pb);
765
                    get_byte(pb);
766 01f4895c Michael Niedermayer
                st->codec->palctrl->palette[k] = b + (g << 8) + (r << 16);
767 69bde0b2 Mike Melanson
            }
768 01f4895c Michael Niedermayer
            st->codec->palctrl->palette_changed = 1;
769 4a8d5135 Michael Niedermayer
            goto resync;
770 69bde0b2 Mike Melanson
        }
771
772 df99755b Michael Niedermayer
    }
773 d2c5f0a4 Michael Niedermayer
774 df99755b Michael Niedermayer
    return -1;
775 de6d9b64 Fabrice Bellard
}
776
777 155e9ee9 Fabrice Bellard
/* XXX: we make the implicit supposition that the position are sorted
778
   for each stream */
779
static int avi_read_idx1(AVFormatContext *s, int size)
780
{
781 7c7f3866 Michael Niedermayer
    AVIContext *avi = s->priv_data;
782 155e9ee9 Fabrice Bellard
    ByteIOContext *pb = &s->pb;
783
    int nb_index_entries, i;
784
    AVStream *st;
785
    AVIStream *ast;
786
    unsigned int index, tag, flags, pos, len;
787 7c7f3866 Michael Niedermayer
    unsigned last_pos= -1;
788 115329f1 Diego Biurrun
789 155e9ee9 Fabrice Bellard
    nb_index_entries = size / 16;
790
    if (nb_index_entries <= 0)
791
        return -1;
792
793
    /* read the entries and sort them in each stream component */
794
    for(i = 0; i < nb_index_entries; i++) {
795
        tag = get_le32(pb);
796
        flags = get_le32(pb);
797
        pos = get_le32(pb);
798
        len = get_le32(pb);
799 52a0bbff Michael Niedermayer
#if defined(DEBUG_SEEK)
800 115329f1 Diego Biurrun
        av_log(NULL, AV_LOG_DEBUG, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
801 155e9ee9 Fabrice Bellard
               i, tag, flags, pos, len);
802
#endif
803 7c7f3866 Michael Niedermayer
        if(i==0 && pos > avi->movi_list)
804
            avi->movi_list= 0; //FIXME better check
805 5c89153e Michael Niedermayer
        pos += avi->movi_list;
806 7c7f3866 Michael Niedermayer
807 155e9ee9 Fabrice Bellard
        index = ((tag & 0xff) - '0') * 10;
808
        index += ((tag >> 8) & 0xff) - '0';
809
        if (index >= s->nb_streams)
810
            continue;
811
        st = s->streams[index];
812
        ast = st->priv_data;
813 115329f1 Diego Biurrun
814 52a0bbff Michael Niedermayer
#if defined(DEBUG_SEEK)
815 949b1a13 Steve L'Homme
        av_log(NULL, AV_LOG_DEBUG, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
816 52a0bbff Michael Niedermayer
#endif
817 80e3a08c Michael Niedermayer
        if(last_pos == pos)
818
            avi->non_interleaved= 1;
819
        else
820 2b70eb2b Michael Niedermayer
            av_add_index_entry(st, pos, ast->cum_len / FFMAX(1, ast->sample_size), len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
821 7c7f3866 Michael Niedermayer
        if(ast->sample_size)
822 2b70eb2b Michael Niedermayer
            ast->cum_len += len;
823 7c7f3866 Michael Niedermayer
        else
824
            ast->cum_len ++;
825
        last_pos= pos;
826 155e9ee9 Fabrice Bellard
    }
827
    return 0;
828
}
829
830 7c7f3866 Michael Niedermayer
static int guess_ni_flag(AVFormatContext *s){
831
    int i;
832
    int64_t last_start=0;
833
    int64_t first_end= INT64_MAX;
834 115329f1 Diego Biurrun
835 7c7f3866 Michael Niedermayer
    for(i=0; i<s->nb_streams; i++){
836
        AVStream *st = s->streams[i];
837
        int n= st->nb_index_entries;
838
839
        if(n <= 0)
840
            continue;
841
842
        if(st->index_entries[0].pos > last_start)
843
            last_start= st->index_entries[0].pos;
844
        if(st->index_entries[n-1].pos < first_end)
845
            first_end= st->index_entries[n-1].pos;
846
    }
847
    return last_start > first_end;
848
}
849
850 155e9ee9 Fabrice Bellard
static int avi_load_index(AVFormatContext *s)
851
{
852
    AVIContext *avi = s->priv_data;
853
    ByteIOContext *pb = &s->pb;
854
    uint32_t tag, size;
855 e6c0297f Michael Niedermayer
    offset_t pos= url_ftell(pb);
856 115329f1 Diego Biurrun
857 155e9ee9 Fabrice Bellard
    url_fseek(pb, avi->movi_end, SEEK_SET);
858
#ifdef DEBUG_SEEK
859 949b1a13 Steve L'Homme
    printf("movi_end=0x%"PRIx64"\n", avi->movi_end);
860 155e9ee9 Fabrice Bellard
#endif
861
    for(;;) {
862
        if (url_feof(pb))
863
            break;
864
        tag = get_le32(pb);
865
        size = get_le32(pb);
866
#ifdef DEBUG_SEEK
867
        printf("tag=%c%c%c%c size=0x%x\n",
868
               tag & 0xff,
869
               (tag >> 8) & 0xff,
870
               (tag >> 16) & 0xff,
871
               (tag >> 24) & 0xff,
872
               size);
873
#endif
874
        switch(tag) {
875
        case MKTAG('i', 'd', 'x', '1'):
876
            if (avi_read_idx1(s, size) < 0)
877
                goto skip;
878
            else
879
                goto the_end;
880
            break;
881
        default:
882
        skip:
883
            size += (size & 1);
884
            url_fskip(pb, size);
885
            break;
886
        }
887
    }
888
 the_end:
889 e6c0297f Michael Niedermayer
    url_fseek(pb, pos, SEEK_SET);
890 155e9ee9 Fabrice Bellard
    return 0;
891
}
892
893 7b3c1382 Michael Niedermayer
static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
894 155e9ee9 Fabrice Bellard
{
895
    AVIContext *avi = s->priv_data;
896
    AVStream *st;
897 52a0bbff Michael Niedermayer
    int i, index;
898 155e9ee9 Fabrice Bellard
    int64_t pos;
899
900
    if (!avi->index_loaded) {
901
        /* we only load the index on demand */
902
        avi_load_index(s);
903
        avi->index_loaded = 1;
904
    }
905 52a0bbff Michael Niedermayer
    assert(stream_index>= 0);
906 155e9ee9 Fabrice Bellard
907
    st = s->streams[stream_index];
908 52a0bbff Michael Niedermayer
    index= av_index_search_timestamp(st, timestamp, flags);
909
    if(index<0)
910 155e9ee9 Fabrice Bellard
        return -1;
911 115329f1 Diego Biurrun
912 155e9ee9 Fabrice Bellard
    /* find the position */
913 52a0bbff Michael Niedermayer
    pos = st->index_entries[index].pos;
914
    timestamp = st->index_entries[index].timestamp;
915
916 949b1a13 Steve L'Homme
//    av_log(NULL, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp);
917 155e9ee9 Fabrice Bellard
918 6eb2de74 Roman Shaposhnik
    if (ENABLE_DV_DEMUXER && avi->dv_demux) {
919
        /* One and only one real stream for DV in AVI, and it has video  */
920
        /* offsets. Calling with other stream indices should have failed */
921
        /* the av_index_search_timestamp call above.                     */
922
        assert(stream_index == 0);
923
924
        /* Feed the DV video stream version of the timestamp to the */
925
        /* DV demux so it can synth correct timestamps              */
926
        dv_offset_reset(avi->dv_demux, timestamp);
927
928
        url_fseek(&s->pb, pos, SEEK_SET);
929
        avi->stream_index= -1;
930
        return 0;
931
    }
932
933 155e9ee9 Fabrice Bellard
    for(i = 0; i < s->nb_streams; i++) {
934 52a0bbff Michael Niedermayer
        AVStream *st2 = s->streams[i];
935
        AVIStream *ast2 = st2->priv_data;
936 7c7f3866 Michael Niedermayer
937
        ast2->packet_size=
938
        ast2->remaining= 0;
939
940 52a0bbff Michael Niedermayer
        if (st2->nb_index_entries <= 0)
941
            continue;
942 115329f1 Diego Biurrun
943 e84dab5f Michael Niedermayer
//        assert(st2->codec->block_align);
944 52a0bbff Michael Niedermayer
        assert(st2->time_base.den == ast2->rate);
945
        assert(st2->time_base.num == ast2->scale);
946
        index = av_index_search_timestamp(
947 115329f1 Diego Biurrun
                st2,
948 52a0bbff Michael Niedermayer
                av_rescale(timestamp, st2->time_base.den*(int64_t)st->time_base.num, st->time_base.den * (int64_t)st2->time_base.num),
949
                flags | AVSEEK_FLAG_BACKWARD);
950
        if(index<0)
951
            index=0;
952 115329f1 Diego Biurrun
953 7c7f3866 Michael Niedermayer
        if(!avi->non_interleaved){
954
            while(index>0 && st2->index_entries[index].pos > pos)
955
                index--;
956
            while(index+1 < st2->nb_index_entries && st2->index_entries[index].pos < pos)
957
                index++;
958
        }
959
960 949b1a13 Steve L'Homme
//        av_log(NULL, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp);
961 52a0bbff Michael Niedermayer
        /* extract the current frame number */
962
        ast2->frame_offset = st2->index_entries[index].timestamp;
963
        if(ast2->sample_size)
964
            ast2->frame_offset *=ast2->sample_size;
965 155e9ee9 Fabrice Bellard
    }
966 52a0bbff Michael Niedermayer
967 155e9ee9 Fabrice Bellard
    /* do the seek */
968
    url_fseek(&s->pb, pos, SEEK_SET);
969 7c7f3866 Michael Niedermayer
    avi->stream_index= -1;
970 155e9ee9 Fabrice Bellard
    return 0;
971
}
972
973 1101abfe Zdenek Kabelac
static int avi_read_close(AVFormatContext *s)
974 de6d9b64 Fabrice Bellard
{
975 5ae2c73e Michael Niedermayer
    int i;
976
    AVIContext *avi = s->priv_data;
977
978
    for(i=0;i<s->nb_streams;i++) {
979
        AVStream *st = s->streams[i];
980 155e9ee9 Fabrice Bellard
        AVIStream *ast = st->priv_data;
981 52a0bbff Michael Niedermayer
        av_free(ast);
982 01f4895c Michael Niedermayer
        av_free(st->codec->palctrl);
983 5ae2c73e Michael Niedermayer
    }
984
985 7458ccbb Roman Shaposhnik
    if (avi->dv_demux)
986
        av_free(avi->dv_demux);
987
988 c9a65ca8 Fabrice Bellard
    return 0;
989
}
990
991
static int avi_probe(AVProbeData *p)
992
{
993
    /* check file header */
994
    if (p->buf_size <= 32)
995
        return 0;
996
    if (p->buf[0] == 'R' && p->buf[1] == 'I' &&
997
        p->buf[2] == 'F' && p->buf[3] == 'F' &&
998
        p->buf[8] == 'A' && p->buf[9] == 'V' &&
999
        p->buf[10] == 'I' && p->buf[11] == ' ')
1000
        return AVPROBE_SCORE_MAX;
1001
    else
1002
        return 0;
1003
}
1004
1005 ff70e601 Måns Rullgård
AVInputFormat avi_demuxer = {
1006 c9a65ca8 Fabrice Bellard
    "avi",
1007
    "avi format",
1008
    sizeof(AVIContext),
1009
    avi_probe,
1010
    avi_read_header,
1011
    avi_read_packet,
1012
    avi_read_close,
1013 155e9ee9 Fabrice Bellard
    avi_read_seek,
1014 c9a65ca8 Fabrice Bellard
};