avidec.c 54.3 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
 * This file is part of Libav.
6
 *
7
 * Libav 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
 * Libav 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 Libav; 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/avstring.h"
25
#include "libavutil/bswap.h"
26
#include "libavutil/dict.h"
27
#include "libavutil/internal.h"
28 29
#include "libavutil/intreadwrite.h"
#include "libavutil/mathematics.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
30 31
#include "avformat.h"
#include "avi.h"
32
#include "dv.h"
33
#include "internal.h"
34
#include "isom.h"
35
#include "riff.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
36

37 38 39
#undef NDEBUG
#include <assert.h>

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

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

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

    AVFormatContext *sub_ctx;
    AVPacket sub_pkt;
    uint8_t *sub_buffer;
Fabrice Bellard's avatar
Fabrice Bellard committed
63
} AVIStream;
Fabrice Bellard's avatar
Fabrice Bellard committed
64

65
typedef struct AVIContext {
66 67 68
    int64_t riff_end;
    int64_t movi_end;
    int64_t fsize;
69
    int64_t movi_list;
70
    int64_t last_pkt_pos;
Fabrice Bellard's avatar
Fabrice Bellard committed
71
    int index_loaded;
72
    int is_odml;
73 74
    int non_interleaved;
    int stream_index;
75
    DVDemuxContext *dv_demux;
76 77
    int odml_depth;
#define MAX_ODML_DEPTH 1000
Fabrice Bellard's avatar
Fabrice Bellard committed
78 79
} AVIContext;

80
static const char avi_headers[][8] = {
81 82 83 84 85
    { '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', ' '  },
86 87 88
    { 0 }
};

89 90 91 92 93
static const AVMetadataConv avi_metadata_conv[] = {
    { "strn", "title" },
    { 0 },
};

94
static int avi_load_index(AVFormatContext *s);
95
static int guess_ni_flag(AVFormatContext *s);
96

97
#define print_tag(str, tag, size)                        \
98
    av_log(NULL, AV_LOG_TRACE, "%s: tag=%c%c%c%c size=0x%x\n",        \
99 100 101 102 103
            str, tag & 0xff,                             \
            (tag >> 8) & 0xff,                           \
            (tag >> 16) & 0xff,                          \
            (tag >> 24) & 0xff,                          \
            size)
Fabrice Bellard's avatar
Fabrice Bellard committed
104

105 106 107
static inline int get_duration(AVIStream *ast, int len)
{
    if (ast->sample_size)
108
        return len;
109 110 111
    else if (ast->dshow_block_align)
        return (len + ast->dshow_block_align - 1) / ast->dshow_block_align;
    else
112 113 114
        return 1;
}

115
static int get_riff(AVFormatContext *s, AVIOContext *pb)
116
{
117
    AVIContext *avi = s->priv_data;
118 119
    char header[8];
    int i;
120

121
    /* check RIFF header */
122
    avio_read(pb, header, 4);
123
    avi->riff_end  = avio_rl32(pb); /* RIFF chunk size */
124
    avi->riff_end += avio_tell(pb); /* RIFF chunk end */
125
    avio_read(pb, header + 4, 4);
126

127 128
    for (i = 0; avi_headers[i][0]; i++)
        if (!memcmp(header, avi_headers[i], 8))
129
            break;
130
    if (!avi_headers[i][0])
131
        return AVERROR_INVALIDDATA;
132

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

137 138 139
    return 0;
}

140 141 142 143 144 145 146 147 148 149 150 151
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');
152 153 154
    AVStream *st;
    AVIStream *ast;
    int i;
155
    int64_t last_pos = -1;
156
    int64_t filesize = avi->fsize;
157

158
    av_log(s, AV_LOG_TRACE,
159 160 161 162 163 164 165 166 167
            "longs_pre_entry:%d index_type:%d entries_in_use:%d "
            "chunk_id:%X base:%16"PRIX64"\n",
            longs_pre_entry,
            index_type,
            entries_in_use,
            chunk_id,
            base);

    if (stream_id >= s->nb_streams || stream_id < 0)
168
        return AVERROR_INVALIDDATA;
169
    st  = s->streams[stream_id];
170 171
    ast = st->priv_data;

172
    if (index_sub_type)
173
        return AVERROR_INVALIDDATA;
174

175
    avio_rl32(pb);
176

177
    if (index_type && longs_pre_entry != 2)
178
        return AVERROR_INVALIDDATA;
179
    if (index_type > 1)
180
        return AVERROR_INVALIDDATA;
181

182
    if (filesize > 0 && base >= filesize) {
183
        av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
184 185 186
        if (base >> 32 == (base & 0xFFFFFFFF) &&
            (base & 0xFFFFFFFF) < filesize    &&
            filesize <= 0xFFFFFFFF)
187 188
            base &= 0xFFFFFFFF;
        else
189
            return AVERROR_INVALIDDATA;
190 191
    }

192 193 194 195 196
    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;
197 198
            len &= 0x7FFFFFFF;

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

201
            if (pb->eof_reached)
202
                return AVERROR_INVALIDDATA;
203

204 205 206 207 208
            if (last_pos == pos || pos == base - 8)
                avi->non_interleaved = 1;
            if (last_pos != pos && (len || !ast->sample_size))
                av_add_index_entry(st, pos, ast->cum_len, len, 0,
                                   key ? AVINDEX_KEYFRAME : 0);
209

210
            ast->cum_len += get_duration(ast, len);
211 212
            last_pos      = pos;
        } else {
Måns Rullgård's avatar
Måns Rullgård committed
213 214
            int64_t offset, pos;
            int duration;
215 216 217
            offset = avio_rl64(pb);
            avio_rl32(pb);       /* size */
            duration = avio_rl32(pb);
218

219
            if (pb->eof_reached)
220
                return AVERROR_INVALIDDATA;
221

222
            pos = avio_tell(pb);
223

224
            if (avi->odml_depth > MAX_ODML_DEPTH) {
225
                av_log(s, AV_LOG_ERROR, "Too deeply nested ODML indexes\n");
226
                return AVERROR_INVALIDDATA;
227 228
            }

229
            avio_seek(pb, offset + 8, SEEK_SET);
230
            avi->odml_depth++;
231
            read_braindead_odml_indx(s, frame_num);
232
            avi->odml_depth--;
233 234
            frame_num += duration;

235
            avio_seek(pb, pos, SEEK_SET);
236 237
        }
    }
238
    avi->index_loaded = 1;
239 240 241
    return 0;
}

242 243
static void clean_index(AVFormatContext *s)
{
244 245
    int i;
    int64_t j;
246

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

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

257 258
        while (max < 1024)
            max += max;
259

260 261 262
        pos  = st->index_entries[0].pos;
        size = st->index_entries[0].size;
        ts   = st->index_entries[0].timestamp;
263

264 265 266
        for (j = 0; j < size; j += max)
            av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0,
                               AVINDEX_KEYFRAME);
267 268 269
    }
}

270 271
static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag,
                        uint32_t size)
272
{
273
    AVIOContext *pb = s->pb;
274 275
    char key[5]     = { 0 };
    char *value;
276

277
    size += (size & 1);
278

279
    if (size == UINT_MAX)
280
        return AVERROR(EINVAL);
281
    value = av_malloc(size + 1);
282
    if (!value)
283
        return AVERROR(ENOMEM);
284
    avio_read(pb, value, size);
285
    value[size] = 0;
286

287 288
    AV_WL32(key, tag);

289
    return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
290
                       AV_DICT_DONT_STRDUP_VAL);
291 292
}

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

296
static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
297 298 299 300 301
{
    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",
302
               month, &day, time, &year) == 4) {
303
        for (i = 0; i < 12; i++)
304
            if (!av_strcasecmp(month, months[i])) {
305
                snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
306
                         year, i + 1, day, time);
307
                av_dict_set(metadata, "creation_time", buffer, 0);
308
            }
309 310
    } else if (date[4] == '/' && date[7] == '/') {
        date[4] = date[7] = '-';
311
        av_dict_set(metadata, "creation_time", date, 0);
312
    }
313 314
}

315 316
static void avi_read_nikon(AVFormatContext *s, uint64_t end)
{
317
    while (avio_tell(s->pb) < end) {
318 319
        uint32_t tag  = avio_rl32(s->pb);
        uint32_t size = avio_rl32(s->pb);
320
        switch (tag) {
321 322
        case MKTAG('n', 'c', 't', 'g'):  /* Nikon Tags */
        {
323 324
            uint64_t tag_end = avio_tell(s->pb) + size;
            while (avio_tell(s->pb) < tag_end) {
325 326
                uint16_t tag     = avio_rl16(s->pb);
                uint16_t size    = avio_rl16(s->pb);
327
                const char *name = NULL;
328
                char buffer[64]  = { 0 };
329
                size -= avio_read(s->pb, buffer,
330
                                  FFMIN(size, sizeof(buffer) - 1));
331
                switch (tag) {
332 333 334 335 336 337 338 339
                case 0x03:
                    name = "maker";
                    break;
                case 0x04:
                    name = "model";
                    break;
                case 0x13:
                    name = "creation_time";
340 341 342 343 344
                    if (buffer[4] == ':' && buffer[7] == ':')
                        buffer[4] = buffer[7] = '-';
                    break;
                }
                if (name)
345
                    av_dict_set(&s->metadata, name, buffer, 0);
346
                avio_skip(s->pb, size);
347 348 349 350
            }
            break;
        }
        default:
351
            avio_skip(s->pb, size);
352 353 354 355 356
            break;
        }
    }
}

357
static int avi_read_header(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
358
{
Fabrice Bellard's avatar
Fabrice Bellard committed
359
    AVIContext *avi = s->priv_data;
360
    AVIOContext *pb = s->pb;
361
    unsigned int tag, tag1, handler;
Mans Rullgard's avatar
Mans Rullgard committed
362
    int codec_type, stream_index, frame_period;
Michael Niedermayer's avatar
Michael Niedermayer committed
363
    unsigned int size;
364
    int i;
Fabrice Bellard's avatar
Fabrice Bellard committed
365
    AVStream *st;
366 367 368 369
    AVIStream *ast      = NULL;
    int avih_width      = 0, avih_height = 0;
    int amv_file_format = 0;
    uint64_t list_end   = 0;
370
    int64_t pos;
371
    int ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
372

373
    avi->stream_index = -1;
374

375 376 377
    ret = get_riff(s, pb);
    if (ret < 0)
        return ret;
378

379
    avi->fsize = avio_size(pb);
380
    if (avi->fsize <= 0 || avi->fsize < avi->riff_end)
381
        avi->fsize = avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
382

Fabrice Bellard's avatar
Fabrice Bellard committed
383 384
    /* first list tag */
    stream_index = -1;
385
    codec_type   = -1;
Fabrice Bellard's avatar
Fabrice Bellard committed
386
    frame_period = 0;
387
    for (;;) {
Anton Khirnov's avatar
Anton Khirnov committed
388
        if (pb->eof_reached)
Fabrice Bellard's avatar
Fabrice Bellard committed
389
            goto fail;
390
        tag  = avio_rl32(pb);
391
        size = avio_rl32(pb);
392

Fabrice Bellard's avatar
Fabrice Bellard committed
393 394
        print_tag("tag", tag, size);

395
        switch (tag) {
Fabrice Bellard's avatar
Fabrice Bellard committed
396
        case MKTAG('L', 'I', 'S', 'T'):
397
            list_end = avio_tell(pb) + size;
Diego Biurrun's avatar
Diego Biurrun committed
398
            /* Ignored, except at start of video packets. */
399
            tag1 = avio_rl32(pb);
400

Fabrice Bellard's avatar
Fabrice Bellard committed
401
            print_tag("list", tag1, 0);
402

Fabrice Bellard's avatar
Fabrice Bellard committed
403
            if (tag1 == MKTAG('m', 'o', 'v', 'i')) {
404
                avi->movi_list = avio_tell(pb) - 4;
405 406 407
                if (size)
                    avi->movi_end = avi->movi_list + size + (size & 1);
                else
408
                    avi->movi_end = avi->fsize;
409
                av_log(NULL, AV_LOG_TRACE, "movi end=%"PRIx64"\n", avi->movi_end);
Fabrice Bellard's avatar
Fabrice Bellard committed
410
                goto end_of_header;
411
            } else if (tag1 == MKTAG('I', 'N', 'F', 'O'))
412
                ff_read_riff_info(s, size - 4);
413 414
            else if (tag1 == MKTAG('n', 'c', 'd', 't'))
                avi_read_nikon(s, list_end);
415

Fabrice Bellard's avatar
Fabrice Bellard committed
416
            break;
417 418 419
        case MKTAG('I', 'D', 'I', 'T'):
        {
            unsigned char date[64] = { 0 };
420
            size += (size & 1);
421
            size -= avio_read(pb, date, FFMIN(size, sizeof(date) - 1));
422
            avio_skip(pb, size);
423 424 425
            avi_metadata_creation_time(&s->metadata, date);
            break;
        }
426
        case MKTAG('d', 'm', 'l', 'h'):
427
            avi->is_odml = 1;
428
            avio_skip(pb, size + (size & 1));
429
            break;
430
        case MKTAG('a', 'm', 'v', 'h'):
431
            amv_file_format = 1;
Fabrice Bellard's avatar
Fabrice Bellard committed
432
        case MKTAG('a', 'v', 'i', 'h'):
Diego Biurrun's avatar
Diego Biurrun committed
433
            /* AVI header */
434
            /* using frame_period is bad idea */
435
            frame_period = avio_rl32(pb);
Mans Rullgard's avatar
Mans Rullgard committed
436
            avio_skip(pb, 4);
437 438
            avio_rl32(pb);
            avi->non_interleaved |= avio_rl32(pb) & AVIF_MUSTUSEINDEX;
439

440
            avio_skip(pb, 2 * 4);
441 442
            avio_rl32(pb);
            avio_rl32(pb);
443 444
            avih_width  = avio_rl32(pb);
            avih_height = avio_rl32(pb);
445

446
            avio_skip(pb, size - 10 * 4);
447 448 449 450
            break;
        case MKTAG('s', 't', 'r', 'h'):
            /* stream header */

451
            tag1    = avio_rl32(pb);
452
            handler = avio_rl32(pb); /* codec tag */
453

454
            if (tag1 == MKTAG('p', 'a', 'd', 's')) {
455
                avio_skip(pb, size - 8);
456
                break;
457
            } else {
458
                stream_index++;
459
                st = avformat_new_stream(s, NULL);
Fabrice Bellard's avatar
Fabrice Bellard committed
460 461
                if (!st)
                    goto fail;
462

463
                st->id = stream_index;
464
                ast    = av_mallocz(sizeof(AVIStream));
Fabrice Bellard's avatar
Fabrice Bellard committed
465 466 467
                if (!ast)
                    goto fail;
                st->priv_data = ast;
468
            }
469 470 471
            if (amv_file_format)
                tag1 = stream_index ? MKTAG('a', 'u', 'd', 's')
                                    : MKTAG('v', 'i', 'd', 's');
472

473
            print_tag("strh", tag1, -1);
474

475 476
            if (tag1 == MKTAG('i', 'a', 'v', 's') ||
                tag1 == MKTAG('i', 'v', 'a', 's')) {
477 478
                int64_t dv_dur;

479 480
                /* After some consideration -- I don't think we
                 * have to support anything but DV in type1 AVIs. */
481 482 483 484 485 486
                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'))
487
                    goto fail;
488 489

                ast = s->streams[0]->priv_data;
490 491
                av_freep(&s->streams[0]->codecpar->extradata);
                av_freep(&s->streams[0]->codecpar);
492
                av_freep(&s->streams[0]->info);
493 494
                av_freep(&s->streams[0]);
                s->nb_streams = 0;
495
                if (CONFIG_DV_DEMUXER) {
496
                    avi->dv_demux = avpriv_dv_init_demux(s);
497 498
                    if (!avi->dv_demux)
                        goto fail;
499 500
                } else
                    goto fail;
501
                s->streams[0]->priv_data = ast;
502
                avio_skip(pb, 3 * 4);
503
                ast->scale = avio_rl32(pb);
504
                ast->rate  = avio_rl32(pb);
505
                avio_skip(pb, 4);  /* start time */
506

507
                dv_dur = avio_rl32(pb);
508
                if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
509
                    dv_dur     *= AV_TIME_BASE;
510 511
                    s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
                }
512 513
                /* else, leave duration alone; timing estimation in utils.c
                 * will make a guess based on bitrate. */
514

515
                stream_index = s->nb_streams - 1;
516
                avio_skip(pb, size - 9 * 4);
517 518
                break;
            }
519

520
            assert(stream_index < s->nb_streams);
521
            ast->handler = handler;
522

523 524 525 526 527
            avio_rl32(pb); /* flags */
            avio_rl16(pb); /* priority */
            avio_rl16(pb); /* language */
            avio_rl32(pb); /* initial frame */
            ast->scale = avio_rl32(pb);
528 529 530
            ast->rate  = avio_rl32(pb);
            if (!(ast->scale && ast->rate)) {
                av_log(s, AV_LOG_WARNING,
531
                       "scale/rate is %"PRIu32"/%"PRIu32" which is invalid. "
532 533 534 535 536
                       "(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
537
                    ast->scale = frame_period;
538 539
                } else {
                    ast->rate  = 25;
Michael Niedermayer's avatar
Michael Niedermayer committed
540 541
                    ast->scale = 1;
                }
542
            }
543
            avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
544

545
            ast->cum_len  = avio_rl32(pb); /* start */
546
            st->nb_frames = avio_rl32(pb);
547

548
            st->start_time = 0;
549 550
            avio_rl32(pb); /* buffer size */
            avio_rl32(pb); /* quality */
551
            ast->sample_size = avio_rl32(pb); /* sample size */
552
            ast->cum_len    *= FFMAX(1, ast->sample_size);
553
            av_log(s, AV_LOG_TRACE, "%"PRIu32" %"PRIu32" %d\n",
554
                    ast->rate, ast->scale, ast->sample_size);
555

556
            switch (tag1) {
557
            case MKTAG('v', 'i', 'd', 's'):
558
                codec_type = AVMEDIA_TYPE_VIDEO;
559

560 561 562
                ast->sample_size = 0;
                break;
            case MKTAG('a', 'u', 'd', 's'):
563
                codec_type = AVMEDIA_TYPE_AUDIO;
564
                break;
565
            case MKTAG('t', 'x', 't', 's'):
566
                codec_type = AVMEDIA_TYPE_SUBTITLE;
567
                break;
Florian Echtler's avatar
Florian Echtler committed
568
            case MKTAG('d', 'a', 't', 's'):
569
                codec_type = AVMEDIA_TYPE_DATA;
Florian Echtler's avatar
Florian Echtler committed
570
                break;
571
            default:
Michael Niedermayer's avatar
Michael Niedermayer committed
572
                av_log(s, AV_LOG_ERROR, "unknown stream type %X\n", tag1);
573
                goto fail;
Fabrice Bellard's avatar
Fabrice Bellard committed
574
            }
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591

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

592
            if (ast->sample_size == 0)
593
                st->duration = st->nb_frames;
594
            ast->frame_offset = ast->cum_len;
595
            avio_skip(pb, size - 12 * 4);
Fabrice Bellard's avatar
Fabrice Bellard committed
596 597 598
            break;
        case MKTAG('s', 't', 'r', 'f'):
            /* stream header */
599
            if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
600
                avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
601
            } else {
602
                uint64_t cur_pos = avio_tell(pb);
603 604
                if (cur_pos < list_end)
                    size = FFMIN(size, list_end - cur_pos);
Fabrice Bellard's avatar
Fabrice Bellard committed
605
                st = s->streams[stream_index];
606
                switch (codec_type) {
607
                case AVMEDIA_TYPE_VIDEO:
608
                    if (amv_file_format) {
609 610 611 612
                        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;
613
                        avio_skip(pb, size);
614 615
                        break;
                    }
616
                    tag1 = ff_get_bmp_header(pb, st, NULL);
617

618 619
                    if (tag1 == MKTAG('D', 'X', 'S', 'B') ||
                        tag1 == MKTAG('D', 'X', 'S', 'A')) {
620 621 622
                        st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
                        st->codecpar->codec_tag  = tag1;
                        st->codecpar->codec_id   = AV_CODEC_ID_XSUB;
623 624 625
                        break;
                    }

626
                    if (size > 10 * 4 && size < (1 << 30)) {
627 628 629 630 631
                        st->codecpar->extradata_size = size - 10 * 4;
                        st->codecpar->extradata      = av_malloc(st->codecpar->extradata_size +
                                                                 AV_INPUT_BUFFER_PADDING_SIZE);
                        if (!st->codecpar->extradata) {
                            st->codecpar->extradata_size = 0;
632 633
                            return AVERROR(ENOMEM);
                        }
634
                        avio_read(pb,
635 636
                                  st->codecpar->extradata,
                                  st->codecpar->extradata_size);
637
                    }
638

639
                    // FIXME: check if the encoder really did this correctly
640
                    if (st->codecpar->extradata_size & 1)
641
                        avio_r8(pb);
642

643 644 645 646
                    /* Extract palette from extradata if bpp <= 8.
                     * This code assumes that extradata contains only palette.
                     * This is true for all paletted codecs implemented in
                     * Libav. */
647 648 649
                    if (st->codecpar->extradata_size &&
                        (st->codecpar->bits_per_coded_sample <= 8)) {
                        int pal_size = (1 << st->codecpar->bits_per_coded_sample) << 2;
650 651
                        const uint8_t *pal_src;

652 653 654
                        pal_size = FFMIN(pal_size, st->codecpar->extradata_size);
                        pal_src  = st->codecpar->extradata +
                                   st->codecpar->extradata_size - pal_size;
655
                        for (i = 0; i < pal_size / 4; i++)
656
                            ast->pal[i] = (0xFFu << 24) | AV_RL32(pal_src + 4 * i);
657
                        ast->has_pal = 1;
658 659
                    }

Fabrice Bellard's avatar
Fabrice Bellard committed
660
                    print_tag("video", tag1, 0);
661

662 663 664
                    st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
                    st->codecpar->codec_tag  = tag1;
                    st->codecpar->codec_id   = ff_codec_get_id(ff_codec_bmp_tags,
665
                                                            tag1);
666
                    /* If codec is not found yet, try with the mov tags. */
667
                    if (!st->codecpar->codec_id) {
668 669
                        char tag_buf[32];
                        av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag1);
670
                        st->codecpar->codec_id =
671
                            ff_codec_get_id(ff_codec_movvideo_tags, tag1);
672
                        if (st->codecpar->codec_id)
673 674 675 676
                           av_log(s, AV_LOG_WARNING,
                                  "mov tag found in avi (fourcc %s)\n",
                                  tag_buf);
                    }
677 678 679
                    /* This is needed to get the pict type which is necessary
                     * for generating correct pts. */
                    st->need_parsing = AVSTREAM_PARSE_HEADERS;
680

681
                    if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4 &&
682
                        ast->handler == MKTAG('X', 'V', 'I', 'D'))
683
                        st->codecpar->codec_tag = MKTAG('X', 'V', 'I', 'D');
684

685
                    // Support "Resolution 1:1" for Avid AVI Codec
686
                    if (tag1 == MKTAG('A', 'V', 'R', 'n') &&
687 688 689 690 691 692 693 694 695
                        st->codecpar->extradata_size >= 31   &&
                        !memcmp(&st->codecpar->extradata[28], "1:1", 3))
                        st->codecpar->codec_id = AV_CODEC_ID_RAWVIDEO;

                    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 +
696
                                               AV_INPUT_BUFFER_PADDING_SIZE)) < 0) {
697
                            st->codecpar->extradata_size = 0;
698
                            return ret;
699
                        } else
700
                            memcpy(st->codecpar->extradata + st->codecpar->extradata_size - 9,
701
                                   "BottomUp", 9);
702
                    }
703
                    st->codecpar->height = FFABS(st->codecpar->height);
704

705
//                    avio_skip(pb, size - 5 * 4);
Fabrice Bellard's avatar
Fabrice Bellard committed
706
                    break;
707
                case AVMEDIA_TYPE_AUDIO:
708
                    ret = ff_get_wav_header(s, pb, st->codecpar, size);
709 710
                    if (ret < 0)
                        return ret;
711 712 713
                    ast->dshow_block_align = st->codecpar->block_align;
                    if (ast->sample_size && st->codecpar->block_align &&
                        ast->sample_size != st->codecpar->block_align) {
714 715 716 717
                        av_log(s,
                               AV_LOG_WARNING,
                               "sample size (%d) != block align (%d)\n",
                               ast->sample_size,
718 719
                               st->codecpar->block_align);
                        ast->sample_size = st->codecpar->block_align;
720
                    }
721 722 723
                    /* 2-aligned
                     * (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
                    if (size & 1)
724
                        avio_skip(pb, 1);
Diego Biurrun's avatar
Diego Biurrun committed
725
                    /* Force parsing as several audio frames can be in
Diego Biurrun's avatar
Diego Biurrun committed
726
                     * one packet and timestamps refer to packet start. */
727
                    st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
Diego Biurrun's avatar
Diego Biurrun committed
728 729 730
                    /* ADTS header is in extradata, AAC without header must be
                     * stored as exact frames. Parser not needed and it will
                     * fail. */
731 732
                    if (st->codecpar->codec_id == AV_CODEC_ID_AAC &&
                        st->codecpar->extradata_size)
733
                        st->need_parsing = AVSTREAM_PARSE_NONE;
734 735
                    /* AVI files with Xan DPCM audio (wrongly) declare PCM
                     * audio in the header but have Axan as stream_code_tag. */
736
                    if (ast->handler == AV_RL32("Axan")) {
737 738
                        st->codecpar->codec_id  = AV_CODEC_ID_XAN_DPCM;
                        st->codecpar->codec_tag = 0;
739
                    }
740
                    if (amv_file_format) {
741
                        st->codecpar->codec_id    = AV_CODEC_ID_ADPCM_IMA_AMV;
742 743
                        ast->dshow_block_align = 0;
                    }
Fabrice Bellard's avatar
Fabrice Bellard committed
744
                    break;
745
                case AVMEDIA_TYPE_SUBTITLE:
746 747
                    st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
                    st->codecpar->codec_id   = AV_CODEC_ID_PROBE;
748
                    break;
Fabrice Bellard's avatar
Fabrice Bellard committed
749
                default:
750 751 752
                    st->codecpar->codec_type = AVMEDIA_TYPE_DATA;
                    st->codecpar->codec_id   = AV_CODEC_ID_NONE;
                    st->codecpar->codec_tag  = 0;
753
                    avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
754 755 756 757
                    break;
                }
            }
            break;
758
        case MKTAG('i', 'n', 'd', 'x'):
759
            pos = avio_tell(pb);
760 761
            if ((pb->seekable & AVIO_SEEKABLE_NORMAL) &&
                !(s->flags & AVFMT_FLAG_IGNIDX) &&
762 763
                read_braindead_odml_indx(s, 0) < 0 &&
                (s->error_recognition & AV_EF_EXPLODE))
764
                goto fail;
765
            avio_seek(pb, pos + size, SEEK_SET);
766
            break;
767
        case MKTAG('v', 'p', 'r', 'p'):
768
            if (stream_index < (unsigned)s->nb_streams && size > 9 * 4) {
769 770 771
                AVRational active, active_aspect;

                st = s->streams[stream_index];
772 773 774 775 776 777
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);

778 779 780 781 782
                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
783

784 785 786
                if (active_aspect.num && active_aspect.den &&
                    active.num && active.den) {
                    st->sample_aspect_ratio = av_div_q(active_aspect, active);
787
                    av_log(s, AV_LOG_TRACE, "vprp %d/%d %d/%d\n",
788 789
                            active_aspect.num, active_aspect.den,
                            active.num, active.den);
790
                }
791
                size -= 9 * 4;
792
            }
793
            avio_skip(pb, size);
794
            break;
795
        case MKTAG('s', 't', 'r', 'n'):
796 797
            if (s->nb_streams) {
                ret = avi_read_tag(s, s->streams[s->nb_streams - 1], tag, size);
798 799
                if (ret < 0)
                    return ret;
800 801
                break;
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
802
        default:
803 804 805 806
            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");
807 808
                if (s->error_recognition & AV_EF_EXPLODE)
                    goto fail;
809
                avi->movi_list = avio_tell(pb) - 4;
810
                avi->movi_end  = avi->fsize;
811 812
                goto end_of_header;
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
813 814
            /* skip tag */
            size += (size & 1);
815
            avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
816 817 818
            break;
        }
    }
819 820

end_of_header:
Fabrice Bellard's avatar
Fabrice Bellard committed
821 822
    /* check stream number */
    if (stream_index != s->nb_streams - 1) {
823 824

fail:
825
        return AVERROR_INVALIDDATA;
Fabrice Bellard's avatar
Fabrice Bellard committed
826
    }
827

828
    if (!avi->index_loaded && (pb->seekable & AVIO_SEEKABLE_NORMAL))
829
        avi_load_index(s);
830
    avi->index_loaded     = 1;
831 832 833 834 835

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

    avi->non_interleaved |= ret;
836
    for (i = 0; i < s->nb_streams; i++) {
837
        AVStream *st = s->streams[i];
838
        if (st->nb_index_entries)
839 840
            break;
    }
841 842 843 844
    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;
845 846
    }

847
    if (avi->non_interleaved) {
Diego Biurrun's avatar
Diego Biurrun committed
848
        av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
849
        clean_index(s);
850
    }
851

852 853
    ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);
    ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
854

Fabrice Bellard's avatar
Fabrice Bellard committed
855 856 857
    return 0;
}

858 859
static int read_gab2_sub(AVStream *st, AVPacket *pkt)
{
860 861
    if (pkt->size >= 7 &&
        !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) {
862
        uint8_t desc[256];
863
        int score      = AVPROBE_SCORE_EXTENSION, ret;
864 865 866
        AVIStream *ast = st->priv_data;
        AVInputFormat *sub_demuxer;
        AVRational time_base;
867 868 869
        AVIOContext *pb = avio_alloc_context(pkt->data + 7,
                                             pkt->size - 7,
                                             0, NULL, NULL, NULL, NULL);
870
        AVProbeData pd;
871
        unsigned int desc_len = avio_rl32(pb);
872

873 874
        if (desc_len > pb->buf_end - pb->buf_ptr)
            goto error;
875

876
        ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
877
        avio_skip(pb, desc_len - ret);
878
        if (*desc)
879
            av_dict_set(&st->metadata, "title", desc, 0);
880

881 882
        avio_rl16(pb);   /* flags? */
        avio_rl32(pb);   /* data size */
883

884 885
        pd = (AVProbeData) { .buf      = pb->buf_ptr,
                             .buf_size = pb->buf_end - pb->buf_ptr };
886
        if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
887
            goto error;
888

889 890 891
        if (!(ast->sub_ctx = avformat_alloc_context()))
            goto error;

892
        ast->sub_ctx->pb = pb;
893
        if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
894
            ff_read_packet(ast->sub_ctx, &ast->sub_pkt);
895
            avcodec_parameters_copy(st->codecpar, ast->sub_ctx->streams[0]->codecpar);
896
            time_base = ast->sub_ctx->streams[0]->time_base;
897
            avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
898 899 900 901
        }
        ast->sub_buffer = pkt->data;
        memset(pkt, 0, sizeof(*pkt));
        return 1;
902

903
error:
904
        avio_context_free(&pb);
905 906 907 908 909 910 911 912 913 914 915 916 917 918 919
    }
    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);

920
    for (i = 0; i < s->nb_streams; i++) {
921 922
        st  = s->streams[i];
        ast = st->priv_data;
923
        if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
924 925 926 927 928 929 930 931 932
            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) {
933 934
        ast               = sub_st->priv_data;
        *pkt              = ast->sub_pkt;
935
        pkt->stream_index = sub_st->index;
936

937
        if (ff_read_packet(ast->sub_ctx, &ast->sub_pkt) < 0)
938 939 940 941 942
            ast->sub_pkt.data = NULL;
    }
    return sub_st;
}

943 944 945 946
static int get_stream_idx(int *d)
{
    if (d[0] >= '0' && d[0] <= '9' &&
        d[1] >= '0' && d[1] <= '9') {
947
        return (d[0] - '0') * 10 + (d[1] - '0');
948 949
    } else {
        return 100; // invalid stream ID
950 951 952
    }
}

953
static int avi_sync(AVFormatContext *s, int exit_early)
Fabrice Bellard's avatar
Fabrice Bellard committed
954 955
{
    AVIContext *avi = s->priv_data;
956
    AVIOContext *pb = s->pb;
957 958
    int n;
    unsigned int d[8];
959
    unsigned int size;
960
    int64_t i, sync;
961 962

start_sync:
963
    memset(d, -1, sizeof(d));
964
    for (i = sync = avio_tell(pb); !pb->eof_reached; i++) {
965 966
        int j;

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

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

973
        n = get_stream_idx(d + 2);
974
        av_log(s, AV_LOG_TRACE, "%X %X %X %X %X %X %X %X %"PRId64" %u %d\n",
975
                d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
976
        if (i + (uint64_t)size > avi->fsize || d[0] > 127)
977 978
            continue;

979 980 981 982 983
        // 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')) {
984 985 986 987
            avio_skip(pb, size);
            goto start_sync;
        }

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

994
        n = get_stream_idx(d);
995

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

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

1006 1007 1008
        if (avi->dv_demux && n != 0)
            continue;

1009 1010
        // parse ##dc/##wb
        if (n < s->nb_streams) {
1011 1012
            AVStream *st;
            AVIStream *ast;
1013
            st  = s->streams[n];
1014 1015
            ast = st->priv_data;

1016 1017 1018 1019 1020
            if (s->nb_streams >= 2) {
                AVStream *st1   = s->streams[1];
                AVIStream *ast1 = st1->priv_data;
                // workaround for broken small-file-bug402.avi
                if (d[2] == 'w' && d[3] == 'b' && n == 0 &&
1021 1022
                    st->codecpar->codec_type  == AVMEDIA_TYPE_VIDEO &&
                    st1->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
1023 1024 1025 1026 1027
                    ast->prefix == 'd' * 256 + 'c' &&
                    (d[2] * 256 + d[3] == ast1->prefix ||
                     !ast1->prefix_count)) {
                    n   = 1;
                    st  = st1;
1028
                    ast = ast1;
1029 1030
                    av_log(s, AV_LOG_WARNING,
                           "Invalid stream + prefix combination, assuming audio.\n");
1031 1032 1033
                }
            }

1034 1035 1036 1037 1038 1039
            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)) {
1040 1041 1042
                if (!exit_early) {
                    ast->frame_offset += get_duration(ast, size);
                }
1043 1044 1045 1046
                avio_skip(pb, size);
                goto start_sync;
            }

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

1051
                avio_rl16(pb); // flags
1052

1053
                // b + (g << 8) + (r << 16);
1054
                for (; k <= last; k++)
1055
                    ast->pal[k] = avio_rb32(pb) >> 8;
1056

1057 1058 1059 1060 1061 1062 1063
                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') */) {
1064 1065
                if (exit_early)
                    return 0;
1066
                if (d[2] * 256 + d[3] == ast->prefix)
1067
                    ast->prefix_count++;
1068 1069 1070
                else {
                    ast->prefix       = d[2] * 256 + d[3];
                    ast->prefix_count = 0;
1071 1072
                }

1073 1074 1075
                avi->stream_index = n;
                ast->packet_size  = size + 8;
                ast->remaining    = size;
1076

1077 1078 1079 1080 1081 1082
                if (size || !ast->sample_size) {
                    uint64_t pos = avio_tell(pb) - 8;
                    if (!st->index_entries || !st->nb_index_entries ||
                        st->index_entries[st->nb_index_entries - 1].pos < pos) {
                        av_add_index_entry(st, pos, ast->frame_offset, size,
                                           0, AVINDEX_KEYFRAME);
1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
                    }
                }
                return 0;
            }
        }
    }

    return AVERROR_EOF;
}

1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 1157 1158 1159 1160 1161
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;
    best_ts  = av_rescale_q(best_ts,
                            (AVRational) { FFMAX(1, best_ast->sample_size),
                                           AV_TIME_BASE },
                            best_st->time_base);
    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;
        avio_seek(s->pb, pos + 8, SEEK_SET);

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

        avi->stream_index = best_stream_index;
        if (!best_ast->remaining)
            best_ast->packet_size =
            best_ast->remaining   = best_st->index_entries[i].size;
    }

    return 0;
}

1162 1163 1164 1165 1166
static int avi_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIContext *avi = s->priv_data;
    AVIOContext *pb = s->pb;
    int err;
1167

1168
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1169
        int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
1170 1171
        if (size >= 0)
            return size;
1172 1173
        else
            goto resync;
1174
    }
1175

1176
    if (avi->non_interleaved) {
1177 1178 1179
        err = ni_prepare_read(s);
        if (err < 0)
            return err;
1180
    }
1181

1182
resync:
1183 1184 1185
    if (avi->stream_index >= 0) {
        AVStream *st   = s->streams[avi->stream_index];
        AVIStream *ast = st->priv_data;
1186
        int size, err;
1187

1188
        if (get_subtitle_pkt(s, st, pkt))
1189 1190
            return 0;

1191 1192 1193 1194
        // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
        if (ast->sample_size <= 1)
            size = INT_MAX;
        else if (ast->sample_size < 32)
1195
            // arbitrary multiplier to avoid tiny packets for raw PCM data
1196
            size = 1024 * ast->sample_size;
1197
        else
1198
            size = ast->sample_size;
1199

1200 1201 1202 1203 1204
        if (size > ast->remaining)
            size = ast->remaining;
        avi->last_pkt_pos = avio_tell(pb);
        err               = av_get_packet(pb, pkt, size);
        if (err < 0)
1205
            return err;
1206

1207
        if (ast->has_pal && pkt->data && pkt->size < (unsigned)INT_MAX / 2) {
1208
            uint8_t *pal;
1209 1210 1211 1212 1213 1214 1215
            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 {
1216 1217 1218
                memcpy(pal, ast->pal, AVPALETTE_SIZE);
                ast->has_pal = 0;
            }
1219 1220
        }

1221
        if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1222
            AVBufferRef *avbuf = pkt->buf;
1223
            size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
1224 1225
                                            pkt->data, pkt->size);
            pkt->buf    = avbuf;
1226
            pkt->flags |= AV_PKT_FLAG_KEY;
1227
            if (size < 0)
1228
                av_packet_unref(pkt);
1229 1230
        } else if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE &&
                   !st->codecpar->codec_tag && read_gab2_sub(st, pkt)) {
1231 1232
            ast->frame_offset++;
            avi->stream_index = -1;
1233
            ast->remaining    = 0;
1234
            goto resync;
1235
        } else {
Diego Biurrun's avatar
Diego Biurrun committed
1236
            /* XXX: How to handle B-frames in AVI? */
1237 1238
            pkt->dts = ast->frame_offset;
//                pkt->dts += ast->start;
1239
            if (ast->sample_size)
1240 1241 1242
                pkt->dts /= ast->sample_size;
            pkt->stream_index = avi->stream_index;

1243
            if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1244 1245
                AVIndexEntry *e;
                int index;
1246
                assert(st->index_entries);
1247

1248 1249
                index = av_index_search_timestamp(st, ast->frame_offset, 0);
                e     = &st->index_entries[index];
1250

1251
                if (index >= 0 && e->timestamp == ast->frame_offset)
Michael Niedermayer's avatar
Michael Niedermayer committed
1252
                    if (e->flags & AVINDEX_KEYFRAME)
1253
                        pkt->flags |= AV_PKT_FLAG_KEY;
1254
            } else {
1255
                pkt->flags |= AV_PKT_FLAG_KEY;
1256
            }
1257
            ast->frame_offset += get_duration(ast, pkt->size);
1258
        }
1259
        ast->remaining -= err;
1260 1261 1262
        if (!ast->remaining) {
            avi->stream_index = -1;
            ast->packet_size  = 0;
1263 1264
        }

1265
        return 0;
1266 1267
    }

1268
    if ((err = avi_sync(s, 0)) < 0)
1269 1270
        return err;
    goto resync;
Fabrice Bellard's avatar
Fabrice Bellard committed
1271 1272
}

Diego Biurrun's avatar
Diego Biurrun committed
1273
/* XXX: We make the implicit supposition that the positions are sorted
1274
 * for each stream. */
Fabrice Bellard's avatar
Fabrice Bellard committed
1275 1276
static int avi_read_idx1(AVFormatContext *s, int size)
{
1277
    AVIContext *avi = s->priv_data;
1278
    AVIOContext *pb = s->pb;
Fabrice Bellard's avatar
Fabrice Bellard committed
1279 1280 1281
    int nb_index_entries, i;
    AVStream *st;
    AVIStream *ast;
1282
    unsigned int index, tag, flags, pos, len, first_packet = 1;
1283
    unsigned last_pos = -1;
1284
    int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
1285

Fabrice Bellard's avatar
Fabrice Bellard committed
1286 1287
    nb_index_entries = size / 16;
    if (nb_index_entries <= 0)
1288
        return AVERROR_INVALIDDATA;
Fabrice Bellard's avatar
Fabrice Bellard committed
1289

1290
    idx1_pos = avio_tell(pb);
1291 1292
    avio_seek(pb, avi->movi_list + 4, SEEK_SET);
    if (avi_sync(s, 1) == 0)
1293 1294 1295 1296
        first_packet_pos = avio_tell(pb) - 8;
    avi->stream_index = -1;
    avio_seek(pb, idx1_pos, SEEK_SET);

Diego Biurrun's avatar
Diego Biurrun committed
1297
    /* Read the entries and sort them in each stream component. */
1298 1299
    for (i = 0; i < nb_index_entries; i++) {
        tag   = avio_rl32(pb);
1300
        flags = avio_rl32(pb);
1301 1302
        pos   = avio_rl32(pb);
        len   = avio_rl32(pb);
1303
        av_log(s, AV_LOG_TRACE, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
1304
                i, tag, flags, pos, len);
1305

1306 1307
        index  = ((tag      & 0xff) - '0') * 10;
        index +=  (tag >> 8 & 0xff) - '0';
Fabrice Bellard's avatar
Fabrice Bellard committed
1308 1309
        if (index >= s->nb_streams)
            continue;
1310
        st  = s->streams[index];
Fabrice Bellard's avatar
Fabrice Bellard committed
1311
        ast = st->priv_data;
1312

1313 1314
        if (first_packet && first_packet_pos && len) {
            data_offset  = first_packet_pos - pos;
1315 1316 1317 1318
            first_packet = 0;
        }
        pos += data_offset;

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

1321
        if (pb->eof_reached)
1322
            return AVERROR_INVALIDDATA;
1323

1324 1325 1326 1327 1328
        if (last_pos == pos)
            avi->non_interleaved = 1;
        else if (len || !ast->sample_size)
            av_add_index_entry(st, pos, ast->cum_len, len, 0,
                               (flags & AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
1329
        ast->cum_len += get_duration(ast, len);
1330
        last_pos      = pos;
Fabrice Bellard's avatar
Fabrice Bellard committed
1331 1332 1333 1334
    }
    return 0;
}

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 1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 1375 1376 1377 1378
/* 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,
1379
                                              st->codecpar->bit_rate,
1380 1381 1382 1383 1384 1385 1386 1387 1388 1389 1390 1391 1392
                                              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;
}

1393 1394
static int guess_ni_flag(AVFormatContext *s)
{
1395
    int i;
1396 1397 1398
    int64_t last_start = 0;
    int64_t first_end  = INT64_MAX;
    int64_t oldpos     = avio_tell(s->pb);
1399

1400
    for (i = 0; i < s->nb_streams; i++) {
1401
        AVStream *st = s->streams[i];
1402
        int n        = st->nb_index_entries;
1403
        unsigned int size;
1404

1405
        if (n <= 0)
1406 1407
            continue;

1408 1409
        if (n >= 2) {
            int64_t pos = st->index_entries[0].pos;
1410
            avio_seek(s->pb, pos + 4, SEEK_SET);
1411 1412 1413
            size = avio_rl32(s->pb);
            if (pos + size > st->index_entries[1].pos)
                last_start = INT64_MAX;
1414 1415
        }

1416 1417 1418 1419
        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;
1420
    }
1421
    avio_seek(s->pb, oldpos, SEEK_SET);
1422 1423 1424 1425 1426

    if (last_start > first_end)
        return 1;

    return check_stream_max_drift(s);
1427 1428
}

Fabrice Bellard's avatar
Fabrice Bellard committed
1429 1430 1431
static int avi_load_index(AVFormatContext *s)
{
    AVIContext *avi = s->priv_data;
1432
    AVIOContext *pb = s->pb;
Fabrice Bellard's avatar
Fabrice Bellard committed
1433
    uint32_t tag, size;
1434 1435
    int64_t pos = avio_tell(pb);
    int ret     = -1;
1436

1437
    if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
1438
        goto the_end; // maybe truncated file
1439
    av_log(s, AV_LOG_TRACE, "movi_end=0x%"PRIx64"\n", avi->movi_end);
1440
    for (;;) {
Anton Khirnov's avatar
Anton Khirnov committed
1441
        if (pb->eof_reached)
Fabrice Bellard's avatar
Fabrice Bellard committed
1442
            break;
1443
        tag  = avio_rl32(pb);
1444
        size = avio_rl32(pb);
1445 1446 1447

        if (tag == MKTAG('i', 'd', 'x', '1') &&
            avi_read_idx1(s, size) >= 0) {
1448
            ret = 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
1449 1450
            break;
        }
1451 1452 1453 1454

        size += (size & 1);
        if (avio_skip(pb, size) < 0)
            break; // something is wrong here
Fabrice Bellard's avatar
Fabrice Bellard committed
1455
    }
1456 1457

the_end:
1458
    avio_seek(pb, pos, SEEK_SET);
1459
    return ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
1460 1461
}

1462 1463 1464
static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
{
    AVIStream *ast2 = st2->priv_data;
1465
    int64_t ts2     = av_rescale_q(timestamp, st->time_base, st2->time_base);
1466
    av_packet_unref(&ast2->sub_pkt);
1467 1468
    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)
1469
        ff_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
1470 1471
}

1472 1473
static int avi_read_seek(AVFormatContext *s, int stream_index,
                         int64_t timestamp, int flags)
Fabrice Bellard's avatar
Fabrice Bellard committed
1474 1475 1476
{
    AVIContext *avi = s->priv_data;
    AVStream *st;
1477
    int i, index;
Fabrice Bellard's avatar
Fabrice Bellard committed
1478
    int64_t pos;
1479
    AVIStream *ast;
Fabrice Bellard's avatar
Fabrice Bellard committed
1480

1481 1482 1483 1484 1485 1486
    /* 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
1487 1488 1489 1490 1491
    if (!avi->index_loaded) {
        /* we only load the index on demand */
        avi_load_index(s);
        avi->index_loaded = 1;
    }
1492 1493 1494 1495 1496 1497 1498

    st    = s->streams[stream_index];
    ast   = st->priv_data;
    index = av_index_search_timestamp(st,
                                      timestamp * FFMAX(ast->sample_size, 1),
                                      flags);
    if (index < 0)
1499
        return AVERROR_INVALIDDATA;
1500

Fabrice Bellard's avatar
Fabrice Bellard committed
1501
    /* find the position */
1502
    pos       = st->index_entries[index].pos;
1503
    timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
1504

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

1508
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1509
        /* One and only one real stream for DV in AVI, and it has video  */
1510
        /* offsets. Calling with other stream indexes should have failed */
1511 1512 1513
        /* the av_index_search_timestamp call above.                     */

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

1517
        avio_seek(s->pb, pos, SEEK_SET);
1518
        avi->stream_index = -1;
1519 1520 1521
        return 0;
    }

1522 1523
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st2   = s->streams[i];
1524
        AVIStream *ast2 = st2->priv_data;
1525

1526 1527
        ast2->packet_size =
        ast2->remaining   = 0;
1528

1529 1530 1531 1532 1533
        if (ast2->sub_ctx) {
            seek_subtitle(st, st2, timestamp);
            continue;
        }

1534 1535
        if (st2->nb_index_entries <= 0)
            continue;
1536

1537
//        assert(st2->codecpar->block_align);
1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550
        assert((int64_t)st2->time_base.num * ast2->rate ==
               (int64_t)st2->time_base.den * ast2->scale);
        index = av_index_search_timestamp(st2,
                                          av_rescale_q(timestamp,
                                                       st->time_base,
                                                       st2->time_base) *
                                          FFMAX(ast2->sample_size, 1),
                                          flags | AVSEEK_FLAG_BACKWARD);
        if (index < 0)
            index = 0;

        if (!avi->non_interleaved) {
            while (index > 0 && st2->index_entries[index].pos > pos)
1551
                index--;
1552 1553
            while (index + 1 < st2->nb_index_entries &&
                   st2->index_entries[index].pos < pos)
1554 1555 1556
                index++;
        }

1557
        av_log(s, AV_LOG_TRACE, "%"PRId64" %d %"PRId64"\n",
1558
                timestamp, index, st2->index_entries[index].timestamp);
1559 1560
        /* extract the current frame number */
        ast2->frame_offset = st2->index_entries[index].timestamp;
Fabrice Bellard's avatar
Fabrice Bellard committed
1561
    }
1562

Fabrice Bellard's avatar
Fabrice Bellard committed
1563
    /* do the seek */
1564
    avio_seek(s->pb, pos, SEEK_SET);
1565
    avi->stream_index = -1;
Fabrice Bellard's avatar
Fabrice Bellard committed
1566 1567 1568
    return 0;
}

1569
static int avi_read_close(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
1570
{
Michael Niedermayer's avatar
Michael Niedermayer committed
1571 1572 1573
    int i;
    AVIContext *avi = s->priv_data;

1574 1575
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st   = s->streams[i];
1576
        AVIStream *ast = st->priv_data;
1577
        if (ast) {
1578
            if (ast->sub_ctx) {
1579
                avio_context_free(&ast->sub_ctx->pb);
1580
                avformat_close_input(&ast->sub_ctx);
1581 1582
            }
            av_free(ast->sub_buffer);
1583
            av_packet_unref(&ast->sub_pkt);
1584
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
1585 1586
    }

1587
    av_free(avi->dv_demux);
1588

Fabrice Bellard's avatar
Fabrice Bellard committed
1589 1590 1591 1592 1593
    return 0;
}

static int avi_probe(AVProbeData *p)
{
1594 1595
    int i;

Fabrice Bellard's avatar
Fabrice Bellard committed
1596
    /* check file header */
1597 1598 1599
    for (i = 0; avi_headers[i][0]; i++)
        if (!memcmp(p->buf,     avi_headers[i],     4) &&
            !memcmp(p->buf + 8, avi_headers[i] + 4, 4))
1600 1601 1602
            return AVPROBE_SCORE_MAX;

    return 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
1603 1604
}

1605
AVInputFormat ff_avi_demuxer = {
1606
    .name           = "avi",
1607
    .long_name      = NULL_IF_CONFIG_SMALL("AVI (Audio Video Interleaved)"),
1608
    .priv_data_size = sizeof(AVIContext),
1609
    .extensions     = "avi",
1610 1611 1612 1613 1614
    .read_probe     = avi_probe,
    .read_header    = avi_read_header,
    .read_packet    = avi_read_packet,
    .read_close     = avi_read_close,
    .read_seek      = avi_read_seek,
Fabrice Bellard's avatar
Fabrice Bellard committed
1615
};