avidec.c 47.0 KB
Newer Older
F
Fabrice Bellard 已提交
1
/*
2
 * AVI demuxer
D
Diego Biurrun 已提交
3
 * Copyright (c) 2001 Fabrice Bellard
F
Fabrice Bellard 已提交
4
 *
5
 * This file is part of Libav.
6
 *
7
 * Libav is free software; you can redistribute it and/or
F
Fabrice Bellard 已提交
8 9
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
10
 * version 2.1 of the License, or (at your option) any later version.
F
Fabrice Bellard 已提交
11
 *
12
 * Libav is distributed in the hope that it will be useful,
F
Fabrice Bellard 已提交
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
F
Fabrice Bellard 已提交
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
F
Fabrice Bellard 已提交
16
 *
F
Fabrice Bellard 已提交
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with Libav; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
F
Fabrice Bellard 已提交
20
 */
21

22
#include "libavutil/intreadwrite.h"
23
#include "libavutil/mathematics.h"
24
#include "libavutil/bswap.h"
25
#include "libavutil/dict.h"
26
#include "libavutil/avstring.h"
F
Fabrice Bellard 已提交
27 28
#include "avformat.h"
#include "avi.h"
29
#include "dv.h"
30
#include "riff.h"
F
Fabrice Bellard 已提交
31

32 33 34
#undef NDEBUG
#include <assert.h>

F
Fabrice Bellard 已提交
35
typedef struct AVIStream {
36
    int64_t frame_offset; /* current frame (video) or byte (audio) counter
F
Fabrice Bellard 已提交
37
                         (used to compute the pts) */
38 39 40
    int remaining;
    int packet_size;

F
Fabrice Bellard 已提交
41
    int scale;
42
    int rate;
43
    int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
44

M
Michael Niedermayer 已提交
45
    int64_t cum_len; /* temporary storage (used during seek) */
46

47 48
    int prefix;                       ///< normally 'd'<<8 + 'c' or 'w'<<8 + 'b'
    int prefix_count;
49 50
    uint32_t pal[256];
    int has_pal;
51
    int dshow_block_align;            ///< block align variable used to emulate bugs in the MS dshow demuxer
52 53 54 55

    AVFormatContext *sub_ctx;
    AVPacket sub_pkt;
    uint8_t *sub_buffer;
F
Fabrice Bellard 已提交
56
} AVIStream;
F
Fabrice Bellard 已提交
57 58

typedef struct {
59 60
    int64_t  riff_end;
    int64_t  movi_end;
61
    int64_t  fsize;
62
    int64_t movi_list;
63
    int64_t last_pkt_pos;
F
Fabrice Bellard 已提交
64
    int index_loaded;
65
    int is_odml;
66 67
    int non_interleaved;
    int stream_index;
68
    DVDemuxContext* dv_demux;
69 70
    int odml_depth;
#define MAX_ODML_DEPTH 1000
F
Fabrice Bellard 已提交
71 72
} AVIContext;

73 74 75 76
static const char avi_headers[][8] = {
    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', ' ' },
    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 'X' },
    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 0x19},
77
    { 'O', 'N', '2', ' ',    'O', 'N', '2', 'f' },
78
    { 'R', 'I', 'F', 'F',    'A', 'M', 'V', ' ' },
79 80 81
    { 0 }
};

82
static int avi_load_index(AVFormatContext *s);
M
Michael Niedermayer 已提交
83
static int guess_ni_flag(AVFormatContext *s);
84

85
#define print_tag(str, tag, size)                       \
L
Luca Barbato 已提交
86
    av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n",       \
87 88 89 90 91
           str, tag & 0xff,                             \
           (tag >> 8) & 0xff,                           \
           (tag >> 16) & 0xff,                          \
           (tag >> 24) & 0xff,                          \
           size)
F
Fabrice Bellard 已提交
92

93 94 95
static inline int get_duration(AVIStream *ast, int len){
    if(ast->sample_size){
        return len;
96 97
    }else if (ast->dshow_block_align){
        return (len + ast->dshow_block_align - 1)/ast->dshow_block_align;
98 99 100 101
    }else
        return 1;
}

102
static int get_riff(AVFormatContext *s, AVIOContext *pb)
103
{
104
    AVIContext *avi = s->priv_data;
105 106
    char header[8];
    int i;
107

108
    /* check RIFF header */
109 110
    avio_read(pb, header, 4);
    avi->riff_end = avio_rl32(pb);  /* RIFF chunk size */
111
    avi->riff_end += avio_tell(pb); /* RIFF chunk end */
112
    avio_read(pb, header+4, 4);
113 114 115 116 117

    for(i=0; avi_headers[i][0]; i++)
        if(!memcmp(header, avi_headers[i], 8))
            break;
    if(!avi_headers[i][0])
118
        return -1;
119

120
    if(header[7] == 0x19)
121
        av_log(s, AV_LOG_INFO, "This file has been generated by a totally broken muxer.\n");
122

123 124 125
    return 0;
}

M
Michael Niedermayer 已提交
126
static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
127
    AVIContext *avi = s->priv_data;
128
    AVIOContext *pb = s->pb;
129 130 131 132 133 134
    int longs_pre_entry= avio_rl16(pb);
    int index_sub_type = avio_r8(pb);
    int index_type     = avio_r8(pb);
    int entries_in_use = avio_rl32(pb);
    int chunk_id       = avio_rl32(pb);
    int64_t base       = avio_rl64(pb);
M
Michael Niedermayer 已提交
135 136 137 138
    int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
    AVStream *st;
    AVIStream *ast;
    int i;
139
    int64_t last_pos= -1;
A
Anton Khirnov 已提交
140
    int64_t filesize= avio_size(s->pb);
M
Michael Niedermayer 已提交
141

142 143
    av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
            longs_pre_entry,index_type, entries_in_use, chunk_id, base);
M
Michael Niedermayer 已提交
144

145
    if(stream_id >= s->nb_streams || stream_id < 0)
M
Michael Niedermayer 已提交
146 147 148 149 150 151 152
        return -1;
    st= s->streams[stream_id];
    ast = st->priv_data;

    if(index_sub_type)
        return -1;

153
    avio_rl32(pb);
M
Michael Niedermayer 已提交
154 155 156 157 158 159

    if(index_type && longs_pre_entry != 2)
        return -1;
    if(index_type>1)
        return -1;

160 161 162 163 164 165 166 167
    if(filesize > 0 && base >= filesize){
        av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
        if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
            base &= 0xFFFFFFFF;
        else
            return -1;
    }

M
Michael Niedermayer 已提交
168 169
    for(i=0; i<entries_in_use; i++){
        if(index_type){
170 171
            int64_t pos= avio_rl32(pb) + base - 8;
            int len    = avio_rl32(pb);
M
Michael Niedermayer 已提交
172
            int key= len >= 0;
M
Michael Niedermayer 已提交
173 174
            len &= 0x7FFFFFFF;

175 176
            av_dlog(s, "pos:%"PRId64", len:%X\n", pos, len);

A
Anton Khirnov 已提交
177
            if(pb->eof_reached)
178 179
                return -1;

180 181
            if(last_pos == pos || pos == base - 8)
                avi->non_interleaved= 1;
182
            if(last_pos != pos && (len || !ast->sample_size))
183
                av_add_index_entry(st, pos, ast->cum_len, len, 0, key ? AVINDEX_KEYFRAME : 0);
M
Michael Niedermayer 已提交
184

185
            ast->cum_len += get_duration(ast, len);
186
            last_pos= pos;
M
Michael Niedermayer 已提交
187
        }else{
M
Måns Rullgård 已提交
188 189
            int64_t offset, pos;
            int duration;
190 191 192
            offset = avio_rl64(pb);
            avio_rl32(pb);       /* size */
            duration = avio_rl32(pb);
193

A
Anton Khirnov 已提交
194
            if(pb->eof_reached)
195 196
                return -1;

197
            pos = avio_tell(pb);
M
Michael Niedermayer 已提交
198

199 200 201 202 203
            if(avi->odml_depth > MAX_ODML_DEPTH){
                av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
                return -1;
            }

A
Anton Khirnov 已提交
204
            avio_seek(pb, offset+8, SEEK_SET);
205
            avi->odml_depth++;
M
Michael Niedermayer 已提交
206
            read_braindead_odml_indx(s, frame_num);
207
            avi->odml_depth--;
M
Michael Niedermayer 已提交
208 209
            frame_num += duration;

A
Anton Khirnov 已提交
210
            avio_seek(pb, pos, SEEK_SET);
M
Michael Niedermayer 已提交
211 212
        }
    }
213
    avi->index_loaded=1;
M
Michael Niedermayer 已提交
214 215 216
    return 0;
}

217
static void clean_index(AVFormatContext *s){
218 219
    int i;
    int64_t j;
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237

    for(i=0; i<s->nb_streams; i++){
        AVStream *st = s->streams[i];
        AVIStream *ast = st->priv_data;
        int n= st->nb_index_entries;
        int max= ast->sample_size;
        int64_t pos, size, ts;

        if(n != 1 || ast->sample_size==0)
            continue;

        while(max < 1024) max+=max;

        pos= st->index_entries[0].pos;
        size= st->index_entries[0].size;
        ts= st->index_entries[0].timestamp;

        for(j=0; j<size; j+=max){
238
            av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
239 240 241 242
        }
    }
}

243
static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size)
244
{
245
    AVIOContext *pb = s->pb;
246
    char key[5] = {0}, *value;
M
Michael Niedermayer 已提交
247

248
    size += (size & 1);
M
Michael Niedermayer 已提交
249

250 251 252 253 254
    if (size == UINT_MAX)
        return -1;
    value = av_malloc(size+1);
    if (!value)
        return -1;
255
    avio_read(pb, value, size);
256
    value[size]=0;
257

258 259
    AV_WL32(key, tag);

260 261
    return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
                            AV_DICT_DONT_STRDUP_VAL);
262 263
}

264 265
static void avi_read_info(AVFormatContext *s, uint64_t end)
{
266
    while (avio_tell(s->pb) < end) {
267 268
        uint32_t tag  = avio_rl32(s->pb);
        uint32_t size = avio_rl32(s->pb);
269 270 271 272
        avi_read_tag(s, NULL, tag, size);
    }
}

273 274 275
static const char months[12][4] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
                                    "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };

276
static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
277 278 279 280 281
{
    char month[4], time[9], buffer[64];
    int i, day, year;
    /* parse standard AVI date format (ie. "Mon Mar 10 15:04:43 2003") */
    if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
282
               month, &day, time, &year) == 4) {
283
        for (i=0; i<12; i++)
284
            if (!av_strcasecmp(month, months[i])) {
285 286
                snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
                         year, i+1, day, time);
287
                av_dict_set(metadata, "creation_time", buffer, 0);
288
            }
289 290
    } else if (date[4] == '/' && date[7] == '/') {
        date[4] = date[7] = '-';
291
        av_dict_set(metadata, "creation_time", date, 0);
292
    }
293 294
}

295 296
static void avi_read_nikon(AVFormatContext *s, uint64_t end)
{
297
    while (avio_tell(s->pb) < end) {
298 299
        uint32_t tag  = avio_rl32(s->pb);
        uint32_t size = avio_rl32(s->pb);
300 301
        switch (tag) {
        case MKTAG('n', 'c', 't', 'g'): {  /* Nikon Tags */
302 303
            uint64_t tag_end = avio_tell(s->pb) + size;
            while (avio_tell(s->pb) < tag_end) {
304 305
                uint16_t tag  = avio_rl16(s->pb);
                uint16_t size = avio_rl16(s->pb);
306 307
                const char *name = NULL;
                char buffer[64] = {0};
308
                size -= avio_read(s->pb, buffer,
309 310 311 312 313 314 315 316 317 318
                                   FFMIN(size, sizeof(buffer)-1));
                switch (tag) {
                case 0x03:  name = "maker";  break;
                case 0x04:  name = "model";  break;
                case 0x13:  name = "creation_time";
                    if (buffer[4] == ':' && buffer[7] == ':')
                        buffer[4] = buffer[7] = '-';
                    break;
                }
                if (name)
319
                    av_dict_set(&s->metadata, name, buffer, 0);
320
                avio_skip(s->pb, size);
321 322 323 324
            }
            break;
        }
        default:
325
            avio_skip(s->pb, size);
326 327 328 329 330
            break;
        }
    }
}

Z
Zdenek Kabelac 已提交
331
static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap)
F
Fabrice Bellard 已提交
332
{
F
Fabrice Bellard 已提交
333
    AVIContext *avi = s->priv_data;
334
    AVIOContext *pb = s->pb;
335
    unsigned int tag, tag1, handler;
M
Mans Rullgard 已提交
336
    int codec_type, stream_index, frame_period;
M
Michael Niedermayer 已提交
337
    unsigned int size;
338
    int i;
F
Fabrice Bellard 已提交
339
    AVStream *st;
M
Måns Rullgård 已提交
340
    AVIStream *ast = NULL;
341 342
    int avih_width=0, avih_height=0;
    int amv_file_format=0;
343
    uint64_t list_end = 0;
344
    int ret;
F
Fabrice Bellard 已提交
345

346
    avi->stream_index= -1;
347

348
    if (get_riff(s, pb) < 0)
F
Fabrice Bellard 已提交
349
        return -1;
Z
Zdenek Kabelac 已提交
350

A
Anton Khirnov 已提交
351
    avi->fsize = avio_size(pb);
352
    if(avi->fsize<=0)
353
        avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
354

F
Fabrice Bellard 已提交
355 356 357 358 359
    /* first list tag */
    stream_index = -1;
    codec_type = -1;
    frame_period = 0;
    for(;;) {
A
Anton Khirnov 已提交
360
        if (pb->eof_reached)
F
Fabrice Bellard 已提交
361
            goto fail;
362 363
        tag = avio_rl32(pb);
        size = avio_rl32(pb);
364

F
Fabrice Bellard 已提交
365 366 367 368
        print_tag("tag", tag, size);

        switch(tag) {
        case MKTAG('L', 'I', 'S', 'T'):
369
            list_end = avio_tell(pb) + size;
D
Diego Biurrun 已提交
370
            /* Ignored, except at start of video packets. */
371
            tag1 = avio_rl32(pb);
372

F
Fabrice Bellard 已提交
373
            print_tag("list", tag1, 0);
374

F
Fabrice Bellard 已提交
375
            if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
376
                avi->movi_list = avio_tell(pb) - 4;
377
                if(size) avi->movi_end = avi->movi_list + size + (size & 1);
A
Anton Khirnov 已提交
378
                else     avi->movi_end = avio_size(pb);
L
Luca Barbato 已提交
379
                av_dlog(NULL, "movi end=%"PRIx64"\n", avi->movi_end);
F
Fabrice Bellard 已提交
380 381
                goto end_of_header;
            }
382 383
            else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
                avi_read_info(s, list_end);
384 385
            else if (tag1 == MKTAG('n', 'c', 'd', 't'))
                avi_read_nikon(s, list_end);
386

F
Fabrice Bellard 已提交
387
            break;
388 389 390
        case MKTAG('I', 'D', 'I', 'T'): {
            unsigned char date[64] = {0};
            size += (size & 1);
391
            size -= avio_read(pb, date, FFMIN(size, sizeof(date)-1));
392
            avio_skip(pb, size);
393 394 395
            avi_metadata_creation_time(&s->metadata, date);
            break;
        }
396
        case MKTAG('d', 'm', 'l', 'h'):
397
            avi->is_odml = 1;
398
            avio_skip(pb, size + (size & 1));
399
            break;
400 401
        case MKTAG('a', 'm', 'v', 'h'):
            amv_file_format=1;
F
Fabrice Bellard 已提交
402
        case MKTAG('a', 'v', 'i', 'h'):
D
Diego Biurrun 已提交
403
            /* AVI header */
Z
Zdenek Kabelac 已提交
404
            /* using frame_period is bad idea */
405
            frame_period = avio_rl32(pb);
M
Mans Rullgard 已提交
406
            avio_skip(pb, 4);
407 408
            avio_rl32(pb);
            avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
409

410
            avio_skip(pb, 2 * 4);
411 412 413 414
            avio_rl32(pb);
            avio_rl32(pb);
            avih_width=avio_rl32(pb);
            avih_height=avio_rl32(pb);
415

416
            avio_skip(pb, size - 10 * 4);
417 418 419 420
            break;
        case MKTAG('s', 't', 'r', 'h'):
            /* stream header */

421 422
            tag1 = avio_rl32(pb);
            handler = avio_rl32(pb); /* codec tag */
423 424

            if(tag1 == MKTAG('p', 'a', 'd', 's')){
425
                avio_skip(pb, size - 8);
426 427 428
                break;
            }else{
                stream_index++;
429
                st = avformat_new_stream(s, NULL);
F
Fabrice Bellard 已提交
430 431
                if (!st)
                    goto fail;
432

433
                st->id = stream_index;
F
Fabrice Bellard 已提交
434 435 436 437
                ast = av_mallocz(sizeof(AVIStream));
                if (!ast)
                    goto fail;
                st->priv_data = ast;
438
            }
439 440
            if(amv_file_format)
                tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s');
441

442
            print_tag("strh", tag1, -1);
443

M
Michael Niedermayer 已提交
444
            if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){
445 446
                int64_t dv_dur;

447
                /*
448
                 * After some consideration -- I don't think we
D
Diego Biurrun 已提交
449
                 * have to support anything but DV in type1 AVIs.
450 451 452 453 454 455 456 457 458 459 460
                 */
                if (s->nb_streams != 1)
                    goto fail;

                if (handler != MKTAG('d', 'v', 's', 'd') &&
                    handler != MKTAG('d', 'v', 'h', 'd') &&
                    handler != MKTAG('d', 'v', 's', 'l'))
                   goto fail;

                ast = s->streams[0]->priv_data;
                av_freep(&s->streams[0]->codec->extradata);
461
                av_freep(&s->streams[0]->codec);
462 463
                av_freep(&s->streams[0]);
                s->nb_streams = 0;
464
                if (CONFIG_DV_DEMUXER) {
465
                    avi->dv_demux = avpriv_dv_init_demux(s);
466 467
                    if (!avi->dv_demux)
                        goto fail;
468
                }
469
                s->streams[0]->priv_data = ast;
470
                avio_skip(pb, 3 * 4);
471 472
                ast->scale = avio_rl32(pb);
                ast->rate = avio_rl32(pb);
473
                avio_skip(pb, 4);  /* start time */
474

475
                dv_dur = avio_rl32(pb);
476 477 478 479 480 481
                if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
                    dv_dur *= AV_TIME_BASE;
                    s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
                }
                /*
                 * else, leave duration alone; timing estimation in utils.c
D
Diego Biurrun 已提交
482
                 *      will make a guess based on bitrate.
483 484
                 */

485
                stream_index = s->nb_streams - 1;
486
                avio_skip(pb, size - 9*4);
M
Michael Niedermayer 已提交
487 488
                break;
            }
489

490
            assert(stream_index < s->nb_streams);
491
            st->codec->stream_codec_tag= handler;
492

493 494 495 496 497 498
            avio_rl32(pb); /* flags */
            avio_rl16(pb); /* priority */
            avio_rl16(pb); /* language */
            avio_rl32(pb); /* initial frame */
            ast->scale = avio_rl32(pb);
            ast->rate = avio_rl32(pb);
499
            if(!(ast->scale && ast->rate)){
D
Diego Biurrun 已提交
500
                av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate);
M
indent  
Michael Niedermayer 已提交
501 502 503 504 505 506 507
                if(frame_period){
                    ast->rate = 1000000;
                    ast->scale = frame_period;
                }else{
                    ast->rate = 25;
                    ast->scale = 1;
                }
508
            }
M
Michael Niedermayer 已提交
509
            av_set_pts_info(st, 64, ast->scale, ast->rate);
510

511 512
            ast->cum_len=avio_rl32(pb); /* start */
            st->nb_frames = avio_rl32(pb);
513

M
Michael Niedermayer 已提交
514
            st->start_time = 0;
515 516 517
            avio_rl32(pb); /* buffer size */
            avio_rl32(pb); /* quality */
            ast->sample_size = avio_rl32(pb); /* sample ssize */
518
            ast->cum_len *= FFMAX(1, ast->sample_size);
519
//            av_log(s, AV_LOG_DEBUG, "%d %d %d %d\n", ast->rate, ast->scale, ast->start, ast->sample_size);
520

M
Michael Niedermayer 已提交
521
            switch(tag1) {
522
            case MKTAG('v', 'i', 'd', 's'):
523
                codec_type = AVMEDIA_TYPE_VIDEO;
524

M
Michael Niedermayer 已提交
525 526 527
                ast->sample_size = 0;
                break;
            case MKTAG('a', 'u', 'd', 's'):
528
                codec_type = AVMEDIA_TYPE_AUDIO;
529
                break;
530
            case MKTAG('t', 'x', 't', 's'):
531
                codec_type = AVMEDIA_TYPE_SUBTITLE;
532
                break;
F
Florian Echtler 已提交
533
            case MKTAG('d', 'a', 't', 's'):
534
                codec_type = AVMEDIA_TYPE_DATA;
F
Florian Echtler 已提交
535
                break;
536
            default:
M
Michael Niedermayer 已提交
537
                av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1);
538
                goto fail;
F
Fabrice Bellard 已提交
539
            }
540 541
            if(ast->sample_size == 0)
                st->duration = st->nb_frames;
542
            ast->frame_offset= ast->cum_len;
543
            avio_skip(pb, size - 12 * 4);
F
Fabrice Bellard 已提交
544 545 546
            break;
        case MKTAG('s', 't', 'r', 'f'):
            /* stream header */
547
            if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
548
                avio_skip(pb, size);
F
Fabrice Bellard 已提交
549
            } else {
550
                uint64_t cur_pos = avio_tell(pb);
551 552
                if (cur_pos < list_end)
                    size = FFMIN(size, list_end - cur_pos);
F
Fabrice Bellard 已提交
553 554
                st = s->streams[stream_index];
                switch(codec_type) {
555
                case AVMEDIA_TYPE_VIDEO:
556 557 558
                    if(amv_file_format){
                        st->codec->width=avih_width;
                        st->codec->height=avih_height;
559
                        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
560
                        st->codec->codec_id = CODEC_ID_AMV;
561
                        avio_skip(pb, size);
562 563
                        break;
                    }
P
Peter Ross 已提交
564
                    tag1 = ff_get_bmp_header(pb, st);
565

M
Michael Niedermayer 已提交
566
                    if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) {
567
                        st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
568 569 570 571 572
                        st->codec->codec_tag = tag1;
                        st->codec->codec_id = CODEC_ID_XSUB;
                        break;
                    }

573 574 575
                    if(size > 10*4 && size<(1<<30)){
                        st->codec->extradata_size= size - 10*4;
                        st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
576 577 578 579
                        if (!st->codec->extradata) {
                            st->codec->extradata_size= 0;
                            return AVERROR(ENOMEM);
                        }
580
                        avio_read(pb, st->codec->extradata, st->codec->extradata_size);
581
                    }
582

583
                    if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
584
                        avio_r8(pb);
585

D
Diego Biurrun 已提交
586 587
                    /* Extract palette from extradata if bpp <= 8. */
                    /* This code assumes that extradata contains only palette. */
588
                    /* This is true for all paletted codecs implemented in Libav. */
589
                    if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
590 591 592 593 594
                        int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
                        const uint8_t *pal_src;

                        pal_size = FFMIN(pal_size, st->codec->extradata_size);
                        pal_src = st->codec->extradata + st->codec->extradata_size - pal_size;
595
#if HAVE_BIGENDIAN
596 597
                        for (i = 0; i < pal_size/4; i++)
                            ast->pal[i] = av_bswap32(((uint32_t*)pal_src)[i]);
598
#else
599
                        memcpy(ast->pal, pal_src, pal_size);
600
#endif
601
                        ast->has_pal = 1;
602 603
                    }

F
Fabrice Bellard 已提交
604
                    print_tag("video", tag1, 0);
605

606
                    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
607
                    st->codec->codec_tag = tag1;
608
                    st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
D
Diego Biurrun 已提交
609
                    st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
610 611 612 613 614
                    // Support "Resolution 1:1" for Avid AVI Codec
                    if(tag1 == MKTAG('A', 'V', 'R', 'n') &&
                       st->codec->extradata_size >= 31 &&
                       !memcmp(&st->codec->extradata[28], "1:1", 3))
                        st->codec->codec_id = CODEC_ID_RAWVIDEO;
615 616 617 618 619 620 621 622 623

                    if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
                        st->codec->extradata_size+= 9;
                        st->codec->extradata= av_realloc(st->codec->extradata, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
                        if(st->codec->extradata)
                            memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
                    }
                    st->codec->height= FFABS(st->codec->height);

624
//                    avio_skip(pb, size - 5 * 4);
F
Fabrice Bellard 已提交
625
                    break;
626
                case AVMEDIA_TYPE_AUDIO:
627 628 629
                    ret = ff_get_wav_header(pb, st->codec, size);
                    if (ret < 0)
                        return ret;
630
                    ast->dshow_block_align= st->codec->block_align;
631
                    if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){
632
                        av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align);
633 634
                        ast->sample_size= st->codec->block_align;
                    }
635
                    if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
636
                        avio_skip(pb, 1);
D
Diego Biurrun 已提交
637
                    /* Force parsing as several audio frames can be in
D
Diego Biurrun 已提交
638
                     * one packet and timestamps refer to packet start. */
639
                    st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
D
Diego Biurrun 已提交
640 641 642
                    /* ADTS header is in extradata, AAC without header must be
                     * stored as exact frames. Parser not needed and it will
                     * fail. */
643
                    if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size)
A
Aurelien Jacobs 已提交
644
                        st->need_parsing = AVSTREAM_PARSE_NONE;
645 646
                    /* AVI files with Xan DPCM audio (wrongly) declare PCM
                     * audio in the header but have Axan as stream_code_tag. */
647
                    if (st->codec->stream_codec_tag == AV_RL32("Axan")){
648 649 650
                        st->codec->codec_id  = CODEC_ID_XAN_DPCM;
                        st->codec->codec_tag = 0;
                    }
651
                    if (amv_file_format){
652
                        st->codec->codec_id  = CODEC_ID_ADPCM_IMA_AMV;
653 654
                        ast->dshow_block_align = 0;
                    }
F
Fabrice Bellard 已提交
655
                    break;
656 657 658 659
                case AVMEDIA_TYPE_SUBTITLE:
                    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
                    st->codec->codec_id   = CODEC_ID_PROBE;
                    break;
F
Fabrice Bellard 已提交
660
                default:
661
                    st->codec->codec_type = AVMEDIA_TYPE_DATA;
662 663
                    st->codec->codec_id= CODEC_ID_NONE;
                    st->codec->codec_tag= 0;
664
                    avio_skip(pb, size);
F
Fabrice Bellard 已提交
665 666 667 668
                    break;
                }
            }
            break;
M
Michael Niedermayer 已提交
669
        case MKTAG('i', 'n', 'd', 'x'):
670
            i= avio_tell(pb);
671 672 673
            if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
               read_braindead_odml_indx(s, 0) < 0 && s->error_recognition >= FF_ER_EXPLODE){
                goto fail;
674
            }
A
Anton Khirnov 已提交
675
            avio_seek(pb, i+size, SEEK_SET);
M
Michael Niedermayer 已提交
676
            break;
677 678 679 680 681
        case MKTAG('v', 'p', 'r', 'p'):
            if(stream_index < (unsigned)s->nb_streams && size > 9*4){
                AVRational active, active_aspect;

                st = s->streams[stream_index];
682 683 684 685 686 687 688 689 690 691 692
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);

                active_aspect.den= avio_rl16(pb);
                active_aspect.num= avio_rl16(pb);
                active.num       = avio_rl32(pb);
                active.den       = avio_rl32(pb);
                avio_rl32(pb); //nbFieldsPerFrame
693 694

                if(active_aspect.num && active_aspect.den && active.num && active.den){
695
                    st->sample_aspect_ratio= av_div_q(active_aspect, active);
696 697 698 699
//av_log(s, AV_LOG_ERROR, "vprp %d/%d %d/%d\n", active_aspect.num, active_aspect.den, active.num, active.den);
                }
                size -= 9*4;
            }
700
            avio_skip(pb, size);
701
            break;
702 703
        case MKTAG('s', 't', 'r', 'n'):
            if(s->nb_streams){
704
                avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
705 706
                break;
            }
F
Fabrice Bellard 已提交
707
        default:
708
            if(size > 1000000){
D
Diego Biurrun 已提交
709 710
                av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
                                        "I will ignore it and try to continue anyway.\n");
711
                if (s->error_recognition >= FF_ER_EXPLODE) goto fail;
712
                avi->movi_list = avio_tell(pb) - 4;
A
Anton Khirnov 已提交
713
                avi->movi_end  = avio_size(pb);
714 715
                goto end_of_header;
            }
F
Fabrice Bellard 已提交
716 717
            /* skip tag */
            size += (size & 1);
718
            avio_skip(pb, size);
F
Fabrice Bellard 已提交
719 720 721 722 723 724 725 726 727
            break;
        }
    }
 end_of_header:
    /* check stream number */
    if (stream_index != s->nb_streams - 1) {
    fail:
        return -1;
    }
Z
Zdenek Kabelac 已提交
728

729
    if(!avi->index_loaded && pb->seekable)
M
Michael Niedermayer 已提交
730
        avi_load_index(s);
731
    avi->index_loaded = 1;
M
Michael Niedermayer 已提交
732
    avi->non_interleaved |= guess_ni_flag(s);
733 734 735 736 737 738 739 740 741 742
    for(i=0; i<s->nb_streams; i++){
        AVStream *st = s->streams[i];
        if(st->nb_index_entries)
            break;
    }
    if(i==s->nb_streams && avi->non_interleaved) {
        av_log(s, AV_LOG_WARNING, "non-interleaved AVI without index, switching to interleaved\n");
        avi->non_interleaved=0;
    }

743
    if(avi->non_interleaved) {
D
Diego Biurrun 已提交
744
        av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
745
        clean_index(s);
746
    }
747

748 749
    ff_metadata_conv_ctx(s, NULL, ff_avi_metadata_conv);

F
Fabrice Bellard 已提交
750 751 752
    return 0;
}

753 754
static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
    if (!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
A
Anton Khirnov 已提交
755 756
        uint8_t desc[256];
        int score = AVPROBE_SCORE_MAX / 2, ret;
757 758 759
        AVIStream *ast = st->priv_data;
        AVInputFormat *sub_demuxer;
        AVRational time_base;
760
        AVIOContext *pb = avio_alloc_context( pkt->data + 7,
A
Anton Khirnov 已提交
761 762
                                              pkt->size - 7,
                                              0, NULL, NULL, NULL, NULL);
763
        AVProbeData pd;
764
        unsigned int desc_len = avio_rl32(pb);
765

A
Anton Khirnov 已提交
766 767
        if (desc_len > pb->buf_end - pb->buf_ptr)
            goto error;
768

A
Anton Khirnov 已提交
769
        ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
770
        avio_skip(pb, desc_len - ret);
771
        if (*desc)
772
            av_dict_set(&st->metadata, "title", desc, 0);
773

774 775
        avio_rl16(pb);   /* flags? */
        avio_rl32(pb);   /* data size */
776

A
Anton Khirnov 已提交
777
        pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };
778
        if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
A
Anton Khirnov 已提交
779
            goto error;
780

781 782 783 784 785
        if (!(ast->sub_ctx = avformat_alloc_context()))
            goto error;

        ast->sub_ctx->pb      = pb;
        if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
786 787 788 789 790 791 792 793 794
            av_read_packet(ast->sub_ctx, &ast->sub_pkt);
            *st->codec = *ast->sub_ctx->streams[0]->codec;
            ast->sub_ctx->streams[0]->codec->extradata = NULL;
            time_base = ast->sub_ctx->streams[0]->time_base;
            av_set_pts_info(st, 64, time_base.num, time_base.den);
        }
        ast->sub_buffer = pkt->data;
        memset(pkt, 0, sizeof(*pkt));
        return 1;
A
Anton Khirnov 已提交
795 796
error:
        av_freep(&pb);
797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814
    }
    return 0;
}

static AVStream *get_subtitle_pkt(AVFormatContext *s, AVStream *next_st,
                                  AVPacket *pkt)
{
    AVIStream *ast, *next_ast = next_st->priv_data;
    int64_t ts, next_ts, ts_min = INT64_MAX;
    AVStream *st, *sub_st = NULL;
    int i;

    next_ts = av_rescale_q(next_ast->frame_offset, next_st->time_base,
                           AV_TIME_BASE_Q);

    for (i=0; i<s->nb_streams; i++) {
        st  = s->streams[i];
        ast = st->priv_data;
815
        if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833
            ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q);
            if (ts <= next_ts && ts < ts_min) {
                ts_min = ts;
                sub_st = st;
            }
        }
    }

    if (sub_st) {
        ast = sub_st->priv_data;
        *pkt = ast->sub_pkt;
        pkt->stream_index = sub_st->index;
        if (av_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
            ast->sub_pkt.data = NULL;
    }
    return sub_st;
}

M
Michael Niedermayer 已提交
834 835 836 837 838 839 840 841 842
static int get_stream_idx(int *d){
    if(    d[0] >= '0' && d[0] <= '9'
        && d[1] >= '0' && d[1] <= '9'){
        return (d[0] - '0') * 10 + (d[1] - '0');
    }else{
        return 100; //invalid stream ID
    }
}

843
static int avi_sync(AVFormatContext *s, int exit_early)
F
Fabrice Bellard 已提交
844 845
{
    AVIContext *avi = s->priv_data;
846
    AVIOContext *pb = s->pb;
847 848
    int n;
    unsigned int d[8];
849
    unsigned int size;
850
    int64_t i, sync;
851 852

start_sync:
853
    memset(d, -1, sizeof(d));
854 855 856 857 858 859 860 861 862 863 864
    for(i=sync=avio_tell(pb); !pb->eof_reached; i++) {
        int j;

        for(j=0; j<7; j++)
            d[j]= d[j+1];
        d[7]= avio_r8(pb);

        size= d[4] + (d[5]<<8) + (d[6]<<16) + (d[7]<<24);

        n= get_stream_idx(d+2);
//av_log(s, 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);
865
        if(i + (uint64_t)size > avi->fsize || d[0] > 127)
866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923
            continue;

        //parse ix##
        if(  (d[0] == 'i' && d[1] == 'x' && n < s->nb_streams)
        //parse JUNK
           ||(d[0] == 'J' && d[1] == 'U' && d[2] == 'N' && d[3] == 'K')
           ||(d[0] == 'i' && d[1] == 'd' && d[2] == 'x' && d[3] == '1')){
            avio_skip(pb, size);
//av_log(s, AV_LOG_DEBUG, "SKIP\n");
            goto start_sync;
        }

        //parse stray LIST
        if(d[0] == 'L' && d[1] == 'I' && d[2] == 'S' && d[3] == 'T'){
            avio_skip(pb, 4);
            goto start_sync;
        }

        n= get_stream_idx(d);

        if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams)
            continue;

        //detect ##ix chunk and skip
        if(d[2] == 'i' && d[3] == 'x' && n < s->nb_streams){
            avio_skip(pb, size);
            goto start_sync;
        }

        //parse ##dc/##wb
        if(n < s->nb_streams){
            AVStream *st;
            AVIStream *ast;
            st = s->streams[n];
            ast = st->priv_data;

            if(s->nb_streams>=2){
                AVStream *st1  = s->streams[1];
                AVIStream *ast1= st1->priv_data;
                //workaround for broken small-file-bug402.avi
                if(   d[2] == 'w' && d[3] == 'b'
                   && n==0
                   && st ->codec->codec_type == AVMEDIA_TYPE_VIDEO
                   && st1->codec->codec_type == AVMEDIA_TYPE_AUDIO
                   && ast->prefix == 'd'*256+'c'
                   && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
                  ){
                    n=1;
                    st = st1;
                    ast = ast1;
                    av_log(s, AV_LOG_WARNING, "Invalid stream + prefix combination, assuming audio.\n");
                }
            }


            if(   (st->discard >= AVDISCARD_DEFAULT && size==0)
               /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
               || st->discard >= AVDISCARD_ALL){
924 925 926
                if (!exit_early) {
                    ast->frame_offset += get_duration(ast, size);
                }
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945
                avio_skip(pb, size);
                goto start_sync;
            }

            if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) {
                int k = avio_r8(pb);
                int last = (k + avio_r8(pb) - 1) & 0xFF;

                avio_rl16(pb); //flags

                for (; k <= last; k++)
                    ast->pal[k] = avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
                ast->has_pal= 1;
                goto start_sync;
            } else if(   ((ast->prefix_count<5 || sync+9 > i) && d[2]<128 && d[3]<128) ||
                         d[2]*256+d[3] == ast->prefix /*||
                         (d[2] == 'd' && d[3] == 'c') ||
                         (d[2] == 'w' && d[3] == 'b')*/) {

946 947
                if (exit_early)
                    return 0;
948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
//av_log(s, AV_LOG_DEBUG, "OK\n");
                if(d[2]*256+d[3] == ast->prefix)
                    ast->prefix_count++;
                else{
                    ast->prefix= d[2]*256+d[3];
                    ast->prefix_count= 0;
                }

                avi->stream_index= n;
                ast->packet_size= size + 8;
                ast->remaining= size;

                if(size || !ast->sample_size){
                    uint64_t pos= avio_tell(pb) - 8;
                    if(!st->index_entries || !st->nb_index_entries || st->index_entries[st->nb_index_entries - 1].pos < pos){
                        av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME);
                    }
                }
                return 0;
            }
        }
    }

    return AVERROR_EOF;
}

static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIContext *avi = s->priv_data;
    AVIOContext *pb = s->pb;
    int err;
979
    void* dstr;
980

981
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
982
        int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
983 984
        if (size >= 0)
            return size;
985
    }
986

987
    if(avi->non_interleaved){
988
        int best_stream_index = 0;
989 990 991 992
        AVStream *best_st= NULL;
        AVIStream *best_ast;
        int64_t best_ts= INT64_MAX;
        int i;
993

994 995 996 997
        for(i=0; i<s->nb_streams; i++){
            AVStream *st = s->streams[i];
            AVIStream *ast = st->priv_data;
            int64_t ts= ast->frame_offset;
998
            int64_t last_ts;
999

1000 1001 1002
            if(!st->nb_index_entries)
                continue;

1003 1004 1005 1006
            last_ts = st->index_entries[st->nb_index_entries - 1].timestamp;
            if(!ast->remaining && ts > last_ts)
                continue;

1007
            ts = av_rescale_q(ts, st->time_base, (AVRational){FFMAX(1, ast->sample_size), AV_TIME_BASE});
1008

1009
//            av_log(s, AV_LOG_DEBUG, "%"PRId64" %d/%d %"PRId64"\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset);
1010
            if(ts < best_ts){
1011 1012 1013 1014 1015
                best_ts= ts;
                best_st= st;
                best_stream_index= i;
            }
        }
1016 1017 1018
        if(!best_st)
            return -1;

1019
        best_ast = best_st->priv_data;
1020
        best_ts = av_rescale_q(best_ts, (AVRational){FFMAX(1, best_ast->sample_size), AV_TIME_BASE}, best_st->time_base);
1021 1022
        if(best_ast->remaining)
            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
1023
        else{
1024
            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
1025
            if(i>=0)
1026
                best_ast->frame_offset= best_st->index_entries[i].timestamp;
1027
        }
1028

1029
//        av_log(s, AV_LOG_DEBUG, "%d\n", i);
1030 1031
        if(i>=0){
            int64_t pos= best_st->index_entries[i].pos;
1032
            pos += best_ast->packet_size - best_ast->remaining;
A
Anton Khirnov 已提交
1033
            avio_seek(s->pb, pos + 8, SEEK_SET);
1034
//        av_log(s, AV_LOG_DEBUG, "pos=%"PRId64"\n", pos);
1035

1036 1037
            assert(best_ast->remaining <= best_ast->packet_size);

1038 1039
            avi->stream_index= best_stream_index;
            if(!best_ast->remaining)
1040
                best_ast->packet_size=
1041
                best_ast->remaining= best_st->index_entries[i].size;
1042 1043
        }
    }
1044

1045
resync:
1046 1047 1048
    if(avi->stream_index >= 0){
        AVStream *st= s->streams[ avi->stream_index ];
        AVIStream *ast= st->priv_data;
M
Michael Niedermayer 已提交
1049
        int size, err;
1050

1051 1052 1053
        if(get_subtitle_pkt(s, st, pkt))
            return 0;

1054
        if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
1055
            size= INT_MAX;
1056
        else if(ast->sample_size < 32)
1057 1058
            // arbitrary multiplier to avoid tiny packets for raw PCM data
            size= 1024*ast->sample_size;
1059 1060 1061 1062 1063
        else
            size= ast->sample_size;

        if(size > ast->remaining)
            size= ast->remaining;
1064
        avi->last_pkt_pos= avio_tell(pb);
M
Michael Niedermayer 已提交
1065 1066 1067
        err= av_get_packet(pb, pkt, size);
        if(err<0)
            return err;
1068

1069
        if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){
1070 1071 1072 1073 1074 1075 1076 1077
            uint8_t *pal;
            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
            if(!pal){
                av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n");
            }else{
                memcpy(pal, ast->pal, AVPALETTE_SIZE);
                ast->has_pal = 0;
            }
1078 1079
        }

1080
        if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1081
            dstr = pkt->destruct;
1082
            size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
1083 1084
                                    pkt->data, pkt->size);
            pkt->destruct = dstr;
1085
            pkt->flags |= AV_PKT_FLAG_KEY;
1086 1087
            if (size < 0)
                av_free_packet(pkt);
1088 1089 1090 1091 1092 1093
        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
                   && !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
            ast->frame_offset++;
            avi->stream_index = -1;
            ast->remaining = 0;
            goto resync;
1094
        } else {
D
Diego Biurrun 已提交
1095
            /* XXX: How to handle B-frames in AVI? */
1096 1097 1098 1099
            pkt->dts = ast->frame_offset;
//                pkt->dts += ast->start;
            if(ast->sample_size)
                pkt->dts /= ast->sample_size;
1100
//av_log(s, 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);
1101 1102
            pkt->stream_index = avi->stream_index;

1103
            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
M
indent  
Michael Niedermayer 已提交
1104 1105
                AVIndexEntry *e;
                int index;
1106
                assert(st->index_entries);
1107

1108
                index= av_index_search_timestamp(st, ast->frame_offset, 0);
M
indent  
Michael Niedermayer 已提交
1109
                e= &st->index_entries[index];
1110

M
indent  
Michael Niedermayer 已提交
1111 1112
                if(index >= 0 && e->timestamp == ast->frame_offset){
                    if (e->flags & AVINDEX_KEYFRAME)
1113
                        pkt->flags |= AV_PKT_FLAG_KEY;
M
indent  
Michael Niedermayer 已提交
1114
                }
1115
            } else {
1116
                pkt->flags |= AV_PKT_FLAG_KEY;
1117
            }
1118
            ast->frame_offset += get_duration(ast, pkt->size);
1119 1120 1121 1122 1123 1124 1125 1126 1127 1128
        }
        ast->remaining -= size;
        if(!ast->remaining){
            avi->stream_index= -1;
            ast->packet_size= 0;
        }

        return size;
    }

1129
    if ((err = avi_sync(s, 0)) < 0)
1130 1131
        return err;
    goto resync;
F
Fabrice Bellard 已提交
1132 1133
}

D
Diego Biurrun 已提交
1134 1135
/* XXX: We make the implicit supposition that the positions are sorted
   for each stream. */
F
Fabrice Bellard 已提交
1136 1137
static int avi_read_idx1(AVFormatContext *s, int size)
{
1138
    AVIContext *avi = s->priv_data;
1139
    AVIOContext *pb = s->pb;
F
Fabrice Bellard 已提交
1140 1141 1142
    int nb_index_entries, i;
    AVStream *st;
    AVIStream *ast;
1143
    unsigned int index, tag, flags, pos, len, first_packet = 1;
1144
    unsigned last_pos= -1;
1145
    int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
1146

F
Fabrice Bellard 已提交
1147 1148 1149 1150
    nb_index_entries = size / 16;
    if (nb_index_entries <= 0)
        return -1;

1151 1152 1153 1154 1155 1156 1157 1158
    idx1_pos = avio_tell(pb);
    avio_seek(pb, avi->movi_list+4, SEEK_SET);
    if (avi_sync(s, 1) == 0) {
        first_packet_pos = avio_tell(pb) - 8;
    }
    avi->stream_index = -1;
    avio_seek(pb, idx1_pos, SEEK_SET);

D
Diego Biurrun 已提交
1159
    /* Read the entries and sort them in each stream component. */
F
Fabrice Bellard 已提交
1160
    for(i = 0; i < nb_index_entries; i++) {
1161 1162 1163 1164
        tag = avio_rl32(pb);
        flags = avio_rl32(pb);
        pos = avio_rl32(pb);
        len = avio_rl32(pb);
1165 1166
        av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
                i, tag, flags, pos, len);
1167

F
Fabrice Bellard 已提交
1168 1169 1170 1171 1172 1173
        index = ((tag & 0xff) - '0') * 10;
        index += ((tag >> 8) & 0xff) - '0';
        if (index >= s->nb_streams)
            continue;
        st = s->streams[index];
        ast = st->priv_data;
1174

1175 1176 1177 1178 1179 1180
        if(first_packet && first_packet_pos && len) {
            data_offset = first_packet_pos - pos;
            first_packet = 0;
        }
        pos += data_offset;

1181 1182
        av_dlog(s, "%d cum_len=%"PRId64"\n", len, ast->cum_len);

A
Anton Khirnov 已提交
1183
        if(pb->eof_reached)
1184 1185
            return -1;

1186 1187
        if(last_pos == pos)
            avi->non_interleaved= 1;
1188
        else if(len || !ast->sample_size)
1189
            av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
1190
        ast->cum_len += get_duration(ast, len);
1191
        last_pos= pos;
F
Fabrice Bellard 已提交
1192 1193 1194 1195
    }
    return 0;
}

1196 1197 1198 1199
static int guess_ni_flag(AVFormatContext *s){
    int i;
    int64_t last_start=0;
    int64_t first_end= INT64_MAX;
1200
    int64_t oldpos= avio_tell(s->pb);
1201

1202 1203 1204
    for(i=0; i<s->nb_streams; i++){
        AVStream *st = s->streams[i];
        int n= st->nb_index_entries;
1205
        unsigned int size;
1206 1207 1208 1209

        if(n <= 0)
            continue;

1210 1211
        if(n >= 2){
            int64_t pos= st->index_entries[0].pos;
A
Anton Khirnov 已提交
1212
            avio_seek(s->pb, pos + 4, SEEK_SET);
1213
            size= avio_rl32(s->pb);
1214 1215 1216 1217
            if(pos + size > st->index_entries[1].pos)
                last_start= INT64_MAX;
        }

1218 1219 1220 1221 1222
        if(st->index_entries[0].pos > last_start)
            last_start= st->index_entries[0].pos;
        if(st->index_entries[n-1].pos < first_end)
            first_end= st->index_entries[n-1].pos;
    }
A
Anton Khirnov 已提交
1223
    avio_seek(s->pb, oldpos, SEEK_SET);
1224 1225 1226
    return last_start > first_end;
}

F
Fabrice Bellard 已提交
1227 1228 1229
static int avi_load_index(AVFormatContext *s)
{
    AVIContext *avi = s->priv_data;
1230
    AVIOContext *pb = s->pb;
F
Fabrice Bellard 已提交
1231
    uint32_t tag, size;
1232
    int64_t pos= avio_tell(pb);
1233
    int ret = -1;
1234

A
Anton Khirnov 已提交
1235
    if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
1236
        goto the_end; // maybe truncated file
1237
    av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
F
Fabrice Bellard 已提交
1238
    for(;;) {
A
Anton Khirnov 已提交
1239
        if (pb->eof_reached)
F
Fabrice Bellard 已提交
1240
            break;
1241 1242
        tag = avio_rl32(pb);
        size = avio_rl32(pb);
1243 1244 1245 1246 1247 1248
        av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
                 tag        & 0xff,
                (tag >>  8) & 0xff,
                (tag >> 16) & 0xff,
                (tag >> 24) & 0xff,
                size);
1249 1250 1251

        if (tag == MKTAG('i', 'd', 'x', '1') &&
            avi_read_idx1(s, size) >= 0) {
1252
            ret = 0;
F
Fabrice Bellard 已提交
1253 1254
            break;
        }
1255 1256 1257 1258

        size += (size & 1);
        if (avio_skip(pb, size) < 0)
            break; // something is wrong here
F
Fabrice Bellard 已提交
1259 1260
    }
 the_end:
A
Anton Khirnov 已提交
1261
    avio_seek(pb, pos, SEEK_SET);
1262
    return ret;
F
Fabrice Bellard 已提交
1263 1264
}

1265 1266 1267 1268 1269 1270 1271 1272 1273 1274
static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
{
    AVIStream *ast2 = st2->priv_data;
    int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base);
    av_free_packet(&ast2->sub_pkt);
    if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 ||
        avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0)
        av_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
}

1275
static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
F
Fabrice Bellard 已提交
1276 1277 1278
{
    AVIContext *avi = s->priv_data;
    AVStream *st;
1279
    int i, index;
F
Fabrice Bellard 已提交
1280
    int64_t pos;
1281
    AVIStream *ast;
F
Fabrice Bellard 已提交
1282 1283 1284 1285 1286 1287

    if (!avi->index_loaded) {
        /* we only load the index on demand */
        avi_load_index(s);
        avi->index_loaded = 1;
    }
1288
    assert(stream_index>= 0);
F
Fabrice Bellard 已提交
1289 1290

    st = s->streams[stream_index];
1291 1292
    ast= st->priv_data;
    index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags);
1293
    if(index<0)
F
Fabrice Bellard 已提交
1294
        return -1;
1295

F
Fabrice Bellard 已提交
1296
    /* find the position */
1297
    pos = st->index_entries[index].pos;
1298
    timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
1299

1300
//    av_log(s, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp);
F
Fabrice Bellard 已提交
1301

1302
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1303
        /* One and only one real stream for DV in AVI, and it has video  */
1304
        /* offsets. Calling with other stream indexes should have failed */
1305 1306 1307 1308
        /* the av_index_search_timestamp call above.                     */
        assert(stream_index == 0);

        /* Feed the DV video stream version of the timestamp to the */
D
Diego Biurrun 已提交
1309
        /* DV demux so it can synthesize correct timestamps.        */
1310 1311
        dv_offset_reset(avi->dv_demux, timestamp);

A
Anton Khirnov 已提交
1312
        avio_seek(s->pb, pos, SEEK_SET);
1313 1314 1315 1316
        avi->stream_index= -1;
        return 0;
    }

F
Fabrice Bellard 已提交
1317
    for(i = 0; i < s->nb_streams; i++) {
1318 1319
        AVStream *st2 = s->streams[i];
        AVIStream *ast2 = st2->priv_data;
1320 1321 1322 1323

        ast2->packet_size=
        ast2->remaining= 0;

1324 1325 1326 1327 1328
        if (ast2->sub_ctx) {
            seek_subtitle(st, st2, timestamp);
            continue;
        }

1329 1330
        if (st2->nb_index_entries <= 0)
            continue;
1331

1332
//        assert(st2->codec->block_align);
1333
        assert((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
1334
        index = av_index_search_timestamp(
1335
                st2,
1336
                av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
1337 1338 1339
                flags | AVSEEK_FLAG_BACKWARD);
        if(index<0)
            index=0;
1340

1341 1342 1343 1344 1345 1346 1347
        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++;
        }

1348
//        av_log(s, AV_LOG_DEBUG, "%"PRId64" %d %"PRId64"\n", timestamp, index, st2->index_entries[index].timestamp);
1349 1350
        /* extract the current frame number */
        ast2->frame_offset = st2->index_entries[index].timestamp;
F
Fabrice Bellard 已提交
1351
    }
1352

F
Fabrice Bellard 已提交
1353
    /* do the seek */
A
Anton Khirnov 已提交
1354
    avio_seek(s->pb, pos, SEEK_SET);
1355
    avi->stream_index= -1;
F
Fabrice Bellard 已提交
1356 1357 1358
    return 0;
}

Z
Zdenek Kabelac 已提交
1359
static int avi_read_close(AVFormatContext *s)
F
Fabrice Bellard 已提交
1360
{
M
Michael Niedermayer 已提交
1361 1362 1363 1364 1365
    int i;
    AVIContext *avi = s->priv_data;

    for(i=0;i<s->nb_streams;i++) {
        AVStream *st = s->streams[i];
1366
        AVIStream *ast = st->priv_data;
1367
        if (ast) {
1368 1369
            if (ast->sub_ctx) {
                av_freep(&ast->sub_ctx->pb);
1370
                av_close_input_file(ast->sub_ctx);
1371 1372 1373
            }
            av_free(ast->sub_buffer);
            av_free_packet(&ast->sub_pkt);
1374
        }
M
Michael Niedermayer 已提交
1375 1376
    }

1377
    av_free(avi->dv_demux);
1378

F
Fabrice Bellard 已提交
1379 1380 1381 1382 1383
    return 0;
}

static int avi_probe(AVProbeData *p)
{
1384 1385
    int i;

F
Fabrice Bellard 已提交
1386
    /* check file header */
1387 1388 1389 1390 1391 1392
    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;
F
Fabrice Bellard 已提交
1393 1394
}

1395
AVInputFormat ff_avi_demuxer = {
1396 1397 1398 1399 1400 1401 1402 1403
    .name           = "avi",
    .long_name      = NULL_IF_CONFIG_SMALL("AVI format"),
    .priv_data_size = sizeof(AVIContext),
    .read_probe     = avi_probe,
    .read_header    = avi_read_header,
    .read_packet    = avi_read_packet,
    .read_close     = avi_read_close,
    .read_seek      = avi_read_seek,
F
Fabrice Bellard 已提交
1404
};