avidec.c 67.2 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 && !avio_feof(s->pb)) {
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
            uint64_t tag_end = avio_tell(s->pb) + size;
354
            while (avio_tell(s->pb) < tag_end && !avio_feof(s->pb)) {
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 FF_API_LAVF_AVCTX
FF_DISABLE_DEPRECATION_WARNINGS
610
                av_freep(&s->streams[0]->codec);
611 612
FF_ENABLE_DEPRECATION_WARNINGS
#endif
613 614
                if (s->streams[0]->info)
                    av_freep(&s->streams[0]->info->duration_error);
615
                av_freep(&s->streams[0]->info);
616 617 618
                if (s->streams[0]->internal)
                    av_freep(&s->streams[0]->internal->avctx);
                av_freep(&s->streams[0]->internal);
619 620
                av_freep(&s->streams[0]);
                s->nb_streams = 0;
621
                if (CONFIG_DV_DEMUXER) {
622
                    avi->dv_demux = avpriv_dv_init_demux(s);
623 624
                    if (!avi->dv_demux)
                        goto fail;
625 626
                } else
                    goto fail;
627
                s->streams[0]->priv_data = ast;
628
                avio_skip(pb, 3 * 4);
629
                ast->scale = avio_rl32(pb);
630
                ast->rate  = avio_rl32(pb);
631
                avio_skip(pb, 4);  /* start time */
632

633
                dv_dur = avio_rl32(pb);
634
                if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
635
                    dv_dur     *= AV_TIME_BASE;
636 637
                    s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
                }
638 639
                /* else, leave duration alone; timing estimation in utils.c
                 * will make a guess based on bitrate. */
640

641
                stream_index = s->nb_streams - 1;
642
                avio_skip(pb, size - 9 * 4);
643 644
                break;
            }
645

646
            av_assert0(stream_index < s->nb_streams);
647
            ast->handler = handler;
648

649 650 651 652 653
            avio_rl32(pb); /* flags */
            avio_rl16(pb); /* priority */
            avio_rl16(pb); /* language */
            avio_rl32(pb); /* initial frame */
            ast->scale = avio_rl32(pb);
654 655 656
            ast->rate  = avio_rl32(pb);
            if (!(ast->scale && ast->rate)) {
                av_log(s, AV_LOG_WARNING,
657
                       "scale/rate is %"PRIu32"/%"PRIu32" which is invalid. "
658 659 660 661 662
                       "(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
663
                    ast->scale = frame_period;
664 665
                } else {
                    ast->rate  = 25;
Michael Niedermayer's avatar
Michael Niedermayer committed
666 667
                    ast->scale = 1;
                }
668
            }
669
            avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
670

671
            ast->cum_len  = avio_rl32(pb); /* start */
672
            st->nb_frames = avio_rl32(pb);
673

674
            st->start_time = 0;
675 676
            avio_rl32(pb); /* buffer size */
            avio_rl32(pb); /* quality */
677 678
            if (ast->cum_len*ast->scale/ast->rate > 3600) {
                av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");
679
                ast->cum_len = 0;
680
            }
681
            ast->sample_size = avio_rl32(pb);
682
            ast->cum_len    *= FFMAX(1, ast->sample_size);
683
            av_log(s, AV_LOG_TRACE, "%"PRIu32" %"PRIu32" %d\n",
684
                    ast->rate, ast->scale, ast->sample_size);
685

686
            switch (tag1) {
687
            case MKTAG('v', 'i', 'd', 's'):
688
                codec_type = AVMEDIA_TYPE_VIDEO;
689

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

            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;
            }

722
            if (ast->sample_size == 0) {
723
                st->duration = st->nb_frames;
724 725 726 727 728
                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);
                }
            }
729
            ast->frame_offset = ast->cum_len;
730
            avio_skip(pb, size - 12 * 4);
Fabrice Bellard's avatar
Fabrice Bellard committed
731 732 733
            break;
        case MKTAG('s', 't', 'r', 'f'):
            /* stream header */
734 735
            if (!size)
                break;
736
            if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
737
                avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
738
            } else {
739
                uint64_t cur_pos = avio_tell(pb);
740
                unsigned esize;
741 742
                if (cur_pos < list_end)
                    size = FFMIN(size, list_end - cur_pos);
Fabrice Bellard's avatar
Fabrice Bellard committed
743
                st = s->streams[stream_index];
744
                if (st->codecpar->codec_type != AVMEDIA_TYPE_UNKNOWN) {
745 746 747
                    avio_skip(pb, size);
                    break;
                }
748
                switch (codec_type) {
749
                case AVMEDIA_TYPE_VIDEO:
750
                    if (amv_file_format) {
751 752 753 754
                        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;
755
                        avio_skip(pb, size);
756 757
                        break;
                    }
758
                    tag1 = ff_get_bmp_header(pb, st, &esize);
759

760 761
                    if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
                        tag1 == MKTAG('D', 'X', 'S', 'A')) {
762 763 764
                        st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
                        st->codecpar->codec_tag  = tag1;
                        st->codecpar->codec_id   = AV_CODEC_ID_XSUB;
765 766 767
                        break;
                    }

768 769
                    if (size > 10 * 4 && size < (1 << 30) && size < avi->fsize) {
                        if (esize == size-1 && (esize&1)) {
770
                            st->codecpar->extradata_size = esize - 10 * 4;
771
                        } else
772
                            st->codecpar->extradata_size =  size - 10 * 4;
773
                        if (ff_get_extradata(s, st->codecpar, pb, st->codecpar->extradata_size) < 0)
774
                            return AVERROR(ENOMEM);
775
                    }
776

777
                    // FIXME: check if the encoder really did this correctly
778
                    if (st->codecpar->extradata_size & 1)
779
                        avio_r8(pb);
780

781 782 783
                    /* Extract palette from extradata if bpp <= 8.
                     * This code assumes that extradata contains only palette.
                     * This is true for all paletted codecs implemented in
784
                     * FFmpeg. */
785 786 787
                    if (st->codecpar->extradata_size &&
                        (st->codecpar->bits_per_coded_sample <= 8)) {
                        int pal_size = (1 << st->codecpar->bits_per_coded_sample) << 2;
788 789
                        const uint8_t *pal_src;

790 791 792
                        pal_size = FFMIN(pal_size, st->codecpar->extradata_size);
                        pal_src  = st->codecpar->extradata +
                                   st->codecpar->extradata_size - pal_size;
793
                        /* Exclude the "BottomUp" field from the palette */
794 795
                        if (pal_src - st->codecpar->extradata >= 9 &&
                            !memcmp(st->codecpar->extradata + st->codecpar->extradata_size - 9, "BottomUp", 9))
796
                            pal_src -= 9;
797
                        for (i = 0; i < pal_size / 4; i++)
798
                            ast->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i);
799
                        ast->has_pal = 1;
800 801
                    }

Fabrice Bellard's avatar
Fabrice Bellard committed
802
                    print_tag("video", tag1, 0);
803

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

823
                    if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4 &&
824
                        ast->handler == MKTAG('X', 'V', 'I', 'D'))
825
                        st->codecpar->codec_tag = MKTAG('X', 'V', 'I', 'D');
826

827
                    if (st->codecpar->codec_tag == MKTAG('V', 'S', 'S', 'H'))
828
                        st->need_parsing = AVSTREAM_PARSE_FULL;
829
                    if (st->codecpar->codec_id == AV_CODEC_ID_RV40)
830
                        st->need_parsing = AVSTREAM_PARSE_NONE;
831

832 833 834 835 836
                    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 +
837
                                               AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
838
                            st->codecpar->extradata_size = 0;
839
                            return ret;
840
                        } else
841
                            memcpy(st->codecpar->extradata + st->codecpar->extradata_size - 9,
842
                                   "BottomUp", 9);
843
                    }
844
                    st->codecpar->height = FFABS(st->codecpar->height);
845

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

927
                if (size<(1<<30)) {
928
                    if (ff_get_extradata(s, st->codecpar, pb, size) < 0)
929 930 931
                        return AVERROR(ENOMEM);
                }

932
                if (st->codecpar->extradata_size & 1) //FIXME check if the encoder really did this correctly
933
                    avio_r8(pb);
934

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

                st = s->streams[stream_index];
955 956 957 958 959 960
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);

961 962 963 964 965
                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
966

967 968 969
                if (active_aspect.num && active_aspect.den &&
                    active.num && active.den) {
                    st->sample_aspect_ratio = av_div_q(active_aspect, active);
970
                    av_log(s, AV_LOG_TRACE, "vprp %d/%d %d/%d\n",
971 972
                            active_aspect.num, active_aspect.den,
                            active.num, active.den);
973
                }
974
                size -= 9 * 4;
975
            }
976
            avio_skip(pb, size);
977
            break;
978
        case MKTAG('s', 't', 'r', 'n'):
979 980
            if (s->nb_streams) {
                ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
981 982
                if (ret < 0)
                    return ret;
983 984
                break;
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
985
        default:
986
            if (size > 1000000) {
987 988
                char tag_buf[32];
                av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag);
989 990
                av_log(s, AV_LOG_ERROR,
                       "Something went wrong during header parsing, "
991 992 993
                       "tag %s has size %u, "
                       "I will ignore it and try to continue anyway.\n",
                       tag_buf, size);
994 995
                if (s->error_recognition & AV_EF_EXPLODE)
                    goto fail;
996
                avi->movi_list = avio_tell(pb) - 4;
997
                avi->movi_end  = avi->fsize;
998 999
                goto end_of_header;
            }
1000 1001
        /* Do not fail for very large idx1 tags */
        case MKTAG('i', 'd', 'x', '1'):
Fabrice Bellard's avatar
Fabrice Bellard committed
1002 1003
            /* skip tag */
            size += (size & 1);
1004
            avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
1005 1006 1007
            break;
        }
    }
1008 1009

end_of_header:
Fabrice Bellard's avatar
Fabrice Bellard committed
1010 1011
    /* check stream number */
    if (stream_index != s->nb_streams - 1) {
1012 1013

fail:
1014
        return AVERROR_INVALIDDATA;
Fabrice Bellard's avatar
Fabrice Bellard committed
1015
    }
1016

1017
    if (!avi->index_loaded && pb->seekable)
1018
        avi_load_index(s);
1019
    calculate_bitrate(s);
1020
    avi->index_loaded    |= 1;
1021 1022 1023 1024

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

1025
    avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS);
1026 1027 1028

    dict_entry = av_dict_get(s->metadata, "ISFT", NULL, 0);
    if (dict_entry && !strcmp(dict_entry->value, "PotEncoder"))
1029
        for (i = 0; i < s->nb_streams; i++) {
1030
            AVStream *st = s->streams[i];
1031 1032
            if (   st->codecpar->codec_id == AV_CODEC_ID_MPEG1VIDEO
                || st->codecpar->codec_id == AV_CODEC_ID_MPEG2VIDEO)
1033 1034 1035
                st->need_parsing = AVSTREAM_PARSE_FULL;
        }

1036
    for (i = 0; i < s->nb_streams; i++) {
1037
        AVStream *st = s->streams[i];
1038
        if (st->nb_index_entries)
1039 1040
            break;
    }
1041 1042
    // DV-in-AVI cannot be non-interleaved, if set this must be
    // a mis-detection.
1043 1044
    if (avi->dv_demux)
        avi->non_interleaved = 0;
1045 1046 1047 1048
    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;
1049 1050
    }

1051
    if (avi->non_interleaved) {
Diego Biurrun's avatar
Diego Biurrun committed
1052
        av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
1053
        clean_index(s);
1054
    }
1055

1056 1057
    ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);
    ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
1058

Fabrice Bellard's avatar
Fabrice Bellard committed
1059 1060 1061
    return 0;
}

1062
static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt)
1063
{
1064
    if (pkt->size >= 7 &&
1065
        pkt->size < INT_MAX - AVPROBE_PADDING_SIZE &&
1066
        !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
1067
        uint8_t desc[256];
1068
        int score      = AVPROBE_SCORE_EXTENSION, ret;
1069 1070 1071
        AVIStream *ast = st->priv_data;
        AVInputFormat *sub_demuxer;
        AVRational time_base;
1072
        int size;
1073 1074 1075
        AVIOContext *pb = avio_alloc_context(pkt->data + 7,
                                             pkt->size - 7,
                                             0, NULL, NULL, NULL, NULL);
1076
        AVProbeData pd;
1077
        unsigned int desc_len = avio_rl32(pb);
1078

1079 1080
        if (desc_len > pb->buf_end - pb->buf_ptr)
            goto error;
1081

1082
        ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
1083
        avio_skip(pb, desc_len - ret);
1084
        if (*desc)
1085
            av_dict_set(&st->metadata, "title", desc, 0);
1086

1087 1088
        avio_rl16(pb);   /* flags? */
        avio_rl32(pb);   /* data size */
1089

1090 1091 1092 1093 1094 1095 1096 1097 1098
        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)
1099
            goto error;
1100

1101 1102 1103
        if (!(ast->sub_ctx = avformat_alloc_context()))
            goto error;

1104
        ast->sub_ctx->pb = pb;
1105

1106
        if (ff_copy_whiteblacklists(ast->sub_ctx, s) < 0)
1107
            goto error;
1108

1109
        if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
1110 1111
            if (ast->sub_ctx->nb_streams != 1)
                goto error;
1112
            ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
1113
            avcodec_parameters_copy(st->codecpar, ast->sub_ctx->streams[0]->codecpar);
1114
            time_base = ast->sub_ctx->streams[0]->time_base;
1115
            avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
1116 1117 1118 1119
        }
        ast->sub_buffer = pkt->data;
        memset(pkt, 0, sizeof(*pkt));
        return 1;
1120

1121
error:
1122
        av_freep(&ast->sub_ctx);
1123
        av_freep(&pb);
1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138
    }
    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);

1139
    for (i = 0; i < s->nb_streams; i++) {
1140 1141
        st  = s->streams[i];
        ast = st->priv_data;
1142
        if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
1143 1144 1145 1146 1147 1148 1149 1150 1151
            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) {
1152 1153
        ast               = sub_st->priv_data;
        *pkt              = ast->sub_pkt;
1154
        pkt->stream_index = sub_st->index;
1155

1156
        if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
1157 1158 1159 1160 1161
            ast->sub_pkt.data = NULL;
    }
    return sub_st;
}

1162
static int get_stream_idx(const unsigned *d)
1163 1164 1165
{
    if (d[0] >= '0' && d[0] <= '9' &&
        d[1] >= '0' && d[1] <= '9') {
1166
        return (d[0] - '0') * 10 + (d[1] - '0');
1167 1168
    } else {
        return 100; // invalid stream ID
1169 1170 1171
    }
}

1172 1173 1174 1175
/**
 *
 * @param exit_early set to 1 to just gather packet position without making the changes needed to actually read & return the packet
 */
1176
static int avi_sync(AVFormatContext *s, int exit_early)
Fabrice Bellard's avatar
Fabrice Bellard committed
1177 1178
{
    AVIContext *avi = s->priv_data;
1179
    AVIOContext *pb = s->pb;
1180 1181
    int n;
    unsigned int d[8];
1182
    unsigned int size;
1183
    int64_t i, sync;
1184 1185

start_sync:
1186
    memset(d, -1, sizeof(d));
1187
    for (i = sync = avio_tell(pb); !avio_feof(pb); i++) {
1188 1189
        int j;

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

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

1196
        n = get_stream_idx(d + 2);
1197
        ff_tlog(s, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
1198
                d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
1199
        if (i*(avi->io_fsize>0) + (uint64_t)size > avi->fsize || d[0] > 127)
1200 1201
            continue;

1202 1203 1204 1205 1206
        // 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')) {
1207 1208 1209 1210
            avio_skip(pb, size);
            goto start_sync;
        }

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

1217
        n = get_stream_idx(d);
1218

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

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

1229 1230 1231
        if (avi->dv_demux && n != 0)
            continue;

1232 1233
        // parse ##dc/##wb
        if (n < s->nb_streams) {
1234 1235
            AVStream *st;
            AVIStream *ast;
1236
            st  = s->streams[n];
1237 1238
            ast = st->priv_data;

1239
            if (!ast) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1240
                av_log(s, AV_LOG_WARNING, "Skipping foreign stream %d packet\n", n);
1241 1242 1243
                continue;
            }

1244 1245 1246 1247
            if (s->nb_streams >= 2) {
                AVStream *st1   = s->streams[1];
                AVIStream *ast1 = st1->priv_data;
                // workaround for broken small-file-bug402.avi
1248 1249
                if (   d[2] == 'w' && d[3] == 'b'
                   && n == 0
1250 1251
                   && st ->codecpar->codec_type == AVMEDIA_TYPE_VIDEO
                   && st1->codecpar->codec_type == AVMEDIA_TYPE_AUDIO
1252 1253
                   && ast->prefix == 'd'*256+'c'
                   && (d[2]*256+d[3] == ast1->prefix || !ast1->prefix_count)
1254
                  ) {
1255 1256
                    n   = 1;
                    st  = st1;
1257
                    ast = ast1;
1258 1259
                    av_log(s, AV_LOG_WARNING,
                           "Invalid stream + prefix combination, assuming audio.\n");
1260 1261 1262
                }
            }

1263 1264 1265 1266 1267 1268
            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)) {
1269 1270
                if (!exit_early) {
                    ast->frame_offset += get_duration(ast, size);
1271 1272
                    avio_skip(pb, size);
                    goto start_sync;
1273
                }
1274 1275
            }

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

1280
                avio_rl16(pb); // flags
1281

1282
                // b + (g << 8) + (r << 16);
1283
                for (; k <= last; k++)
1284
                    ast->pal[k] = 0xFFU<<24 | avio_rb32(pb)>>8;
1285

1286 1287 1288 1289 1290 1291 1292
                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') */) {
1293 1294
                if (exit_early)
                    return 0;
1295
                if (d[2] * 256 + d[3] == ast->prefix)
1296
                    ast->prefix_count++;
1297 1298 1299
                else {
                    ast->prefix       = d[2] * 256 + d[3];
                    ast->prefix_count = 0;
1300 1301
                }

1302 1303 1304
                avi->stream_index = n;
                ast->packet_size  = size + 8;
                ast->remaining    = size;
1305

1306
                if (size) {
1307 1308 1309 1310 1311
                    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);
1312 1313 1314 1315 1316 1317 1318
                    }
                }
                return 0;
            }
        }
    }

1319
    if (pb->error)
1320
        return pb->error;
1321 1322 1323
    return AVERROR_EOF;
}

1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361
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;
1362
    best_ts  = best_ast->frame_offset;
1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376
    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;
1377 1378
        if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
          return AVERROR_EOF;
1379

1380
        av_assert0(best_ast->remaining <= best_ast->packet_size);
1381 1382 1383 1384 1385 1386

        avi->stream_index = best_stream_index;
        if (!best_ast->remaining)
            best_ast->packet_size =
            best_ast->remaining   = best_st->index_entries[i].size;
    }
1387 1388
    else
        return AVERROR_EOF;
1389 1390 1391 1392

    return 0;
}

1393 1394 1395 1396 1397
static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIContext *avi = s->priv_data;
    AVIOContext *pb = s->pb;
    int err;
1398

1399
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1400
        int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
1401 1402
        if (size >= 0)
            return size;
1403 1404
        else
            goto resync;
1405
    }
1406

1407
    if (avi->non_interleaved) {
1408 1409 1410
        err = ni_prepare_read(s);
        if (err < 0)
            return err;
1411
    }
1412

1413
resync:
1414 1415 1416
    if (avi->stream_index >= 0) {
        AVStream *st   = s->streams[avi->stream_index];
        AVIStream *ast = st->priv_data;
1417
        int size, err;
1418

1419
        if (get_subtitle_pkt(s, st, pkt))
1420 1421
            return 0;

1422 1423 1424 1425
        // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
        if (ast->sample_size <= 1)
            size = INT_MAX;
        else if (ast->sample_size < 32)
1426
            // arbitrary multiplier to avoid tiny packets for raw PCM data
1427
            size = 1024 * ast->sample_size;
1428
        else
1429
            size = ast->sample_size;
1430

1431 1432 1433 1434 1435
        if (size > ast->remaining)
            size = ast->remaining;
        avi->last_pkt_pos = avio_tell(pb);
        err               = av_get_packet(pb, pkt, size);
        if (err < 0)
1436
            return err;
1437
        size = err;
1438

1439
        if (ast->has_pal && pkt->size < (unsigned)INT_MAX / 2) {
1440
            uint8_t *pal;
1441 1442 1443 1444 1445 1446 1447
            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 {
1448 1449 1450
                memcpy(pal, ast->pal, AVPALETTE_SIZE);
                ast->has_pal = 0;
            }
1451 1452
        }

1453
        if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1454
            AVBufferRef *avbuf = pkt->buf;
1455
            size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
1456
                                            pkt->data, pkt->size, pkt->pos);
1457
            pkt->buf    = avbuf;
1458
            pkt->flags |= AV_PKT_FLAG_KEY;
1459
            if (size < 0)
1460
                av_packet_unref(pkt);
1461
        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
1462
                   !st->codecpar->codec_tag && read_gab2_sub(s, st, pkt)) {
1463 1464
            ast->frame_offset++;
            avi->stream_index = -1;
1465
            ast->remaining    = 0;
1466
            goto resync;
1467
        } else {
Diego Biurrun's avatar
Diego Biurrun committed
1468
            /* XXX: How to handle B-frames in AVI? */
1469 1470
            pkt->dts = ast->frame_offset;
//                pkt->dts += ast->start;
1471
            if (ast->sample_size)
1472
                pkt->dts /= ast->sample_size;
1473
            av_log(s, AV_LOG_TRACE,
1474 1475 1476 1477 1478 1479 1480 1481 1482 1483
                    "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);
1484 1485
            pkt->stream_index = avi->stream_index;

1486
            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1487 1488
                AVIndexEntry *e;
                int index;
1489

1490
                index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY);
1491
                e     = &st->index_entries[index];
1492

1493 1494
                if (index >= 0 && e->timestamp == ast->frame_offset) {
                    if (index == st->nb_index_entries-1) {
1495 1496
                        int key=1;
                        uint32_t state=-1;
1497
                        if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4) {
1498 1499 1500 1501 1502
                            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);
1503 1504
                                    break;
                                }
1505
                            }
1506
                        }
1507
                        if (!key)
1508 1509
                            e->flags &= ~AVINDEX_KEYFRAME;
                    }
Michael Niedermayer's avatar
Michael Niedermayer committed
1510
                    if (e->flags & AVINDEX_KEYFRAME)
1511
                        pkt->flags |= AV_PKT_FLAG_KEY;
Michael Niedermayer's avatar
Michael Niedermayer committed
1512
                }
1513
            } else {
1514
                pkt->flags |= AV_PKT_FLAG_KEY;
1515
            }
1516
            ast->frame_offset += get_duration(ast, pkt->size);
1517
        }
1518
        ast->remaining -= err;
1519 1520 1521
        if (!ast->remaining) {
            avi->stream_index = -1;
            ast->packet_size  = 0;
1522 1523
        }

1524
        if (!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos) {
1525
            av_packet_unref(pkt);
1526 1527 1528 1529
            goto resync;
        }
        ast->seek_pos= 0;

1530
        if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) {
1531 1532
            int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);

1533
            if (avi->dts_max - dts > 2*AV_TIME_BASE) {
1534 1535
                avi->non_interleaved= 1;
                av_log(s, AV_LOG_INFO, "Switching to NI mode, due to poor interleaving\n");
1536
            }else if (avi->dts_max < dts)
1537 1538 1539
                avi->dts_max = dts;
        }

1540
        return 0;
1541 1542
    }

1543
    if ((err = avi_sync(s, 0)) < 0)
1544 1545
        return err;
    goto resync;
Fabrice Bellard's avatar
Fabrice Bellard committed
1546 1547
}

Diego Biurrun's avatar
Diego Biurrun committed
1548
/* XXX: We make the implicit supposition that the positions are sorted
1549
 * for each stream. */
Fabrice Bellard's avatar
Fabrice Bellard committed
1550 1551
static int avi_read_idx1(AVFormatContext *s, int size)
{
1552
    AVIContext *avi = s->priv_data;
1553
    AVIOContext *pb = s->pb;
Fabrice Bellard's avatar
Fabrice Bellard committed
1554 1555 1556
    int nb_index_entries, i;
    AVStream *st;
    AVIStream *ast;
1557 1558 1559
    int64_t pos;
    unsigned int index, tag, flags, len, first_packet = 1;
    int64_t last_pos = -1;
1560
    unsigned last_idx = -1;
1561
    int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
1562
    int anykey = 0;
1563

Fabrice Bellard's avatar
Fabrice Bellard committed
1564 1565
    nb_index_entries = size / 16;
    if (nb_index_entries <= 0)
1566
        return AVERROR_INVALIDDATA;
Fabrice Bellard's avatar
Fabrice Bellard committed
1567

1568
    idx1_pos = avio_tell(pb);
1569 1570
    avio_seek(pb, avi->movi_list + 4, SEEK_SET);
    if (avi_sync(s, 1) == 0)
1571 1572 1573 1574
        first_packet_pos = avio_tell(pb) - 8;
    avi->stream_index = -1;
    avio_seek(pb, idx1_pos, SEEK_SET);

1575
    if (s->nb_streams == 1 && s->streams[0]->codecpar->codec_tag == AV_RL32("MMES")) {
1576 1577 1578 1579
        first_packet_pos = 0;
        data_offset = avi->movi_list;
    }

Diego Biurrun's avatar
Diego Biurrun committed
1580
    /* Read the entries and sort them in each stream component. */
1581
    for (i = 0; i < nb_index_entries; i++) {
1582
        if (avio_feof(pb))
1583 1584
            return -1;

1585
        tag   = avio_rl32(pb);
1586
        flags = avio_rl32(pb);
1587 1588
        pos   = avio_rl32(pb);
        len   = avio_rl32(pb);
1589
        av_log(s, AV_LOG_TRACE, "%d: tag=0x%x flags=0x%x pos=0x%"PRIx64" len=%d/",
1590
                i, tag, flags, pos, len);
1591

1592 1593
        index  = ((tag      & 0xff) - '0') * 10;
        index +=  (tag >> 8 & 0xff) - '0';
Fabrice Bellard's avatar
Fabrice Bellard committed
1594 1595
        if (index >= s->nb_streams)
            continue;
1596
        st  = s->streams[index];
Fabrice Bellard's avatar
Fabrice Bellard committed
1597
        ast = st->priv_data;
1598

1599 1600
        /* Skip 'xxpc' palette change entries in the index until a logic
         * to process these is properly implemented. */
1601 1602 1603
        if ((tag >> 16 & 0xff) == 'p' && (tag >> 24 & 0xff) == 'c')
            continue;

1604
        if (first_packet && first_packet_pos) {
1605 1606
            if (avi->movi_list + 4 != pos || pos + 500 > first_packet_pos)
                data_offset  = first_packet_pos - pos;
1607 1608 1609 1610
            first_packet = 0;
        }
        pos += data_offset;

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

1613 1614
        // even if we have only a single stream, we should
        // switch to non-interleaved to get correct timestamps
1615 1616
        if (last_pos == pos)
            avi->non_interleaved = 1;
1617
        if (last_idx != pos && len) {
1618 1619
            av_add_index_entry(st, pos, ast->cum_len, len, 0,
                               (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
1620
            last_idx= pos;
1621
        }
1622
        ast->cum_len += get_duration(ast, len);
1623
        last_pos      = pos;
1624
        anykey       |= flags&AVIIF_INDEX;
1625 1626 1627 1628 1629 1630 1631
    }
    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
1632 1633 1634 1635
    }
    return 0;
}

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 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678
/* 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,
1679
                                              st->codecpar->bit_rate,
1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692
                                              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;
}

1693 1694
static int guess_ni_flag(AVFormatContext *s)
{
1695
    int i;
1696 1697 1698
    int64_t last_start = 0;
    int64_t first_end  = INT64_MAX;
    int64_t oldpos     = avio_tell(s->pb);
1699

1700
    for (i = 0; i < s->nb_streams; i++) {
1701
        AVStream *st = s->streams[i];
1702
        int n        = st->nb_index_entries;
1703
        unsigned int size;
1704

1705
        if (n <= 0)
1706 1707
            continue;

1708 1709
        if (n >= 2) {
            int64_t pos = st->index_entries[0].pos;
1710 1711 1712 1713 1714
            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);
1715
            size = avio_rl32(s->pb);
1716
            if (get_stream_idx(tag) == i && pos + size > st->index_entries[1].pos)
1717
                last_start = INT64_MAX;
1718 1719
            if (get_stream_idx(tag) == i && size == st->index_entries[0].size + 8)
                last_start = INT64_MAX;
1720 1721
        }

1722 1723 1724 1725
        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;
1726
    }
1727
    avio_seek(s->pb, oldpos, SEEK_SET);
1728

1729 1730 1731
    if (last_start > first_end)
        return 1;

1732
    return check_stream_max_drift(s);
1733 1734
}

Fabrice Bellard's avatar
Fabrice Bellard committed
1735 1736 1737
static int avi_load_index(AVFormatContext *s)
{
    AVIContext *avi = s->priv_data;
1738
    AVIOContext *pb = s->pb;
Fabrice Bellard's avatar
Fabrice Bellard committed
1739
    uint32_t tag, size;
1740
    int64_t pos = avio_tell(pb);
1741
    int64_t next;
1742
    int ret     = -1;
1743

1744
    if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
1745
        goto the_end; // maybe truncated file
1746
    av_log(s, AV_LOG_TRACE, "movi_end=0x%"PRIx64"\n", avi->movi_end);
1747 1748
    for (;;) {
        tag  = avio_rl32(pb);
1749
        size = avio_rl32(pb);
1750
        if (avio_feof(pb))
1751 1752 1753
            break;
        next = avio_tell(pb) + size + (size & 1);

1754
        av_log(s, AV_LOG_TRACE, "tag=%c%c%c%c size=0x%x\n",
1755 1756 1757 1758 1759
                 tag        & 0xff,
                (tag >>  8) & 0xff,
                (tag >> 16) & 0xff,
                (tag >> 24) & 0xff,
                size);
1760 1761 1762

        if (tag == MKTAG('i', 'd', 'x', '1') &&
            avi_read_idx1(s, size) >= 0) {
1763
            avi->index_loaded=2;
1764
            ret = 0;
1765
        }else if (tag == MKTAG('L', 'I', 'S', 'T')) {
1766 1767 1768 1769
            uint32_t tag1 = avio_rl32(pb);

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

1773
        if (avio_seek(pb, next, SEEK_SET) < 0)
1774
            break; // something is wrong here
Fabrice Bellard's avatar
Fabrice Bellard committed
1775
    }
1776 1777

the_end:
1778
    avio_seek(pb, pos, SEEK_SET);
1779
    return ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
1780 1781
}

1782 1783 1784
static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
{
    AVIStream *ast2 = st2->priv_data;
1785
    int64_t ts2     = av_rescale_q(timestamp, st->time_base, st2->time_base);
1786
    av_packet_unref(&ast2->sub_pkt);
1787 1788
    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)
1789
        ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
1790 1791
}

1792 1793
static int avi_read_seek(AVFormatContext *s, int stream_index,
                         int64_t timestamp, int flags)
Fabrice Bellard's avatar
Fabrice Bellard committed
1794 1795 1796
{
    AVIContext *avi = s->priv_data;
    AVStream *st;
1797
    int i, index;
1798
    int64_t pos, pos_min;
1799
    AVIStream *ast;
Fabrice Bellard's avatar
Fabrice Bellard committed
1800

1801 1802 1803 1804 1805 1806
    /* 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
1807 1808 1809
    if (!avi->index_loaded) {
        /* we only load the index on demand */
        avi_load_index(s);
1810
        avi->index_loaded |= 1;
Fabrice Bellard's avatar
Fabrice Bellard committed
1811
    }
1812
    av_assert0(stream_index >= 0);
1813 1814 1815 1816 1817 1818

    st    = s->streams[stream_index];
    ast   = st->priv_data;
    index = av_index_search_timestamp(st,
                                      timestamp * FFMAX(ast->sample_size, 1),
                                      flags);
1819
    if (index < 0) {
1820
        if (st->nb_index_entries > 0)
1821
            av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
1822 1823 1824
                   timestamp * FFMAX(ast->sample_size, 1),
                   st->index_entries[0].timestamp,
                   st->index_entries[st->nb_index_entries - 1].timestamp);
1825
        return AVERROR_INVALIDDATA;
1826
    }
1827

Fabrice Bellard's avatar
Fabrice Bellard committed
1828
    /* find the position */
1829
    pos       = st->index_entries[index].pos;
1830
    timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
1831

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

1835
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1836
        /* One and only one real stream for DV in AVI, and it has video  */
1837
        /* offsets. Calling with other stream indexes should have failed */
1838 1839
        /* the av_index_search_timestamp call above.                     */

1840
        if (avio_seek(s->pb, pos, SEEK_SET) < 0)
1841 1842
            return -1;

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

1847
        avi->stream_index = -1;
1848 1849 1850
        return 0;
    }

1851
    pos_min = pos;
1852 1853
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st2   = s->streams[i];
1854
        AVIStream *ast2 = st2->priv_data;
1855

1856 1857
        ast2->packet_size =
        ast2->remaining   = 0;
1858

1859 1860 1861 1862 1863
        if (ast2->sub_ctx) {
            seek_subtitle(st, st2, timestamp);
            continue;
        }

1864 1865
        if (st2->nb_index_entries <= 0)
            continue;
1866

1867
//        av_assert1(st2->codecpar->block_align);
1868 1869 1870 1871 1872
        index = av_index_search_timestamp(st2,
                                          av_rescale_q(timestamp,
                                                       st->time_base,
                                                       st2->time_base) *
                                          FFMAX(ast2->sample_size, 1),
1873 1874
                                          flags |
                                          AVSEEK_FLAG_BACKWARD |
1875
                                          (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
1876 1877
        if (index < 0)
            index = 0;
1878 1879
        ast2->seek_pos = st2->index_entries[index].pos;
        pos_min = FFMIN(pos_min,ast2->seek_pos);
1880
    }
1881
    for (i = 0; i < s->nb_streams; i++) {
1882 1883 1884 1885 1886 1887 1888 1889 1890
        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),
1891
                flags | AVSEEK_FLAG_BACKWARD | (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
1892 1893 1894
        if (index < 0)
            index = 0;
        while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
1895
            index--;
1896
        ast2->frame_offset = st2->index_entries[index].timestamp;
Fabrice Bellard's avatar
Fabrice Bellard committed
1897
    }
1898

Fabrice Bellard's avatar
Fabrice Bellard committed
1899
    /* do the seek */
1900 1901
    if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) {
        av_log(s, AV_LOG_ERROR, "Seek failed\n");
1902
        return -1;
1903
    }
1904
    avi->stream_index = -1;
1905
    avi->dts_max      = INT_MIN;
Fabrice Bellard's avatar
Fabrice Bellard committed
1906 1907 1908
    return 0;
}

1909
static int avi_read_close(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
1910
{
Michael Niedermayer's avatar
Michael Niedermayer committed
1911 1912 1913
    int i;
    AVIContext *avi = s->priv_data;

1914 1915
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st   = s->streams[i];
1916
        AVIStream *ast = st->priv_data;
1917
        if (ast) {
1918 1919
            if (ast->sub_ctx) {
                av_freep(&ast->sub_ctx->pb);
1920
                avformat_close_input(&ast->sub_ctx);
1921
            }
1922
            av_freep(&ast->sub_buffer);
1923
            av_packet_unref(&ast->sub_pkt);
1924
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
1925 1926
    }

1927
    av_freep(&avi->dv_demux);
1928

Fabrice Bellard's avatar
Fabrice Bellard committed
1929 1930 1931 1932 1933
    return 0;
}

static int avi_probe(AVProbeData *p)
{
1934 1935
    int i;

Fabrice Bellard's avatar
Fabrice Bellard committed
1936
    /* check file header */
1937
    for (i = 0; avi_headers[i][0]; i++)
1938 1939
        if (AV_RL32(p->buf    ) == AV_RL32(avi_headers[i]    ) &&
            AV_RL32(p->buf + 8) == AV_RL32(avi_headers[i] + 4))
1940 1941 1942
            return AVPROBE_SCORE_MAX;

    return 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
1943 1944
}

1945
AVInputFormat ff_avi_demuxer = {
1946
    .name           = "avi",
1947
    .long_name      = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
1948
    .priv_data_size = sizeof(AVIContext),
1949
    .extensions     = "avi",
1950 1951 1952 1953 1954
    .read_probe     = avi_probe,
    .read_header    = avi_read_header,
    .read_packet    = avi_read_packet,
    .read_close     = avi_read_close,
    .read_seek      = avi_read_seek,
1955
    .priv_class = &demuxer_class,
Fabrice Bellard's avatar
Fabrice Bellard committed
1956
};