avidec.c 66.7 KB
Newer Older
Fabrice Bellard's avatar
Fabrice Bellard committed
1
/*
2
 * AVI demuxer
Diego Biurrun's avatar
Diego Biurrun committed
3
 * Copyright (c) 2001 Fabrice Bellard
Fabrice Bellard's avatar
Fabrice Bellard committed
4
 *
5 6 7
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
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.
Fabrice Bellard's avatar
Fabrice Bellard committed
11
 *
12
 * FFmpeg is distributed in the hope that it will be useful,
Fabrice Bellard's avatar
Fabrice Bellard committed
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 15
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
Fabrice Bellard's avatar
Fabrice Bellard committed
16
 *
17
 * You should have received a copy of the GNU Lesser General Public
18
 * License along with FFmpeg; if not, write to the Free Software
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Fabrice Bellard's avatar
Fabrice Bellard committed
20
 */
21

22
#include <inttypes.h>
23

24
#include "libavutil/avassert.h"
25
#include "libavutil/avstring.h"
26
#include "libavutil/bswap.h"
27
#include "libavutil/opt.h"
28
#include "libavutil/dict.h"
29
#include "libavutil/internal.h"
30 31
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
32 33
#include "avformat.h"
#include "avi.h"
34
#include "dv.h"
35
#include "internal.h"
36
#include "isom.h"
37
#include "riff.h"
38 39
#include "libavcodec/bytestream.h"
#include "libavcodec/exif.h"
40
#include "libavcodec/internal.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
41

Fabrice Bellard's avatar
Fabrice Bellard committed
42
typedef struct AVIStream {
43 44
    int64_t frame_offset;   /* current frame (video) or byte (audio) counter
                             * (used to compute the pts) */
45 46 47
    int remaining;
    int packet_size;

48
    uint32_t handler;
49 50
    uint32_t scale;
    uint32_t rate;
51 52
    int sample_size;        /* size of one sample (or packet)
                             * (in the rate/scale sense) in bytes */
53

54 55
    int64_t cum_len;        /* temporary storage (used during seek) */
    int prefix;             /* normally 'd'<<8 + 'c' or 'w'<<8 + 'b' */
56
    int prefix_count;
57 58
    uint32_t pal[256];
    int has_pal;
59 60
    int dshow_block_align;  /* block align variable used to emulate bugs in
                             * the MS dshow demuxer */
61 62 63 64

    AVFormatContext *sub_ctx;
    AVPacket sub_pkt;
    uint8_t *sub_buffer;
65 66

    int64_t seek_pos;
Fabrice Bellard's avatar
Fabrice Bellard committed
67
} AVIStream;
Fabrice Bellard's avatar
Fabrice Bellard committed
68

69
typedef struct AVIContext {
70
    const AVClass *class;
71 72 73
    int64_t riff_end;
    int64_t movi_end;
    int64_t fsize;
74
    int64_t io_fsize;
75
    int64_t movi_list;
76
    int64_t last_pkt_pos;
Fabrice Bellard's avatar
Fabrice Bellard committed
77
    int index_loaded;
78
    int is_odml;
79 80
    int non_interleaved;
    int stream_index;
81
    DVDemuxContext *dv_demux;
82
    int odml_depth;
83
    int use_odml;
84
#define MAX_ODML_DEPTH 1000
85
    int64_t dts_max;
Fabrice Bellard's avatar
Fabrice Bellard committed
86 87
} AVIContext;

88 89

static const AVOption options[] = {
90
    { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_BOOL, {.i64 = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
91 92 93 94
    { NULL },
};

static const AVClass demuxer_class = {
Paul B Mahol's avatar
Paul B Mahol committed
95
    .class_name = "avi",
96 97 98
    .item_name  = av_default_item_name,
    .option     = options,
    .version    = LIBAVUTIL_VERSION_INT,
Paul B Mahol's avatar
Paul B Mahol committed
99
    .category   = AV_CLASS_CATEGORY_DEMUXER,
100 101 102
};


103
static const char avi_headers[][8] = {
104 105 106 107 108
    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', ' '  },
    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 'X'  },
    { 'R', 'I', 'F', 'F', 'A', 'V', 'I', 0x19 },
    { 'O', 'N', '2', ' ', 'O', 'N', '2', 'f'  },
    { 'R', 'I', 'F', 'F', 'A', 'M', 'V', ' '  },
109 110 111
    { 0 }
};

112 113 114 115 116
static const AVMetadataConv avi_metadata_conv[] = {
    { "strn", "title" },
    { 0 },
};

117
static int avi_load_index(AVFormatContext *s);
118
static int guess_ni_flag(AVFormatContext *s);
119

120
#define print_tag(str, tag, size)                        \
121
    av_log(NULL, AV_LOG_TRACE, "pos:%"PRIX64" %s: tag=%c%c%c%c size=0x%x\n", \
122
            avio_tell(pb), str, tag & 0xff,              \
123 124 125 126
            (tag >> 8) & 0xff,                           \
            (tag >> 16) & 0xff,                          \
            (tag >> 24) & 0xff,                          \
            size)
Fabrice Bellard's avatar
Fabrice Bellard committed
127

128 129 130
static inline int get_duration(AVIStream *ast, int len)
{
    if (ast->sample_size)
131
        return len;
132
    else if (ast->dshow_block_align)
133 134
        return (len + ast->dshow_block_align - 1) / ast->dshow_block_align;
    else
135 136 137
        return 1;
}

138
static int get_riff(AVFormatContext *s, AVIOContext *pb)
139
{
140
    AVIContext *avi = s->priv_data;
141
    char header[8] = {0};
142
    int i;
143

144
    /* check RIFF header */
145
    avio_read(pb, header, 4);
146
    avi->riff_end  = avio_rl32(pb); /* RIFF chunk size */
147
    avi->riff_end += avio_tell(pb); /* RIFF chunk end */
148
    avio_read(pb, header + 4, 4);
149

150 151
    for (i = 0; avi_headers[i][0]; i++)
        if (!memcmp(header, avi_headers[i], 8))
152
            break;
153
    if (!avi_headers[i][0])
154
        return AVERROR_INVALIDDATA;
155

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

160 161 162
    return 0;
}

163 164 165 166 167 168 169 170 171 172 173 174
static int read_braindead_odml_indx(AVFormatContext *s, int frame_num)
{
    AVIContext *avi     = s->priv_data;
    AVIOContext *pb     = s->pb;
    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);
    int stream_id       = ((chunk_id      & 0xFF) - '0') * 10 +
                          ((chunk_id >> 8 & 0xFF) - '0');
175 176 177
    AVStream *st;
    AVIStream *ast;
    int i;
178
    int64_t last_pos = -1;
179
    int64_t filesize = avi->fsize;
180

181
    av_log(s, AV_LOG_TRACE,
182
            "longs_pre_entry:%d index_type:%d entries_in_use:%d "
183
            "chunk_id:%X base:%16"PRIX64" frame_num:%d\n",
184 185 186 187
            longs_pre_entry,
            index_type,
            entries_in_use,
            chunk_id,
188 189
            base,
            frame_num);
190 191

    if (stream_id >= s->nb_streams || stream_id < 0)
192
        return AVERROR_INVALIDDATA;
193
    st  = s->streams[stream_id];
194 195
    ast = st->priv_data;

196
    if (index_sub_type)
197
        return AVERROR_INVALIDDATA;
198

199
    avio_rl32(pb);
200

201
    if (index_type && longs_pre_entry != 2)
202
        return AVERROR_INVALIDDATA;
203
    if (index_type > 1)
204
        return AVERROR_INVALIDDATA;
205

206
    if (filesize > 0 && base >= filesize) {
207
        av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
208 209 210
        if (base >> 32 == (base & 0xFFFFFFFF) &&
            (base & 0xFFFFFFFF) < filesize    &&
            filesize <= 0xFFFFFFFF)
211 212
            base &= 0xFFFFFFFF;
        else
213
            return AVERROR_INVALIDDATA;
214 215
    }

216 217 218 219 220
    for (i = 0; i < entries_in_use; i++) {
        if (index_type) {
            int64_t pos = avio_rl32(pb) + base - 8;
            int len     = avio_rl32(pb);
            int key     = len >= 0;
221 222
            len &= 0x7FFFFFFF;

223
            av_log(s, AV_LOG_TRACE, "pos:%"PRId64", len:%X\n", pos, len);
224

225
            if (avio_feof(pb))
226
                return AVERROR_INVALIDDATA;
227

228 229
            if (last_pos == pos || pos == base - 8)
                avi->non_interleaved = 1;
230
            if (last_pos != pos && len)
231 232
                av_add_index_entry(st, pos, ast->cum_len, len, 0,
                                   key ? AVINDEX_KEYFRAME : 0);
233

234
            ast->cum_len += get_duration(ast, len);
235 236
            last_pos      = pos;
        } else {
Måns Rullgård's avatar
Måns Rullgård committed
237 238
            int64_t offset, pos;
            int duration;
239 240 241
            offset = avio_rl64(pb);
            avio_rl32(pb);       /* size */
            duration = avio_rl32(pb);
242

243
            if (avio_feof(pb))
244
                return AVERROR_INVALIDDATA;
245

246
            pos = avio_tell(pb);
247

248
            if (avi->odml_depth > MAX_ODML_DEPTH) {
249
                av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
250
                return AVERROR_INVALIDDATA;
251 252
            }

253
            if (avio_seek(pb, offset + 8, SEEK_SET) < 0)
254
                return -1;
255
            avi->odml_depth++;
256
            read_braindead_odml_indx(s, frame_num);
257
            avi->odml_depth--;
258 259
            frame_num += duration;

260
            if (avio_seek(pb, pos, SEEK_SET) < 0) {
261
                av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n");
262 263 264
                return -1;
            }

265 266
        }
    }
267
    avi->index_loaded = 2;
268 269 270
    return 0;
}

271 272
static void clean_index(AVFormatContext *s)
{
273 274
    int i;
    int64_t j;
275

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

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

286 287
        while (max < 1024)
            max += max;
288

289 290 291
        pos  = st->index_entries[0].pos;
        size = st->index_entries[0].size;
        ts   = st->index_entries[0].timestamp;
292

293 294 295
        for (j = 0; j < size; j += max)
            av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0,
                               AVINDEX_KEYFRAME);
296 297 298
    }
}

299 300
static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag,
                        uint32_t size)
301
{
302
    AVIOContext *pb = s->pb;
303 304
    char key[5]     = { 0 };
    char *value;
305

306
    size += (size & 1);
307

308
    if (size == UINT_MAX)
309
        return AVERROR(EINVAL);
310
    value = av_malloc(size + 1);
311
    if (!value)
312
        return AVERROR(ENOMEM);
313 314
    if (avio_read(pb, value, size) != size)
        return AVERROR_INVALIDDATA;
315
    value[size] = 0;
316

317 318
    AV_WL32(key, tag);

319
    return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
320
                       AV_DICT_DONT_STRDUP_VAL);
321 322
}

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

326
static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
327 328 329 330 331
{
    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",
332
               month, &day, time, &year) == 4) {
333
        for (i = 0; i < 12; i++)
334
            if (!av_strcasecmp(month, months[i])) {
335
                snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
336
                         year, i + 1, day, time);
337
                av_dict_set(metadata, "creation_time", buffer, 0);
338
            }
339 340
    } else if (date[4] == '/' && date[7] == '/') {
        date[4] = date[7] = '-';
341
        av_dict_set(metadata, "creation_time", date, 0);
342
    }
343 344
}

345 346
static void avi_read_nikon(AVFormatContext *s, uint64_t end)
{
347
    while (avio_tell(s->pb) < end) {
348 349
        uint32_t tag  = avio_rl32(s->pb);
        uint32_t size = avio_rl32(s->pb);
350
        switch (tag) {
351 352
        case MKTAG('n', 'c', 't', 'g'):  /* Nikon Tags */
        {
353 354
            uint64_t tag_end = avio_tell(s->pb) + size;
            while (avio_tell(s->pb) < tag_end) {
355 356
                uint16_t tag     = avio_rl16(s->pb);
                uint16_t size    = avio_rl16(s->pb);
357
                const char *name = NULL;
358
                char buffer[64]  = { 0 };
359
                size = FFMIN(size, tag_end - avio_tell(s->pb));
360
                size -= avio_read(s->pb, buffer,
361
                                  FFMIN(size, sizeof(buffer) - 1));
362
                switch (tag) {
363 364 365 366 367 368 369 370
                case 0x03:
                    name = "maker";
                    break;
                case 0x04:
                    name = "model";
                    break;
                case 0x13:
                    name = "creation_time";
371 372 373 374 375
                    if (buffer[4] == ':' && buffer[7] == ':')
                        buffer[4] = buffer[7] = '-';
                    break;
                }
                if (name)
376
                    av_dict_set(&s->metadata, name, buffer, 0);
377
                avio_skip(s->pb, size);
378 379 380 381
            }
            break;
        }
        default:
382
            avio_skip(s->pb, size);
383 384 385 386 387
            break;
        }
    }
}

388
static int avi_extract_stream_metadata(AVFormatContext *s, AVStream *st)
389 390
{
    GetByteContext gb;
391 392
    uint8_t *data = st->codecpar->extradata;
    int data_size = st->codecpar->extradata_size;
393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
    int tag, offset;

    if (!data || data_size < 8) {
        return AVERROR_INVALIDDATA;
    }

    bytestream2_init(&gb, data, data_size);

    tag = bytestream2_get_le32(&gb);

    switch (tag) {
    case MKTAG('A', 'V', 'I', 'F'):
        // skip 4 byte padding
        bytestream2_skip(&gb, 4);
        offset = bytestream2_tell(&gb);
        bytestream2_init(&gb, data + offset, data_size - offset);

        // decode EXIF tags from IFD, AVI is always little-endian
411
        return avpriv_exif_decode_ifd(s, &gb, 1, 0, &st->metadata);
412 413
        break;
    case MKTAG('C', 'A', 'S', 'I'):
414
        avpriv_request_sample(s, "RIFF stream data tag type CASI (%u)", tag);
415 416
        break;
    case MKTAG('Z', 'o', 'r', 'a'):
417
        avpriv_request_sample(s, "RIFF stream data tag type Zora (%u)", tag);
418 419 420 421 422 423 424 425
        break;
    default:
        break;
    }

    return 0;
}

426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
static int calculate_bitrate(AVFormatContext *s)
{
    AVIContext *avi = s->priv_data;
    int i, j;
    int64_t lensum = 0;
    int64_t maxpos = 0;

    for (i = 0; i<s->nb_streams; i++) {
        int64_t len = 0;
        AVStream *st = s->streams[i];

        if (!st->nb_index_entries)
            continue;

        for (j = 0; j < st->nb_index_entries; j++)
            len += st->index_entries[j].size;
        maxpos = FFMAX(maxpos, st->index_entries[j-1].pos);
        lensum += len;
    }
445
    if (maxpos < avi->io_fsize*9/10) // index does not cover the whole file
446 447 448 449 450 451 452 453
        return 0;
    if (lensum*9/10 > maxpos || lensum < maxpos*9/10) // frame sum and filesize mismatch
        return 0;

    for (i = 0; i<s->nb_streams; i++) {
        int64_t len = 0;
        AVStream *st = s->streams[i];
        int64_t duration;
454
        int64_t bitrate;
455 456 457 458

        for (j = 0; j < st->nb_index_entries; j++)
            len += st->index_entries[j].size;

459
        if (st->nb_index_entries < 2 || st->codecpar->bit_rate > 0)
460 461
            continue;
        duration = st->index_entries[j-1].timestamp - st->index_entries[0].timestamp;
462 463
        bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num);
        if (bitrate <= INT_MAX && bitrate > 0) {
464
            st->codecpar->bit_rate = bitrate;
465
        }
466 467 468 469
    }
    return 1;
}

470
static int avi_read_header(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
471
{
Fabrice Bellard's avatar
Fabrice Bellard committed
472
    AVIContext *avi = s->priv_data;
473
    AVIOContext *pb = s->pb;
474
    unsigned int tag, tag1, handler;
475
    int codec_type, stream_index, frame_period;
Michael Niedermayer's avatar
Michael Niedermayer committed
476
    unsigned int size;
477
    int i;
Fabrice Bellard's avatar
Fabrice Bellard committed
478
    AVStream *st;
479 480 481 482
    AVIStream *ast      = NULL;
    int avih_width      = 0, avih_height = 0;
    int amv_file_format = 0;
    uint64_t list_end   = 0;
483
    int64_t pos;
484
    int ret;
485
    AVDictionaryEntry *dict_entry;
Fabrice Bellard's avatar
Fabrice Bellard committed
486

487
    avi->stream_index = -1;
488

489 490 491
    ret = get_riff(s, pb);
    if (ret < 0)
        return ret;
492

493 494
    av_log(avi, AV_LOG_DEBUG, "use odml:%d\n", avi->use_odml);

495
    avi->io_fsize = avi->fsize = avio_size(pb);
496
    if (avi->fsize <= 0 || avi->fsize < avi->riff_end)
497
        avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
498

Fabrice Bellard's avatar
Fabrice Bellard committed
499 500
    /* first list tag */
    stream_index = -1;
501
    codec_type   = -1;
Fabrice Bellard's avatar
Fabrice Bellard committed
502
    frame_period = 0;
503
    for (;;) {
504
        if (avio_feof(pb))
Fabrice Bellard's avatar
Fabrice Bellard committed
505
            goto fail;
506
        tag  = avio_rl32(pb);
507
        size = avio_rl32(pb);
508

Fabrice Bellard's avatar
Fabrice Bellard committed
509 510
        print_tag("tag", tag, size);

511
        switch (tag) {
Fabrice Bellard's avatar
Fabrice Bellard committed
512
        case MKTAG('L', 'I', 'S', 'T'):
513
            list_end = avio_tell(pb) + size;
Diego Biurrun's avatar
Diego Biurrun committed
514
            /* Ignored, except at start of video packets. */
515
            tag1 = avio_rl32(pb);
516

Fabrice Bellard's avatar
Fabrice Bellard committed
517
            print_tag("list", tag1, 0);
518

Fabrice Bellard's avatar
Fabrice Bellard committed
519
            if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
520
                avi->movi_list = avio_tell(pb) - 4;
521 522 523
                if (size)
                    avi->movi_end = avi->movi_list + size + (size & 1);
                else
524
                    avi->movi_end = avi->fsize;
525
                av_log(NULL, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end);
Fabrice Bellard's avatar
Fabrice Bellard committed
526
                goto end_of_header;
527
            } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
528
                ff_read_riff_info(s, size - 4);
529 530
            else if (tag1 == MKTAG('n', 'c', 'd', 't'))
                avi_read_nikon(s, list_end);
531

Fabrice Bellard's avatar
Fabrice Bellard committed
532
            break;
533 534 535
        case MKTAG('I', 'D', 'I', 'T'):
        {
            unsigned char date[64] = { 0 };
536
            size += (size & 1);
537
            size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1));
538
            avio_skip(pb, size);
539 540 541
            avi_metadata_creation_time(&s->metadata, date);
            break;
        }
542
        case MKTAG('d', 'm', 'l', 'h'):
543
            avi->is_odml = 1;
544
            avio_skip(pb, size + (size & 1));
545
            break;
546
        case MKTAG('a', 'm', 'v', 'h'):
547
            amv_file_format = 1;
Fabrice Bellard's avatar
Fabrice Bellard committed
548
        case MKTAG('a', 'v', 'i', 'h'):
Diego Biurrun's avatar
Diego Biurrun committed
549
            /* AVI header */
550
            /* using frame_period is bad idea */
551
            frame_period = avio_rl32(pb);
552
            avio_rl32(pb); /* max. bytes per second */
553 554
            avio_rl32(pb);
            avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
555

556
            avio_skip(pb, 2 * 4);
557 558
            avio_rl32(pb);
            avio_rl32(pb);
559 560
            avih_width  = avio_rl32(pb);
            avih_height = avio_rl32(pb);
561

562
            avio_skip(pb, size - 10 * 4);
563 564 565 566
            break;
        case MKTAG('s', 't', 'r', 'h'):
            /* stream header */

567
            tag1    = avio_rl32(pb);
568
            handler = avio_rl32(pb); /* codec tag */
569

570
            if (tag1 == MKTAG('p', 'a', 'd', 's')) {
571
                avio_skip(pb, size - 8);
572
                break;
573
            } else {
574
                stream_index++;
575
                st = avformat_new_stream(s, NULL);
Fabrice Bellard's avatar
Fabrice Bellard committed
576 577
                if (!st)
                    goto fail;
578

579
                st->id = stream_index;
580
                ast    = av_mallocz(sizeof(AVIStream));
Fabrice Bellard's avatar
Fabrice Bellard committed
581 582 583
                if (!ast)
                    goto fail;
                st->priv_data = ast;
584
            }
585 586 587
            if (amv_file_format)
                tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')
                                    : MKTAG('v', 'i', 'd', 's');
588

589
            print_tag("strh", tag1, -1);
590

591 592
            if (tag1 == MKTAG('i', 'a', 'v', 's') ||
                tag1 == MKTAG('i', 'v', 'a', 's')) {
593 594
                int64_t dv_dur;

595 596
                /* After some consideration -- I don't think we
                 * have to support anything but DV in type1 AVIs. */
597 598 599 600 601 602
                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'))
603
                    goto fail;
604 605

                ast = s->streams[0]->priv_data;
606 607
                av_freep(&s->streams[0]->codecpar->extradata);
                av_freep(&s->streams[0]->codecpar);
608 609
                if (s->streams[0]->info)
                    av_freep(&s->streams[0]->info->duration_error);
610
                av_freep(&s->streams[0]->info);
611 612
                av_freep(&s->streams[0]);
                s->nb_streams = 0;
613
                if (CONFIG_DV_DEMUXER) {
614
                    avi->dv_demux = avpriv_dv_init_demux(s);
615 616
                    if (!avi->dv_demux)
                        goto fail;
617 618
                } else
                    goto fail;
619
                s->streams[0]->priv_data = ast;
620
                avio_skip(pb, 3 * 4);
621
                ast->scale = avio_rl32(pb);
622
                ast->rate  = avio_rl32(pb);
623
                avio_skip(pb, 4);  /* start time */
624

625
                dv_dur = avio_rl32(pb);
626
                if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
627
                    dv_dur     *= AV_TIME_BASE;
628 629
                    s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
                }
630 631
                /* else, leave duration alone; timing estimation in utils.c
                 * will make a guess based on bitrate. */
632

633
                stream_index = s->nb_streams - 1;
634
                avio_skip(pb, size - 9 * 4);
635 636
                break;
            }
637

638
            av_assert0(stream_index < s->nb_streams);
639
            ast->handler = handler;
640

641 642 643 644 645
            avio_rl32(pb); /* flags */
            avio_rl16(pb); /* priority */
            avio_rl16(pb); /* language */
            avio_rl32(pb); /* initial frame */
            ast->scale = avio_rl32(pb);
646 647 648
            ast->rate  = avio_rl32(pb);
            if (!(ast->scale && ast->rate)) {
                av_log(s, AV_LOG_WARNING,
649
                       "scale/rate is %"PRIu32"/%"PRIu32" which is invalid. "
650 651 652 653 654
                       "(This file has been generated by broken software.)\n",
                       ast->scale,
                       ast->rate);
                if (frame_period) {
                    ast->rate  = 1000000;
Michael Niedermayer's avatar
Michael Niedermayer committed
655
                    ast->scale = frame_period;
656 657
                } else {
                    ast->rate  = 25;
Michael Niedermayer's avatar
Michael Niedermayer committed
658 659
                    ast->scale = 1;
                }
660
            }
661
            avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
662

663
            ast->cum_len  = avio_rl32(pb); /* start */
664
            st->nb_frames = avio_rl32(pb);
665

666
            st->start_time = 0;
667 668
            avio_rl32(pb); /* buffer size */
            avio_rl32(pb); /* quality */
669 670
            if (ast->cum_len*ast->scale/ast->rate > 3600) {
                av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");
671
                ast->cum_len = 0;
672
            }
673
            ast->sample_size = avio_rl32(pb); /* sample ssize */
674
            ast->cum_len    *= FFMAX(1, ast->sample_size);
675
            av_log(s, AV_LOG_TRACE, "%"PRIu32" %"PRIu32" %d\n",
676
                    ast->rate, ast->scale, ast->sample_size);
677

678
            switch (tag1) {
679
            case MKTAG('v', 'i', 'd', 's'):
680
                codec_type = AVMEDIA_TYPE_VIDEO;
681

682
                ast->sample_size = 0;
683
                st->avg_frame_rate = av_inv_q(st->time_base);
684 685
                break;
            case MKTAG('a', 'u', 'd', 's'):
686
                codec_type = AVMEDIA_TYPE_AUDIO;
687
                break;
688
            case MKTAG('t', 'x', 't', 's'):
689
                codec_type = AVMEDIA_TYPE_SUBTITLE;
690
                break;
Florian Echtler's avatar
Florian Echtler committed
691
            case MKTAG('d', 'a', 't', 's'):
692
                codec_type = AVMEDIA_TYPE_DATA;
Florian Echtler's avatar
Florian Echtler committed
693
                break;
694
            default:
695
                av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
Fabrice Bellard's avatar
Fabrice Bellard committed
696
            }
697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713

            if (ast->sample_size < 0) {
                if (s->error_recognition & AV_EF_EXPLODE) {
                    av_log(s, AV_LOG_ERROR,
                           "Invalid sample_size %d at stream %d\n",
                           ast->sample_size,
                           stream_index);
                    goto fail;
                }
                av_log(s, AV_LOG_WARNING,
                       "Invalid sample_size %d at stream %d "
                       "setting it to 0\n",
                       ast->sample_size,
                       stream_index);
                ast->sample_size = 0;
            }

714
            if (ast->sample_size == 0) {
715
                st->duration = st->nb_frames;
716 717 718 719 720
                if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) {
                    av_log(s, AV_LOG_DEBUG, "File is truncated adjusting duration\n");
                    st->duration = av_rescale(st->duration, avi->io_fsize, avi->riff_end);
                }
            }
721
            ast->frame_offset = ast->cum_len;
722
            avio_skip(pb, size - 12 * 4);
Fabrice Bellard's avatar
Fabrice Bellard committed
723 724 725
            break;
        case MKTAG('s', 't', 'r', 'f'):
            /* stream header */
726 727
            if (!size)
                break;
728
            if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
729
                avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
730
            } else {
731
                uint64_t cur_pos = avio_tell(pb);
732
                unsigned esize;
733 734
                if (cur_pos < list_end)
                    size = FFMIN(size, list_end - cur_pos);
Fabrice Bellard's avatar
Fabrice Bellard committed
735
                st = s->streams[stream_index];
736
                if (st->codecpar->codec_type != AVMEDIA_TYPE_UNKNOWN) {
737 738 739
                    avio_skip(pb, size);
                    break;
                }
740
                switch (codec_type) {
741
                case AVMEDIA_TYPE_VIDEO:
742
                    if (amv_file_format) {
743 744 745 746
                        st->codecpar->width      = avih_width;
                        st->codecpar->height     = avih_height;
                        st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
                        st->codecpar->codec_id   = AV_CODEC_ID_AMV;
747
                        avio_skip(pb, size);
748 749
                        break;
                    }
750
                    tag1 = ff_get_bmp_header(pb, st, &esize);
751

752 753
                    if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
                        tag1 == MKTAG('D', 'X', 'S', 'A')) {
754 755 756
                        st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
                        st->codecpar->codec_tag  = tag1;
                        st->codecpar->codec_id   = AV_CODEC_ID_XSUB;
757 758 759
                        break;
                    }

760 761
                    if (size > 10 * 4 && size < (1 << 30) && size < avi->fsize) {
                        if (esize == size-1 && (esize&1)) {
762
                            st->codecpar->extradata_size = esize - 10 * 4;
763
                        } else
764
                            st->codecpar->extradata_size =  size - 10 * 4;
765
                        if (ff_get_extradata(s, st->codecpar, pb, st->codecpar->extradata_size) < 0)
766
                            return AVERROR(ENOMEM);
767
                    }
768

769
                    // FIXME: check if the encoder really did this correctly
770
                    if (st->codecpar->extradata_size & 1)
771
                        avio_r8(pb);
772

773 774 775
                    /* Extract palette from extradata if bpp <= 8.
                     * This code assumes that extradata contains only palette.
                     * This is true for all paletted codecs implemented in
776
                     * FFmpeg. */
777 778 779
                    if (st->codecpar->extradata_size &&
                        (st->codecpar->bits_per_coded_sample <= 8)) {
                        int pal_size = (1 << st->codecpar->bits_per_coded_sample) << 2;
780 781
                        const uint8_t *pal_src;

782 783 784
                        pal_size = FFMIN(pal_size, st->codecpar->extradata_size);
                        pal_src  = st->codecpar->extradata +
                                   st->codecpar->extradata_size - pal_size;
785
                        /* Exclude the "BottomUp" field from the palette */
786 787
                        if (pal_src - st->codecpar->extradata >= 9 &&
                            !memcmp(st->codecpar->extradata + st->codecpar->extradata_size - 9, "BottomUp", 9))
788
                            pal_src -= 9;
789
                        for (i = 0; i < pal_size / 4; i++)
790
                            ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
791
                        ast->has_pal = 1;
792 793
                    }

Fabrice Bellard's avatar
Fabrice Bellard committed
794
                    print_tag("video", tag1, 0);
795

796 797 798
                    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
                    st->codecpar->codec_tag  = tag1;
                    st->codecpar->codec_id   = ff_codec_get_id(ff_codec_bmp_tags,
799
                                                            tag1);
800
                    /* If codec is not found yet, try with the mov tags. */
801
                    if (!st->codecpar->codec_id) {
802 803
                        char tag_buf[32];
                        av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag1);
804
                        st->codecpar->codec_id =
805
                            ff_codec_get_id(ff_codec_movvideo_tags, tag1);
806
                        if (st->codecpar->codec_id)
807 808 809
                           av_log(s, AV_LOG_WARNING,
                                  "mov tag found in avi (fourcc %s)\n",
                                  tag_buf);
810
                    }
811 812 813
                    /* This is needed to get the pict type which is necessary
                     * for generating correct pts. */
                    st->need_parsing = AVSTREAM_PARSE_HEADERS;
814

815
                    if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4 &&
816
                        ast->handler == MKTAG('X', 'V', 'I', 'D'))
817
                        st->codecpar->codec_tag = MKTAG('X', 'V', 'I', 'D');
818

819
                    if (st->codecpar->codec_tag == MKTAG('V', 'S', 'S', 'H'))
820
                        st->need_parsing = AVSTREAM_PARSE_FULL;
821
                    if (st->codecpar->codec_id == AV_CODEC_ID_RV40)
822
                        st->need_parsing = AVSTREAM_PARSE_NONE;
823

824 825 826 827 828
                    if (st->codecpar->codec_tag == 0 && st->codecpar->height > 0 &&
                        st->codecpar->extradata_size < 1U << 30) {
                        st->codecpar->extradata_size += 9;
                        if ((ret = av_reallocp(&st->codecpar->extradata,
                                               st->codecpar->extradata_size +
829
                                               AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
830
                            st->codecpar->extradata_size = 0;
831
                            return ret;
832
                        } else
833
                            memcpy(st->codecpar->extradata + st->codecpar->extradata_size - 9,
834
                                   "BottomUp", 9);
835
                    }
836
                    st->codecpar->height = FFABS(st->codecpar->height);
837

838
//                    avio_skip(pb, size - 5 * 4);
Fabrice Bellard's avatar
Fabrice Bellard committed
839
                    break;
840
                case AVMEDIA_TYPE_AUDIO:
841
                    ret = ff_get_wav_header(s, pb, st->codecpar, size, 0);
842 843
                    if (ret < 0)
                        return ret;
844 845 846
                    ast->dshow_block_align = st->codecpar->block_align;
                    if (ast->sample_size && st->codecpar->block_align &&
                        ast->sample_size != st->codecpar->block_align) {
847 848 849 850
                        av_log(s,
                               AV_LOG_WARNING,
                               "sample size (%d) != block align (%d)\n",
                               ast->sample_size,
851 852
                               st->codecpar->block_align);
                        ast->sample_size = st->codecpar->block_align;
853
                    }
854 855 856
                    /* 2-aligned
                     * (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
                    if (size & 1)
857
                        avio_skip(pb, 1);
Diego Biurrun's avatar
Diego Biurrun committed
858
                    /* Force parsing as several audio frames can be in
Diego Biurrun's avatar
Diego Biurrun committed
859
                     * one packet and timestamps refer to packet start. */
860
                    st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
Diego Biurrun's avatar
Diego Biurrun committed
861 862 863
                    /* ADTS header is in extradata, AAC without header must be
                     * stored as exact frames. Parser not needed and it will
                     * fail. */
864 865
                    if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
                        st->codecpar->extradata_size)
866
                        st->need_parsing = AVSTREAM_PARSE_NONE;
867
                    // The flac parser does not work with AVSTREAM_PARSE_TIMESTAMPS
868
                    if (st->codecpar->codec_id == AV_CODEC_ID_FLAC)
869
                        st->need_parsing = AVSTREAM_PARSE_NONE;
870 871
                    /* AVI files with Xan DPCM audio (wrongly) declare PCM
                     * audio in the header but have Axan as stream_code_tag. */
872
                    if (ast->handler == AV_RL32("Axan")) {
873 874
                        st->codecpar->codec_id  = AV_CODEC_ID_XAN_DPCM;
                        st->codecpar->codec_tag = 0;
875
                        ast->dshow_block_align = 0;
876
                    }
877
                    if (amv_file_format) {
878
                        st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_IMA_AMV;
879 880
                        ast->dshow_block_align = 0;
                    }
881 882 883
                    if ((st->codecpar->codec_id == AV_CODEC_ID_AAC  ||
                         st->codecpar->codec_id == AV_CODEC_ID_FLAC ||
                         st->codecpar->codec_id == AV_CODEC_ID_MP2 ) && ast->dshow_block_align <= 4 && ast->dshow_block_align) {
884 885 886
                        av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align);
                        ast->dshow_block_align = 0;
                    }
887 888 889
                    if (st->codecpar->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 1024 && ast->sample_size == 1024 ||
                       st->codecpar->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align == 4096 && ast->sample_size == 4096 ||
                       st->codecpar->codec_id == AV_CODEC_ID_MP3 && ast->dshow_block_align == 1152 && ast->sample_size == 1152) {
890
                        av_log(s, AV_LOG_DEBUG, "overriding sample_size\n");
891 892
                        ast->sample_size = 0;
                    }
Fabrice Bellard's avatar
Fabrice Bellard committed
893
                    break;
894
                case AVMEDIA_TYPE_SUBTITLE:
895
                    st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
896
                    st->request_probe= 1;
897
                    avio_skip(pb, size);
898
                    break;
Fabrice Bellard's avatar
Fabrice Bellard committed
899
                default:
900 901 902
                    st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
                    st->codecpar->codec_id   = AV_CODEC_ID_NONE;
                    st->codecpar->codec_tag  = 0;
903
                    avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
904 905 906 907
                    break;
                }
            }
            break;
908
        case MKTAG('s', 't', 'r', 'd'):
909
            if (stream_index >= (unsigned)s->nb_streams
910 911
                || s->streams[stream_index]->codecpar->extradata_size
                || s->streams[stream_index]->codecpar->codec_tag == MKTAG('H','2','6','4')) {
912 913 914 915 916 917 918
                avio_skip(pb, size);
            } else {
                uint64_t cur_pos = avio_tell(pb);
                if (cur_pos < list_end)
                    size = FFMIN(size, list_end - cur_pos);
                st = s->streams[stream_index];

919
                if (size<(1<<30)) {
920
                    if (ff_get_extradata(s, st->codecpar, pb, size) < 0)
921 922 923
                        return AVERROR(ENOMEM);
                }

924
                if (st->codecpar->extradata_size & 1) //FIXME check if the encoder really did this correctly
925
                    avio_r8(pb);
926

927
                ret = avi_extract_stream_metadata(s, st);
928 929 930
                if (ret < 0) {
                    av_log(s, AV_LOG_WARNING, "could not decoding EXIF data in stream header.\n");
                }
931 932
            }
            break;
933
        case MKTAG('i', 'n', 'd', 'x'):
934
            pos = avio_tell(pb);
935
            if (pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) &&
936
                avi->use_odml &&
937 938
                read_braindead_odml_indx(s, 0) < 0 &&
                (s->error_recognition & AV_EF_EXPLODE))
939
                goto fail;
940
            avio_seek(pb, pos + size, SEEK_SET);
941
            break;
942
        case MKTAG('v', 'p', 'r', 'p'):
943
            if (stream_index < (unsigned)s->nb_streams && size > 9 * 4) {
944 945 946
                AVRational active, active_aspect;

                st = s->streams[stream_index];
947 948 949 950 951 952
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);

953 954 955 956 957
                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
958

959 960 961
                if (active_aspect.num && active_aspect.den &&
                    active.num && active.den) {
                    st->sample_aspect_ratio = av_div_q(active_aspect, active);
962
                    av_log(s, AV_LOG_TRACE, "vprp %d/%d %d/%d\n",
963 964
                            active_aspect.num, active_aspect.den,
                            active.num, active.den);
965
                }
966
                size -= 9 * 4;
967
            }
968
            avio_skip(pb, size);
969
            break;
970
        case MKTAG('s', 't', 'r', 'n'):
971 972
            if (s->nb_streams) {
                ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
973 974
                if (ret < 0)
                    return ret;
975 976
                break;
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
977
        default:
978 979 980 981
            if (size > 1000000) {
                av_log(s, AV_LOG_ERROR,
                       "Something went wrong during header parsing, "
                       "I will ignore it and try to continue anyway.\n");
982 983
                if (s->error_recognition & AV_EF_EXPLODE)
                    goto fail;
984
                avi->movi_list = avio_tell(pb) - 4;
985
                avi->movi_end  = avi->fsize;
986 987
                goto end_of_header;
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
988 989
            /* skip tag */
            size += (size & 1);
990
            avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
991 992 993
            break;
        }
    }
994 995

end_of_header:
Fabrice Bellard's avatar
Fabrice Bellard committed
996 997
    /* check stream number */
    if (stream_index != s->nb_streams - 1) {
998 999

fail:
1000
        return AVERROR_INVALIDDATA;
Fabrice Bellard's avatar
Fabrice Bellard committed
1001
    }
1002

1003
    if (!avi->index_loaded && pb->seekable)
1004
        avi_load_index(s);
1005
    calculate_bitrate(s);
1006
    avi->index_loaded    |= 1;
1007 1008 1009 1010

    if ((ret = guess_ni_flag(s)) < 0)
        return ret;

1011
    avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS);
1012 1013 1014

    dict_entry = av_dict_get(s->metadata, "ISFT", NULL, 0);
    if (dict_entry && !strcmp(dict_entry->value, "PotEncoder"))
1015
        for (i = 0; i < s->nb_streams; i++) {
1016
            AVStream *st = s->streams[i];
1017 1018
            if (   st->codecpar->codec_id == AV_CODEC_ID_MPEG1VIDEO
                || st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1019 1020 1021
                st->need_parsing = AVSTREAM_PARSE_FULL;
        }

1022
    for (i = 0; i < s->nb_streams; i++) {
1023
        AVStream *st = s->streams[i];
1024
        if (st->nb_index_entries)
1025 1026
            break;
    }
1027 1028
    // DV-in-AVI cannot be non-interleaved, if set this must be
    // a mis-detection.
1029 1030
    if (avi->dv_demux)
        avi->non_interleaved = 0;
1031 1032 1033 1034
    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;
1035 1036
    }

1037
    if (avi->non_interleaved) {
Diego Biurrun's avatar
Diego Biurrun committed
1038
        av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
1039
        clean_index(s);
1040
    }
1041

1042 1043
    ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);
    ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
1044

Fabrice Bellard's avatar
Fabrice Bellard committed
1045 1046 1047
    return 0;
}

1048
static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
1049
{
1050
    if (pkt->size >= 7 &&
1051
        pkt->size < INT_MAX - AVPROBE_PADDING_SIZE &&
1052
        !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
1053
        uint8_t desc[256];
1054
        int score      = AVPROBE_SCORE_EXTENSION, ret;
1055 1056 1057
        AVIStream *ast = st->priv_data;
        AVInputFormat *sub_demuxer;
        AVRational time_base;
1058
        int size;
1059 1060 1061
        AVIOContext *pb = avio_alloc_context(pkt->data + 7,
                                             pkt->size - 7,
                                             0, NULL, NULL, NULL, NULL);
1062
        AVProbeData pd;
1063
        unsigned int desc_len = avio_rl32(pb);
1064

1065 1066
        if (desc_len > pb->buf_end - pb->buf_ptr)
            goto error;
1067

1068
        ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
1069
        avio_skip(pb, desc_len - ret);
1070
        if (*desc)
1071
            av_dict_set(&st->metadata, "title", desc, 0);
1072

1073 1074
        avio_rl16(pb);   /* flags? */
        avio_rl32(pb);   /* data size */
1075

1076 1077 1078 1079 1080 1081 1082 1083 1084
        size = pb->buf_end - pb->buf_ptr;
        pd = (AVProbeData) { .buf      = av_mallocz(size + AVPROBE_PADDING_SIZE),
                             .buf_size = size };
        if (!pd.buf)
            goto error;
        memcpy(pd.buf, pb->buf_ptr, size);
        sub_demuxer = av_probe_input_format2(&pd, 1, &score);
        av_freep(&pd.buf);
        if (!sub_demuxer)
1085
            goto error;
1086

1087 1088 1089
        if (!(ast->sub_ctx = avformat_alloc_context()))
            goto error;

1090
        ast->sub_ctx->pb = pb;
1091

1092
        if (ff_copy_whiteblacklists(ast->sub_ctx, s) < 0)
1093
            goto error;
1094

1095
        if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
1096
            ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
1097
            avcodec_parameters_copy(st->codecpar, ast->sub_ctx->streams[0]->codecpar);
1098
            time_base = ast->sub_ctx->streams[0]->time_base;
1099
            avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
1100 1101 1102 1103
        }
        ast->sub_buffer = pkt->data;
        memset(pkt, 0, sizeof(*pkt));
        return 1;
1104

1105
error:
1106
        av_freep(&ast->sub_ctx);
1107
        av_freep(&pb);
1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122
    }
    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);

1123
    for (i = 0; i < s->nb_streams; i++) {
1124 1125
        st  = s->streams[i];
        ast = st->priv_data;
1126
        if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
1127 1128 1129 1130 1131 1132 1133 1134 1135
            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) {
1136 1137
        ast               = sub_st->priv_data;
        *pkt              = ast->sub_pkt;
1138
        pkt->stream_index = sub_st->index;
1139

1140
        if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
1141 1142 1143 1144 1145
            ast->sub_pkt.data = NULL;
    }
    return sub_st;
}

1146
static int get_stream_idx(const unsigned *d)
1147 1148 1149
{
    if (d[0] >= '0' && d[0] <= '9' &&
        d[1] >= '0' && d[1] <= '9') {
1150
        return (d[0] - '0') * 10 + (d[1] - '0');
1151 1152
    } else {
        return 100; // invalid stream ID
1153 1154 1155
    }
}

1156 1157 1158 1159
/**
 *
 * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet
 */
1160
static int avi_sync(AVFormatContext *s, int exit_early)
Fabrice Bellard's avatar
Fabrice Bellard committed
1161 1162
{
    AVIContext *avi = s->priv_data;
1163
    AVIOContext *pb = s->pb;
1164 1165
    int n;
    unsigned int d[8];
1166
    unsigned int size;
1167
    int64_t i, sync;
1168 1169

start_sync:
1170
    memset(d, -1, sizeof(d));
1171
    for (i = sync = avio_tell(pb); !avio_feof(pb); i++) {
1172 1173
        int j;

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

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

1180
        n = get_stream_idx(d + 2);
1181
        ff_tlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
1182
                d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
1183
        if (i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
1184 1185
            continue;

1186 1187 1188 1189 1190
        // 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')) {
1191 1192 1193 1194
            avio_skip(pb, size);
            goto start_sync;
        }

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

1201
        n = get_stream_idx(d);
1202

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

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

1213 1214 1215
        if (avi->dv_demux && n != 0)
            continue;

1216 1217
        // parse ##dc/##wb
        if (n < s->nb_streams) {
1218 1219
            AVStream *st;
            AVIStream *ast;
1220
            st  = s->streams[n];
1221 1222
            ast = st->priv_data;

1223
            if (!ast) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1224
                av_log(s, AV_LOG_WARNING, "Skipping foreign stream %d packet\n", n);
1225 1226 1227
                continue;
            }

1228 1229 1230 1231
            if (s->nb_streams >= 2) {
                AVStream *st1   = s->streams[1];
                AVIStream *ast1 = st1->priv_data;
                // workaround for broken small-file-bug402.avi
1232 1233
                if (   d[2] == 'w' && d[3] == 'b'
                   && n == 0
1234 1235
                   && st ->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
                   && st1->codecpar->codec_type == AVMEDIA_TYPE_AUDIO
1236 1237
                   && ast->prefix == 'd'*256+'c'
                   && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
1238
                  ) {
1239 1240
                    n   = 1;
                    st  = st1;
1241
                    ast = ast1;
1242 1243
                    av_log(s, AV_LOG_WARNING,
                           "Invalid stream + prefix combination, assuming audio.\n");
1244 1245 1246
                }
            }

1247 1248 1249 1250 1251 1252
            if (!avi->dv_demux &&
                ((st->discard >= AVDISCARD_DEFAULT && size == 0) /* ||
                 // FIXME: needs a little reordering
                 (st->discard >= AVDISCARD_NONKEY &&
                 !(pkt->flags & AV_PKT_FLAG_KEY)) */
                || st->discard >= AVDISCARD_ALL)) {
1253 1254
                if (!exit_early) {
                    ast->frame_offset += get_duration(ast, size);
1255 1256
                    avio_skip(pb, size);
                    goto start_sync;
1257
                }
1258 1259
            }

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

1264
                avio_rl16(pb); // flags
1265

1266
                // b + (g << 8) + (r << 16);
1267
                for (; k <= last; k++)
1268
                    ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;
1269

1270 1271 1272 1273 1274 1275 1276
                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') */) {
1277 1278
                if (exit_early)
                    return 0;
1279
                if (d[2] * 256 + d[3] == ast->prefix)
1280
                    ast->prefix_count++;
1281 1282 1283
                else {
                    ast->prefix       = d[2] * 256 + d[3];
                    ast->prefix_count = 0;
1284 1285
                }

1286 1287 1288
                avi->stream_index = n;
                ast->packet_size  = size + 8;
                ast->remaining    = size;
1289

1290
                if (size) {
1291 1292 1293 1294 1295
                    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);
1296 1297 1298 1299 1300 1301 1302
                    }
                }
                return 0;
            }
        }
    }

1303
    if (pb->error)
1304
        return pb->error;
1305 1306 1307
    return AVERROR_EOF;
}

1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345
static int ni_prepare_read(AVFormatContext *s)
{
    AVIContext *avi = s->priv_data;
    int best_stream_index = 0;
    AVStream *best_st     = NULL;
    AVIStream *best_ast;
    int64_t best_ts = INT64_MAX;
    int i;

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

        if (!st->nb_index_entries)
            continue;

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

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

        av_log(s, AV_LOG_TRACE, "%"PRId64" %d/%d %"PRId64"\n", ts,
                st->time_base.num, st->time_base.den, ast->frame_offset);
        if (ts < best_ts) {
            best_ts           = ts;
            best_st           = st;
            best_stream_index = i;
        }
    }
    if (!best_st)
        return AVERROR_EOF;

    best_ast = best_st->priv_data;
1346
    best_ts  = best_ast->frame_offset;
1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360
    if (best_ast->remaining) {
        i = av_index_search_timestamp(best_st,
                                      best_ts,
                                      AVSEEK_FLAG_ANY |
                                      AVSEEK_FLAG_BACKWARD);
    } else {
        i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
        if (i >= 0)
            best_ast->frame_offset = best_st->index_entries[i].timestamp;
    }

    if (i >= 0) {
        int64_t pos = best_st->index_entries[i].pos;
        pos += best_ast->packet_size - best_ast->remaining;
1361 1362
        if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
          return AVERROR_EOF;
1363

1364
        av_assert0(best_ast->remaining <= best_ast->packet_size);
1365 1366 1367 1368 1369 1370

        avi->stream_index = best_stream_index;
        if (!best_ast->remaining)
            best_ast->packet_size =
            best_ast->remaining   = best_st->index_entries[i].size;
    }
1371 1372
    else
        return AVERROR_EOF;
1373 1374 1375 1376

    return 0;
}

1377 1378 1379 1380 1381
static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIContext *avi = s->priv_data;
    AVIOContext *pb = s->pb;
    int err;
1382

1383
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1384
        int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
1385 1386
        if (size >= 0)
            return size;
1387 1388
        else
            goto resync;
1389
    }
1390

1391
    if (avi->non_interleaved) {
1392 1393 1394
        err = ni_prepare_read(s);
        if (err < 0)
            return err;
1395
    }
1396

1397
resync:
1398 1399 1400
    if (avi->stream_index >= 0) {
        AVStream *st   = s->streams[avi->stream_index];
        AVIStream *ast = st->priv_data;
1401
        int size, err;
1402

1403
        if (get_subtitle_pkt(s, st, pkt))
1404 1405
            return 0;

1406 1407 1408 1409
        // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
        if (ast->sample_size <= 1)
            size = INT_MAX;
        else if (ast->sample_size < 32)
1410
            // arbitrary multiplier to avoid tiny packets for raw PCM data
1411
            size = 1024 * ast->sample_size;
1412
        else
1413
            size = ast->sample_size;
1414

1415 1416 1417 1418 1419
        if (size > ast->remaining)
            size = ast->remaining;
        avi->last_pkt_pos = avio_tell(pb);
        err               = av_get_packet(pb, pkt, size);
        if (err < 0)
1420
            return err;
1421
        size = err;
1422

1423
        if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) {
1424
            uint8_t *pal;
1425 1426 1427 1428 1429 1430 1431
            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 {
1432 1433 1434
                memcpy(pal, ast->pal, AVPALETTE_SIZE);
                ast->has_pal = 0;
            }
1435 1436
        }

1437
        if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1438
            AVBufferRef *avbuf = pkt->buf;
1439
            size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
1440
                                            pkt->data, pkt->size, pkt->pos);
1441
            pkt->buf    = avbuf;
1442
            pkt->flags |= AV_PKT_FLAG_KEY;
1443
            if (size < 0)
1444
                av_packet_unref(pkt);
1445
        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
1446
                   !st->codecpar->codec_tag && read_gab2_sub(s, st, pkt)) {
1447 1448
            ast->frame_offset++;
            avi->stream_index = -1;
1449
            ast->remaining    = 0;
1450
            goto resync;
1451
        } else {
Diego Biurrun's avatar
Diego Biurrun committed
1452
            /* XXX: How to handle B-frames in AVI? */
1453 1454
            pkt->dts = ast->frame_offset;
//                pkt->dts += ast->start;
1455
            if (ast->sample_size)
1456
                pkt->dts /= ast->sample_size;
1457
            av_log(s, AV_LOG_TRACE,
1458 1459 1460 1461 1462 1463 1464 1465 1466 1467
                    "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);
1468 1469
            pkt->stream_index = avi->stream_index;

1470
            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1471 1472
                AVIndexEntry *e;
                int index;
1473

1474
                index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY);
1475
                e     = &st->index_entries[index];
1476

1477 1478
                if (index >= 0 && e->timestamp == ast->frame_offset) {
                    if (index == st->nb_index_entries-1) {
1479 1480
                        int key=1;
                        uint32_t state=-1;
1481
                        if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
1482 1483 1484 1485 1486
                            const uint8_t *ptr = pkt->data, *end = ptr + FFMIN(size, 256);
                            while (ptr < end) {
                                ptr = avpriv_find_start_code(ptr, end, &state);
                                if (state == 0x1B6 && ptr < end) {
                                    key = !(*ptr & 0xC0);
1487 1488
                                    break;
                                }
1489
                            }
1490
                        }
1491
                        if (!key)
1492 1493
                            e->flags &= ~AVINDEX_KEYFRAME;
                    }
Michael Niedermayer's avatar
Michael Niedermayer committed
1494
                    if (e->flags & AVINDEX_KEYFRAME)
1495
                        pkt->flags |= AV_PKT_FLAG_KEY;
Michael Niedermayer's avatar
Michael Niedermayer committed
1496
                }
1497
            } else {
1498
                pkt->flags |= AV_PKT_FLAG_KEY;
1499
            }
1500
            ast->frame_offset += get_duration(ast, pkt->size);
1501
        }
1502
        ast->remaining -= err;
1503 1504 1505
        if (!ast->remaining) {
            avi->stream_index = -1;
            ast->packet_size  = 0;
1506 1507
        }

1508
        if (!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos) {
1509
            av_packet_unref(pkt);
1510 1511 1512 1513
            goto resync;
        }
        ast->seek_pos= 0;

1514
        if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
1515 1516
            int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);

1517
            if (avi->dts_max - dts > 2*AV_TIME_BASE) {
1518 1519
                avi->non_interleaved= 1;
                av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
1520
            }else if (avi->dts_max < dts)
1521 1522 1523
                avi->dts_max = dts;
        }

1524
        return 0;
1525 1526
    }

1527
    if ((err = avi_sync(s, 0)) < 0)
1528 1529
        return err;
    goto resync;
Fabrice Bellard's avatar
Fabrice Bellard committed
1530 1531
}

Diego Biurrun's avatar
Diego Biurrun committed
1532
/* XXX: We make the implicit supposition that the positions are sorted
1533
 * for each stream. */
Fabrice Bellard's avatar
Fabrice Bellard committed
1534 1535
static int avi_read_idx1(AVFormatContext *s, int size)
{
1536
    AVIContext *avi = s->priv_data;
1537
    AVIOContext *pb = s->pb;
Fabrice Bellard's avatar
Fabrice Bellard committed
1538 1539 1540
    int nb_index_entries, i;
    AVStream *st;
    AVIStream *ast;
1541 1542 1543
    int64_t pos;
    unsigned int index, tag, flags, len, first_packet = 1;
    int64_t last_pos = -1;
1544
    unsigned last_idx = -1;
1545
    int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
1546
    int anykey = 0;
1547

Fabrice Bellard's avatar
Fabrice Bellard committed
1548 1549
    nb_index_entries = size / 16;
    if (nb_index_entries <= 0)
1550
        return AVERROR_INVALIDDATA;
Fabrice Bellard's avatar
Fabrice Bellard committed
1551

1552
    idx1_pos = avio_tell(pb);
1553 1554
    avio_seek(pb, avi->movi_list + 4, SEEK_SET);
    if (avi_sync(s, 1) == 0)
1555 1556 1557 1558
        first_packet_pos = avio_tell(pb) - 8;
    avi->stream_index = -1;
    avio_seek(pb, idx1_pos, SEEK_SET);

1559
    if (s->nb_streams == 1 && s->streams[0]->codecpar->codec_tag == AV_RL32("MMES")) {
1560 1561 1562 1563
        first_packet_pos = 0;
        data_offset = avi->movi_list;
    }

Diego Biurrun's avatar
Diego Biurrun committed
1564
    /* Read the entries and sort them in each stream component. */
1565
    for (i = 0; i < nb_index_entries; i++) {
1566
        if (avio_feof(pb))
1567 1568
            return -1;

1569
        tag   = avio_rl32(pb);
1570
        flags = avio_rl32(pb);
1571 1572
        pos   = avio_rl32(pb);
        len   = avio_rl32(pb);
1573
        av_log(s, AV_LOG_TRACE, "%d: tag=0x%x flags=0x%x pos=0x%"PRIx64" len=%d/",
1574
                i, tag, flags, pos, len);
1575

1576 1577
        index  = ((tag      & 0xff) - '0') * 10;
        index +=  (tag >> 8 & 0xff) - '0';
Fabrice Bellard's avatar
Fabrice Bellard committed
1578 1579
        if (index >= s->nb_streams)
            continue;
1580
        st  = s->streams[index];
Fabrice Bellard's avatar
Fabrice Bellard committed
1581
        ast = st->priv_data;
1582

1583 1584
        /* Skip 'xxpc' palette change entries in the index until a logic
         * to process these is properly implemented. */
1585 1586 1587
        if ((tag >> 16 & 0xff) == 'p' && (tag >> 24 & 0xff) == 'c')
            continue;

1588
        if (first_packet && first_packet_pos) {
1589 1590
            if (avi->movi_list + 4 != pos || pos + 500 > first_packet_pos)
                data_offset  = first_packet_pos - pos;
1591 1592 1593 1594
            first_packet = 0;
        }
        pos += data_offset;

1595
        av_log(s, AV_LOG_TRACE, "%d cum_len=%"PRId64"\n", len, ast->cum_len);
1596

1597 1598
        // even if we have only a single stream, we should
        // switch to non-interleaved to get correct timestamps
1599 1600
        if (last_pos == pos)
            avi->non_interleaved = 1;
1601
        if (last_idx != pos && len) {
1602 1603
            av_add_index_entry(st, pos, ast->cum_len, len, 0,
                               (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
1604
            last_idx= pos;
1605
        }
1606
        ast->cum_len += get_duration(ast, len);
1607
        last_pos      = pos;
1608
        anykey       |= flags&AVIIF_INDEX;
1609 1610 1611 1612 1613 1614 1615
    }
    if (!anykey) {
        for (index = 0; index < s->nb_streams; index++) {
            st = s->streams[index];
            if (st->nb_index_entries)
                st->index_entries[0].flags |= AVINDEX_KEYFRAME;
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
1616 1617 1618 1619
    }
    return 0;
}

1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662
/* Scan the index and consider any file with streams more than
 * 2 seconds or 64MB apart non-interleaved. */
static int check_stream_max_drift(AVFormatContext *s)
{
    int64_t min_pos, pos;
    int i;
    int *idx = av_mallocz_array(s->nb_streams, sizeof(*idx));
    if (!idx)
        return AVERROR(ENOMEM);
    for (min_pos = pos = 0; min_pos != INT64_MAX; pos = min_pos + 1LU) {
        int64_t max_dts = INT64_MIN / 2;
        int64_t min_dts = INT64_MAX / 2;
        int64_t max_buffer = 0;

        min_pos = INT64_MAX;

        for (i = 0; i < s->nb_streams; i++) {
            AVStream *st = s->streams[i];
            AVIStream *ast = st->priv_data;
            int n = st->nb_index_entries;
            while (idx[i] < n && st->index_entries[idx[i]].pos < pos)
                idx[i]++;
            if (idx[i] < n) {
                int64_t dts;
                dts = av_rescale_q(st->index_entries[idx[i]].timestamp /
                                   FFMAX(ast->sample_size, 1),
                                   st->time_base, AV_TIME_BASE_Q);
                min_dts = FFMIN(min_dts, dts);
                min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos);
            }
        }
        for (i = 0; i < s->nb_streams; i++) {
            AVStream *st = s->streams[i];
            AVIStream *ast = st->priv_data;

            if (idx[i] && min_dts != INT64_MAX / 2) {
                int64_t dts;
                dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp /
                                   FFMAX(ast->sample_size, 1),
                                   st->time_base, AV_TIME_BASE_Q);
                max_dts = FFMAX(max_dts, dts);
                max_buffer = FFMAX(max_buffer,
                                   av_rescale(dts - min_dts,
1663
                                              st->codecpar->bit_rate,
1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676
                                              AV_TIME_BASE));
            }
        }
        if (max_dts - min_dts > 2 * AV_TIME_BASE ||
            max_buffer > 1024 * 1024 * 8 * 8) {
            av_free(idx);
            return 1;
        }
    }
    av_free(idx);
    return 0;
}

1677 1678
static int guess_ni_flag(AVFormatContext *s)
{
1679
    int i;
1680 1681 1682
    int64_t last_start = 0;
    int64_t first_end  = INT64_MAX;
    int64_t oldpos     = avio_tell(s->pb);
1683

1684
    for (i = 0; i < s->nb_streams; i++) {
1685
        AVStream *st = s->streams[i];
1686
        int n        = st->nb_index_entries;
1687
        unsigned int size;
1688

1689
        if (n <= 0)
1690 1691
            continue;

1692 1693
        if (n >= 2) {
            int64_t pos = st->index_entries[0].pos;
1694 1695 1696 1697 1698
            unsigned tag[2];
            avio_seek(s->pb, pos, SEEK_SET);
            tag[0] = avio_r8(s->pb);
            tag[1] = avio_r8(s->pb);
            avio_rl16(s->pb);
1699
            size = avio_rl32(s->pb);
1700
            if (get_stream_idx(tag) == i && pos + size > st->index_entries[1].pos)
1701
                last_start = INT64_MAX;
1702 1703
            if (get_stream_idx(tag) == i && size == st->index_entries[0].size + 8)
                last_start = INT64_MAX;
1704 1705
        }

1706 1707 1708 1709
        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;
1710
    }
1711
    avio_seek(s->pb, oldpos, SEEK_SET);
1712

1713 1714 1715
    if (last_start > first_end)
        return 1;

1716
    return check_stream_max_drift(s);
1717 1718
}

Fabrice Bellard's avatar
Fabrice Bellard committed
1719 1720 1721
static int avi_load_index(AVFormatContext *s)
{
    AVIContext *avi = s->priv_data;
1722
    AVIOContext *pb = s->pb;
Fabrice Bellard's avatar
Fabrice Bellard committed
1723
    uint32_t tag, size;
1724
    int64_t pos = avio_tell(pb);
1725
    int64_t next;
1726
    int ret     = -1;
1727

1728
    if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
1729
        goto the_end; // maybe truncated file
1730
    av_log(s, AV_LOG_TRACE, "movi_end=0x%"PRIx64"\n", avi->movi_end);
1731 1732
    for (;;) {
        tag  = avio_rl32(pb);
1733
        size = avio_rl32(pb);
1734
        if (avio_feof(pb))
1735 1736 1737
            break;
        next = avio_tell(pb) + size + (size & 1);

1738
        av_log(s, AV_LOG_TRACE, "tag=%c%c%c%c size=0x%x\n",
1739 1740 1741 1742 1743
                 tag        & 0xff,
                (tag >>  8) & 0xff,
                (tag >> 16) & 0xff,
                (tag >> 24) & 0xff,
                size);
1744 1745 1746

        if (tag == MKTAG('i', 'd', 'x', '1') &&
            avi_read_idx1(s, size) >= 0) {
1747
            avi->index_loaded=2;
1748
            ret = 0;
1749
        }else if (tag == MKTAG('L', 'I', 'S', 'T')) {
1750 1751 1752 1753
            uint32_t tag1 = avio_rl32(pb);

            if (tag1 == MKTAG('I', 'N', 'F', 'O'))
                ff_read_riff_info(s, size - 4);
1754
        }else if (!ret)
Fabrice Bellard's avatar
Fabrice Bellard committed
1755
            break;
1756

1757
        if (avio_seek(pb, next, SEEK_SET) < 0)
1758
            break; // something is wrong here
Fabrice Bellard's avatar
Fabrice Bellard committed
1759
    }
1760 1761

the_end:
1762
    avio_seek(pb, pos, SEEK_SET);
1763
    return ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
1764 1765
}

1766 1767 1768
static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
{
    AVIStream *ast2 = st2->priv_data;
1769
    int64_t ts2     = av_rescale_q(timestamp, st->time_base, st2->time_base);
1770
    av_packet_unref(&ast2->sub_pkt);
1771 1772
    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)
1773
        ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
1774 1775
}

1776 1777
static int avi_read_seek(AVFormatContext *s, int stream_index,
                         int64_t timestamp, int flags)
Fabrice Bellard's avatar
Fabrice Bellard committed
1778 1779 1780
{
    AVIContext *avi = s->priv_data;
    AVStream *st;
1781
    int i, index;
1782
    int64_t pos, pos_min;
1783
    AVIStream *ast;
Fabrice Bellard's avatar
Fabrice Bellard committed
1784

1785 1786 1787 1788 1789 1790
    /* Does not matter which stream is requested dv in avi has the
     * stream information in the first video stream.
     */
    if (avi->dv_demux)
        stream_index = 0;

Fabrice Bellard's avatar
Fabrice Bellard committed
1791 1792 1793
    if (!avi->index_loaded) {
        /* we only load the index on demand */
        avi_load_index(s);
1794
        avi->index_loaded |= 1;
Fabrice Bellard's avatar
Fabrice Bellard committed
1795
    }
1796
    av_assert0(stream_index >= 0);
1797 1798 1799 1800 1801 1802

    st    = s->streams[stream_index];
    ast   = st->priv_data;
    index = av_index_search_timestamp(st,
                                      timestamp * FFMAX(ast->sample_size, 1),
                                      flags);
1803
    if (index < 0) {
1804
        if (st->nb_index_entries > 0)
1805
            av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
1806 1807 1808
                   timestamp * FFMAX(ast->sample_size, 1),
                   st->index_entries[0].timestamp,
                   st->index_entries[st->nb_index_entries - 1].timestamp);
1809
        return AVERROR_INVALIDDATA;
1810
    }
1811

Fabrice Bellard's avatar
Fabrice Bellard committed
1812
    /* find the position */
1813
    pos       = st->index_entries[index].pos;
1814
    timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
1815

1816
    av_log(s, AV_LOG_TRACE, "XX %"PRId64" %d %"PRId64"\n",
1817
            timestamp, index, st->index_entries[index].timestamp);
Fabrice Bellard's avatar
Fabrice Bellard committed
1818

1819
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1820
        /* One and only one real stream for DV in AVI, and it has video  */
1821
        /* offsets. Calling with other stream indexes should have failed */
1822 1823
        /* the av_index_search_timestamp call above.                     */

1824
        if (avio_seek(s->pb, pos, SEEK_SET) < 0)
1825 1826
            return -1;

1827
        /* Feed the DV video stream version of the timestamp to the */
Diego Biurrun's avatar
Diego Biurrun committed
1828
        /* DV demux so it can synthesize correct timestamps.        */
1829
        ff_dv_offset_reset(avi->dv_demux, timestamp);
1830

1831
        avi->stream_index = -1;
1832 1833 1834
        return 0;
    }

1835
    pos_min = pos;
1836 1837
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st2   = s->streams[i];
1838
        AVIStream *ast2 = st2->priv_data;
1839

1840 1841
        ast2->packet_size =
        ast2->remaining   = 0;
1842

1843 1844 1845 1846 1847
        if (ast2->sub_ctx) {
            seek_subtitle(st, st2, timestamp);
            continue;
        }

1848 1849
        if (st2->nb_index_entries <= 0)
            continue;
1850

1851
//        av_assert1(st2->codecpar->block_align);
1852
        av_assert0(fabs(av_q2d(st2->time_base) - ast2->scale / (double)ast2->rate) < av_q2d(st2->time_base) * 0.00000001);
1853 1854 1855 1856 1857
        index = av_index_search_timestamp(st2,
                                          av_rescale_q(timestamp,
                                                       st->time_base,
                                                       st2->time_base) *
                                          FFMAX(ast2->sample_size, 1),
1858 1859
                                          flags |
                                          AVSEEK_FLAG_BACKWARD |
1860
                                          (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
1861 1862
        if (index < 0)
            index = 0;
1863 1864
        ast2->seek_pos = st2->index_entries[index].pos;
        pos_min = FFMIN(pos_min,ast2->seek_pos);
1865
    }
1866
    for (i = 0; i < s->nb_streams; i++) {
1867 1868 1869 1870 1871 1872 1873 1874 1875
        AVStream *st2 = s->streams[i];
        AVIStream *ast2 = st2->priv_data;

        if (ast2->sub_ctx || st2->nb_index_entries <= 0)
            continue;

        index = av_index_search_timestamp(
                st2,
                av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
1876
                flags | AVSEEK_FLAG_BACKWARD | (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
1877 1878 1879
        if (index < 0)
            index = 0;
        while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
1880
            index--;
1881
        ast2->frame_offset = st2->index_entries[index].timestamp;
Fabrice Bellard's avatar
Fabrice Bellard committed
1882
    }
1883

Fabrice Bellard's avatar
Fabrice Bellard committed
1884
    /* do the seek */
1885 1886
    if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) {
        av_log(s, AV_LOG_ERROR, "Seek failed\n");
1887
        return -1;
1888
    }
1889
    avi->stream_index = -1;
1890
    avi->dts_max      = INT_MIN;
Fabrice Bellard's avatar
Fabrice Bellard committed
1891 1892 1893
    return 0;
}

1894
static int avi_read_close(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
1895
{
Michael Niedermayer's avatar
Michael Niedermayer committed
1896 1897 1898
    int i;
    AVIContext *avi = s->priv_data;

1899 1900
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st   = s->streams[i];
1901
        AVIStream *ast = st->priv_data;
1902
        if (ast) {
1903 1904
            if (ast->sub_ctx) {
                av_freep(&ast->sub_ctx->pb);
1905
                avformat_close_input(&ast->sub_ctx);
1906
            }
1907
            av_freep(&ast->sub_buffer);
1908
            av_packet_unref(&ast->sub_pkt);
1909
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
1910 1911
    }

1912
    av_freep(&avi->dv_demux);
1913

Fabrice Bellard's avatar
Fabrice Bellard committed
1914 1915 1916 1917 1918
    return 0;
}

static int avi_probe(AVProbeData *p)
{
1919 1920
    int i;

Fabrice Bellard's avatar
Fabrice Bellard committed
1921
    /* check file header */
1922
    for (i = 0; avi_headers[i][0]; i++)
1923 1924
        if (AV_RL32(p->buf    ) == AV_RL32(avi_headers[i]    ) &&
            AV_RL32(p->buf + 8) == AV_RL32(avi_headers[i] + 4))
1925 1926 1927
            return AVPROBE_SCORE_MAX;

    return 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
1928 1929
}

1930
AVInputFormat ff_avi_demuxer = {
1931
    .name           = "avi",
1932
    .long_name      = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
1933
    .priv_data_size = sizeof(AVIContext),
1934
    .extensions     = "avi",
1935 1936 1937 1938 1939
    .read_probe     = avi_probe,
    .read_header    = avi_read_header,
    .read_packet    = avi_read_packet,
    .read_close     = avi_read_close,
    .read_seek      = avi_read_seek,
1940
    .priv_class = &demuxer_class,
Fabrice Bellard's avatar
Fabrice Bellard committed
1941
};