avidec.c 51.4 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 "libavutil/intreadwrite.h"
23
#include "libavutil/mathematics.h"
24
#include "libavutil/bswap.h"
25
#include "libavutil/opt.h"
26
#include "libavutil/dict.h"
27
#include "libavutil/avstring.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
28
#include "avformat.h"
29
#include "internal.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
30
#include "avi.h"
31
#include "dv.h"
32
#include "riff.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
33

34 35 36
#undef NDEBUG
#include <assert.h>

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

Fabrice Bellard's avatar
Fabrice Bellard committed
43
    int scale;
44
    int rate;
45
    int sample_size; /* size of one sample (or packet) (in the rate/scale sense) in bytes */
46

47
    int64_t cum_len; /* temporary storage (used during seek) */
48

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

    AVFormatContext *sub_ctx;
    AVPacket sub_pkt;
    uint8_t *sub_buffer;
58 59

    int64_t seek_pos;
Fabrice Bellard's avatar
Fabrice Bellard committed
60
} AVIStream;
Fabrice Bellard's avatar
Fabrice Bellard committed
61 62

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

80 81

static const AVOption options[] = {
82
    { "use_odml", "use odml index", offsetof(AVIContext, use_odml), AV_OPT_TYPE_INT, {.dbl = 1}, -1, 1, AV_OPT_FLAG_DECODING_PARAM},
83 84 85 86 87 88 89 90 91 92 93
    { NULL },
};

static const AVClass demuxer_class = {
    "AVI demuxer",
    av_default_item_name,
    options,
    LIBAVUTIL_VERSION_INT,
};


94 95 96 97
static const char avi_headers[][8] = {
    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', ' ' },
    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 'X' },
    { 'R', 'I', 'F', 'F',    'A', 'V', 'I', 0x19},
98
    { 'O', 'N', '2', ' ',    'O', 'N', '2', 'f' },
99
    { 'R', 'I', 'F', 'F',    'A', 'M', 'V', ' ' },
100 101 102
    { 0 }
};

103 104 105 106 107
static const AVMetadataConv avi_metadata_conv[] = {
    { "strn", "title" },
    { 0 },
};

108
static int avi_load_index(AVFormatContext *s);
109
static int guess_ni_flag(AVFormatContext *s);
110

111
#define print_tag(str, tag, size)                       \
112
    av_dlog(NULL, "%s: tag=%c%c%c%c size=0x%x\n",       \
113 114 115 116 117
           str, tag & 0xff,                             \
           (tag >> 8) & 0xff,                           \
           (tag >> 16) & 0xff,                          \
           (tag >> 24) & 0xff,                          \
           size)
Fabrice Bellard's avatar
Fabrice Bellard committed
118

119 120 121
static inline int get_duration(AVIStream *ast, int len){
    if(ast->sample_size){
        return len;
122 123
    }else if (ast->dshow_block_align){
        return (len + ast->dshow_block_align - 1)/ast->dshow_block_align;
124 125 126 127
    }else
        return 1;
}

128
static int get_riff(AVFormatContext *s, AVIOContext *pb)
129
{
130
    AVIContext *avi = s->priv_data;
131 132
    char header[8];
    int i;
133

134
    /* check RIFF header */
135 136
    avio_read(pb, header, 4);
    avi->riff_end = avio_rl32(pb);  /* RIFF chunk size */
137
    avi->riff_end += avio_tell(pb); /* RIFF chunk end */
138
    avio_read(pb, header+4, 4);
139 140 141 142 143

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

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

149 150 151
    return 0;
}

152
static int read_braindead_odml_indx(AVFormatContext *s, int frame_num){
153
    AVIContext *avi = s->priv_data;
154
    AVIOContext *pb = s->pb;
155 156 157 158 159 160
    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);
161 162 163 164
    int stream_id= 10*((chunk_id&0xFF) - '0') + (((chunk_id>>8)&0xFF) - '0');
    AVStream *st;
    AVIStream *ast;
    int i;
165
    int64_t last_pos= -1;
166
    int64_t filesize= avi->fsize;
167

168 169
    av_dlog(s, "longs_pre_entry:%d index_type:%d entries_in_use:%d chunk_id:%X base:%16"PRIX64"\n",
            longs_pre_entry,index_type, entries_in_use, chunk_id, base);
170

171
    if(stream_id >= s->nb_streams || stream_id < 0)
172 173 174 175 176 177 178
        return -1;
    st= s->streams[stream_id];
    ast = st->priv_data;

    if(index_sub_type)
        return -1;

179
    avio_rl32(pb);
180 181 182 183 184 185

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

186 187 188 189 190 191 192 193
    if(filesize > 0 && base >= filesize){
        av_log(s, AV_LOG_ERROR, "ODML index invalid\n");
        if(base>>32 == (base & 0xFFFFFFFF) && (base & 0xFFFFFFFF) < filesize && filesize <= 0xFFFFFFFF)
            base &= 0xFFFFFFFF;
        else
            return -1;
    }

194 195
    for(i=0; i<entries_in_use; i++){
        if(index_type){
196 197
            int64_t pos= avio_rl32(pb) + base - 8;
            int len    = avio_rl32(pb);
198
            int key= len >= 0;
199 200
            len &= 0x7FFFFFFF;

201
#ifdef DEBUG_SEEK
202
            av_log(s, AV_LOG_ERROR, "pos:%"PRId64", len:%X\n", pos, len);
203
#endif
204 205 206
            if(url_feof(pb))
                return -1;

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

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

            if(url_feof(pb))
                return -1;

224
            pos = avio_tell(pb);
225

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

231 232
            if(avio_seek(pb, offset+8, SEEK_SET) < 0)
                return -1;
233
            avi->odml_depth++;
234
            read_braindead_odml_indx(s, frame_num);
235
            avi->odml_depth--;
236 237
            frame_num += duration;

238 239 240 241 242
            if(avio_seek(pb, pos, SEEK_SET) < 0) {
                av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index");
                return -1;
            }

243 244
        }
    }
245
    avi->index_loaded=2;
246 247 248
    return 0;
}

249
static void clean_index(AVFormatContext *s){
250 251
    int i;
    int64_t j;
252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269

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

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

        while(max < 1024) max+=max;

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

        for(j=0; j<size; j+=max){
270
            av_add_index_entry(st, pos+j, ts+j, FFMIN(max, size-j), 0, AVINDEX_KEYFRAME);
271 272 273 274
        }
    }
}

275
static int avi_read_tag(AVFormatContext *s, AVStream *st, uint32_t tag, uint32_t size)
276
{
277
    AVIOContext *pb = s->pb;
278
    char key[5] = {0}, *value;
279

280
    size += (size & 1);
281

282 283 284 285 286
    if (size == UINT_MAX)
        return -1;
    value = av_malloc(size+1);
    if (!value)
        return -1;
287
    avio_read(pb, value, size);
288
    value[size]=0;
289

290 291
    AV_WL32(key, tag);

292 293
    return av_dict_set(st ? &st->metadata : &s->metadata, key, value,
                            AV_DICT_DONT_STRDUP_VAL);
294 295
}

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

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

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

354
static int avi_read_header(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
355
{
Fabrice Bellard's avatar
Fabrice Bellard committed
356
    AVIContext *avi = s->priv_data;
357
    AVIOContext *pb = s->pb;
358
    unsigned int tag, tag1, handler;
359
    int codec_type, stream_index, frame_period;
Michael Niedermayer's avatar
Michael Niedermayer committed
360
    unsigned int size;
361
    int i;
Fabrice Bellard's avatar
Fabrice Bellard committed
362
    AVStream *st;
Måns Rullgård's avatar
Måns Rullgård committed
363
    AVIStream *ast = NULL;
364 365
    int avih_width=0, avih_height=0;
    int amv_file_format=0;
366
    uint64_t list_end = 0;
367
    int ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
368

369
    avi->stream_index= -1;
370

371
    if (get_riff(s, pb) < 0)
Fabrice Bellard's avatar
Fabrice Bellard committed
372
        return -1;
373

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

376
    avi->fsize = avio_size(pb);
377
    if(avi->fsize<=0 || avi->fsize < avi->riff_end)
378
        avi->fsize= avi->riff_end == 8 ? INT64_MAX : avi->riff_end;
379

Fabrice Bellard's avatar
Fabrice Bellard committed
380 381 382 383 384 385 386
    /* first list tag */
    stream_index = -1;
    codec_type = -1;
    frame_period = 0;
    for(;;) {
        if (url_feof(pb))
            goto fail;
387 388
        tag = avio_rl32(pb);
        size = avio_rl32(pb);
389

Fabrice Bellard's avatar
Fabrice Bellard committed
390 391 392 393
        print_tag("tag", tag, size);

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

Fabrice Bellard's avatar
Fabrice Bellard committed
398
            print_tag("list", tag1, 0);
399

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

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

435
            avio_skip(pb, 2 * 4);
436 437 438 439
            avio_rl32(pb);
            avio_rl32(pb);
            avih_width=avio_rl32(pb);
            avih_height=avio_rl32(pb);
440

441
            avio_skip(pb, size - 10 * 4);
442 443 444 445
            break;
        case MKTAG('s', 't', 'r', 'h'):
            /* stream header */

446 447
            tag1 = avio_rl32(pb);
            handler = avio_rl32(pb); /* codec tag */
448 449

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

458
                st->id = stream_index;
Fabrice Bellard's avatar
Fabrice Bellard committed
459 460 461 462
                ast = av_mallocz(sizeof(AVIStream));
                if (!ast)
                    goto fail;
                st->priv_data = ast;
463
            }
464 465
            if(amv_file_format)
                tag1 = stream_index ? MKTAG('a','u','d','s') : MKTAG('v','i','d','s');
466

467
            print_tag("strh", tag1, -1);
468

469
            if(tag1 == MKTAG('i', 'a', 'v', 's') || tag1 == MKTAG('i', 'v', 'a', 's')){
470 471
                int64_t dv_dur;

472
                /*
473
                 * After some consideration -- I don't think we
Diego Biurrun's avatar
Diego Biurrun committed
474
                 * have to support anything but DV in type1 AVIs.
475 476 477 478 479 480 481 482 483 484 485
                 */
                if (s->nb_streams != 1)
                    goto fail;

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

                ast = s->streams[0]->priv_data;
                av_freep(&s->streams[0]->codec->extradata);
486
                av_freep(&s->streams[0]->codec);
487 488
                av_freep(&s->streams[0]);
                s->nb_streams = 0;
489
                if (CONFIG_DV_DEMUXER) {
490
                    avi->dv_demux = avpriv_dv_init_demux(s);
491 492
                    if (!avi->dv_demux)
                        goto fail;
493
                }
494
                s->streams[0]->priv_data = ast;
495
                avio_skip(pb, 3 * 4);
496 497
                ast->scale = avio_rl32(pb);
                ast->rate = avio_rl32(pb);
498
                avio_skip(pb, 4);  /* start time */
499

500
                dv_dur = avio_rl32(pb);
501 502 503 504 505 506
                if (ast->scale > 0 && ast->rate > 0 && dv_dur > 0) {
                    dv_dur *= AV_TIME_BASE;
                    s->duration = av_rescale(dv_dur, ast->scale, ast->rate);
                }
                /*
                 * else, leave duration alone; timing estimation in utils.c
Diego Biurrun's avatar
Diego Biurrun committed
507
                 *      will make a guess based on bitrate.
508 509
                 */

510
                stream_index = s->nb_streams - 1;
511
                avio_skip(pb, size - 9*4);
512 513
                break;
            }
514

515
            assert(stream_index < s->nb_streams);
516
            st->codec->stream_codec_tag= handler;
517

518 519 520 521 522 523
            avio_rl32(pb); /* flags */
            avio_rl16(pb); /* priority */
            avio_rl16(pb); /* language */
            avio_rl32(pb); /* initial frame */
            ast->scale = avio_rl32(pb);
            ast->rate = avio_rl32(pb);
524
            if(!(ast->scale && ast->rate)){
Diego Biurrun's avatar
Diego Biurrun committed
525
                av_log(s, AV_LOG_WARNING, "scale/rate is %u/%u which is invalid. (This file has been generated by broken software.)\n", ast->scale, ast->rate);
Michael Niedermayer's avatar
Michael Niedermayer committed
526 527 528 529 530 531 532
                if(frame_period){
                    ast->rate = 1000000;
                    ast->scale = frame_period;
                }else{
                    ast->rate = 25;
                    ast->scale = 1;
                }
533
            }
534
            avpriv_set_pts_info(st, 64, ast->scale, ast->rate);
535

536 537
            ast->cum_len=avio_rl32(pb); /* start */
            st->nb_frames = avio_rl32(pb);
538

539
            st->start_time = 0;
540 541
            avio_rl32(pb); /* buffer size */
            avio_rl32(pb); /* quality */
542 543 544 545
            if (ast->cum_len*ast->scale/ast->rate > 3600) {
                av_log(s, AV_LOG_ERROR, "crazy start time, iam scared, giving up\n");
                return AVERROR_INVALIDDATA;
            }
546
            ast->sample_size = avio_rl32(pb); /* sample ssize */
547
            ast->cum_len *= FFMAX(1, ast->sample_size);
548
//            av_log(s, AV_LOG_DEBUG, "%d %d %d %d\n", ast->rate, ast->scale, ast->start, ast->sample_size);
549

550
            switch(tag1) {
551
            case MKTAG('v', 'i', 'd', 's'):
552
                codec_type = AVMEDIA_TYPE_VIDEO;
553

554 555 556
                ast->sample_size = 0;
                break;
            case MKTAG('a', 'u', 'd', 's'):
557
                codec_type = AVMEDIA_TYPE_AUDIO;
558
                break;
559
            case MKTAG('t', 'x', 't', 's'):
560
                codec_type = AVMEDIA_TYPE_SUBTITLE;
561
                break;
Florian Echtler's avatar
Florian Echtler committed
562
            case MKTAG('d', 'a', 't', 's'):
563
                codec_type = AVMEDIA_TYPE_DATA;
Florian Echtler's avatar
Florian Echtler committed
564
                break;
565
            default:
566
                av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1);
Fabrice Bellard's avatar
Fabrice Bellard committed
567
            }
568 569
            if(ast->sample_size == 0)
                st->duration = st->nb_frames;
570
            ast->frame_offset= ast->cum_len;
571
            avio_skip(pb, size - 12 * 4);
Fabrice Bellard's avatar
Fabrice Bellard committed
572 573 574
            break;
        case MKTAG('s', 't', 'r', 'f'):
            /* stream header */
575 576
            if (!size)
                break;
577
            if (stream_index >= (unsigned)s->nb_streams || avi->dv_demux) {
578
                avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
579
            } else {
580
                uint64_t cur_pos = avio_tell(pb);
581 582
                if (cur_pos < list_end)
                    size = FFMIN(size, list_end - cur_pos);
Fabrice Bellard's avatar
Fabrice Bellard committed
583 584
                st = s->streams[stream_index];
                switch(codec_type) {
585
                case AVMEDIA_TYPE_VIDEO:
586 587 588
                    if(amv_file_format){
                        st->codec->width=avih_width;
                        st->codec->height=avih_height;
589
                        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
590
                        st->codec->codec_id = CODEC_ID_AMV;
591
                        avio_skip(pb, size);
592 593
                        break;
                    }
Peter Ross's avatar
Peter Ross committed
594
                    tag1 = ff_get_bmp_header(pb, st);
595

Michael Niedermayer's avatar
Michael Niedermayer committed
596
                    if (tag1 == MKTAG('D', 'X', 'S', 'B') || tag1 == MKTAG('D','X','S','A')) {
597
                        st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
598 599 600 601 602
                        st->codec->codec_tag = tag1;
                        st->codec->codec_id = CODEC_ID_XSUB;
                        break;
                    }

603
                    if(size > 10*4 && size<(1<<30) && size < avi->fsize){
604 605
                        st->codec->extradata_size= size - 10*4;
                        st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
606 607 608 609
                        if (!st->codec->extradata) {
                            st->codec->extradata_size= 0;
                            return AVERROR(ENOMEM);
                        }
610
                        avio_read(pb, st->codec->extradata, st->codec->extradata_size);
611
                    }
612

613
                    if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
614
                        avio_r8(pb);
615

Diego Biurrun's avatar
Diego Biurrun committed
616 617
                    /* Extract palette from extradata if bpp <= 8. */
                    /* This code assumes that extradata contains only palette. */
618
                    /* This is true for all paletted codecs implemented in FFmpeg. */
619
                    if (st->codec->extradata_size && (st->codec->bits_per_coded_sample <= 8)) {
620 621 622 623 624 625
                        int pal_size = (1 << st->codec->bits_per_coded_sample) << 2;
                        const uint8_t *pal_src;

                        pal_size = FFMIN(pal_size, st->codec->extradata_size);
                        pal_src = st->codec->extradata + st->codec->extradata_size - pal_size;
                        for (i = 0; i < pal_size/4; i++)
626
                            ast->pal[i] = 0xFF<<24 | AV_RL32(pal_src+4*i);
627
                        ast->has_pal = 1;
628 629
                    }

Fabrice Bellard's avatar
Fabrice Bellard committed
630
                    print_tag("video", tag1, 0);
631

632
                    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
633
                    st->codec->codec_tag = tag1;
634
                    st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1);
Diego Biurrun's avatar
Diego Biurrun committed
635
                    st->need_parsing = AVSTREAM_PARSE_HEADERS; // This is needed to get the pict type which is necessary for generating correct pts.
636 637 638 639 640
                    // Support "Resolution 1:1" for Avid AVI Codec
                    if(tag1 == MKTAG('A', 'V', 'R', 'n') &&
                       st->codec->extradata_size >= 31 &&
                       !memcmp(&st->codec->extradata[28], "1:1", 3))
                        st->codec->codec_id = CODEC_ID_RAWVIDEO;
641 642 643

                    if(st->codec->codec_tag==0 && st->codec->height > 0 && st->codec->extradata_size < 1U<<30){
                        st->codec->extradata_size+= 9;
644
                        st->codec->extradata= av_realloc_f(st->codec->extradata, 1, st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
645 646 647 648 649
                        if(st->codec->extradata)
                            memcpy(st->codec->extradata + st->codec->extradata_size - 9, "BottomUp", 9);
                    }
                    st->codec->height= FFABS(st->codec->height);

650
//                    avio_skip(pb, size - 5 * 4);
Fabrice Bellard's avatar
Fabrice Bellard committed
651
                    break;
652
                case AVMEDIA_TYPE_AUDIO:
653 654 655
                    ret = ff_get_wav_header(pb, st->codec, size);
                    if (ret < 0)
                        return ret;
656
                    ast->dshow_block_align= st->codec->block_align;
657
                    if(ast->sample_size && st->codec->block_align && ast->sample_size != st->codec->block_align){
658
                        av_log(s, AV_LOG_WARNING, "sample size (%d) != block align (%d)\n", ast->sample_size, st->codec->block_align);
659 660
                        ast->sample_size= st->codec->block_align;
                    }
661
                    if (size&1) /* 2-aligned (fix for Stargate SG-1 - 3x18 - Shades of Grey.avi) */
662
                        avio_skip(pb, 1);
Diego Biurrun's avatar
Diego Biurrun committed
663
                    /* Force parsing as several audio frames can be in
Diego Biurrun's avatar
Diego Biurrun committed
664
                     * one packet and timestamps refer to packet start. */
665
                    st->need_parsing = AVSTREAM_PARSE_TIMESTAMPS;
Diego Biurrun's avatar
Diego Biurrun committed
666 667 668
                    /* ADTS header is in extradata, AAC without header must be
                     * stored as exact frames. Parser not needed and it will
                     * fail. */
669
                    if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size)
670
                        st->need_parsing = AVSTREAM_PARSE_NONE;
671 672
                    /* AVI files with Xan DPCM audio (wrongly) declare PCM
                     * audio in the header but have Axan as stream_code_tag. */
673
                    if (st->codec->stream_codec_tag == AV_RL32("Axan")){
674 675
                        st->codec->codec_id  = CODEC_ID_XAN_DPCM;
                        st->codec->codec_tag = 0;
676
                        ast->dshow_block_align = 0;
677
                    }
678
                    if (amv_file_format){
679
                        st->codec->codec_id  = CODEC_ID_ADPCM_IMA_AMV;
680 681
                        ast->dshow_block_align = 0;
                    }
Fabrice Bellard's avatar
Fabrice Bellard committed
682
                    break;
683 684
                case AVMEDIA_TYPE_SUBTITLE:
                    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
685
                    st->request_probe= 1;
686
                    break;
Fabrice Bellard's avatar
Fabrice Bellard committed
687
                default:
688
                    st->codec->codec_type = AVMEDIA_TYPE_DATA;
689 690
                    st->codec->codec_id= CODEC_ID_NONE;
                    st->codec->codec_tag= 0;
691
                    avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
692 693 694 695
                    break;
                }
            }
            break;
696
        case MKTAG('s', 't', 'r', 'd'):
697
            if (stream_index >= (unsigned)s->nb_streams || s->streams[stream_index]->codec->extradata_size) {
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718
                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];

                if(size<(1<<30)){
                    st->codec->extradata_size= size;
                    st->codec->extradata= av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
                    if (!st->codec->extradata) {
                        st->codec->extradata_size= 0;
                        return AVERROR(ENOMEM);
                    }
                    avio_read(pb, st->codec->extradata, st->codec->extradata_size);
                }

                if(st->codec->extradata_size & 1) //FIXME check if the encoder really did this correctly
                    avio_r8(pb);
            }
            break;
719
        case MKTAG('i', 'n', 'd', 'x'):
720
            i= avio_tell(pb);
721
            if(pb->seekable && !(s->flags & AVFMT_FLAG_IGNIDX) && avi->use_odml &&
722
               read_braindead_odml_indx(s, 0) < 0 && (s->error_recognition & AV_EF_EXPLODE))
723
                goto fail;
724
            avio_seek(pb, i+size, SEEK_SET);
725
            break;
726 727 728 729 730
        case MKTAG('v', 'p', 'r', 'p'):
            if(stream_index < (unsigned)s->nb_streams && size > 9*4){
                AVRational active, active_aspect;

                st = s->streams[stream_index];
731 732 733 734 735 736 737 738 739 740 741
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);
                avio_rl32(pb);

                active_aspect.den= avio_rl16(pb);
                active_aspect.num= avio_rl16(pb);
                active.num       = avio_rl32(pb);
                active.den       = avio_rl32(pb);
                avio_rl32(pb); //nbFieldsPerFrame
742 743

                if(active_aspect.num && active_aspect.den && active.num && active.den){
744
                    st->sample_aspect_ratio= av_div_q(active_aspect, active);
745 746 747 748
//av_log(s, AV_LOG_ERROR, "vprp %d/%d %d/%d\n", active_aspect.num, active_aspect.den, active.num, active.den);
                }
                size -= 9*4;
            }
749
            avio_skip(pb, size);
750
            break;
751 752
        case MKTAG('s', 't', 'r', 'n'):
            if(s->nb_streams){
753
                avi_read_tag(s, s->streams[s->nb_streams-1], tag, size);
754 755
                break;
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
756
        default:
757
            if(size > 1000000){
Diego Biurrun's avatar
Diego Biurrun committed
758 759
                av_log(s, AV_LOG_ERROR, "Something went wrong during header parsing, "
                                        "I will ignore it and try to continue anyway.\n");
760 761
                if (s->error_recognition & AV_EF_EXPLODE)
                    goto fail;
762
                avi->movi_list = avio_tell(pb) - 4;
763
                avi->movi_end  = avi->fsize;
764 765
                goto end_of_header;
            }
Fabrice Bellard's avatar
Fabrice Bellard committed
766 767
            /* skip tag */
            size += (size & 1);
768
            avio_skip(pb, size);
Fabrice Bellard's avatar
Fabrice Bellard committed
769 770 771 772 773 774 775 776 777
            break;
        }
    }
 end_of_header:
    /* check stream number */
    if (stream_index != s->nb_streams - 1) {
    fail:
        return -1;
    }
778

779
    if(!avi->index_loaded && pb->seekable)
780
        avi_load_index(s);
781
    avi->index_loaded |= 1;
782
    avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS);
783 784 785 786 787
    for(i=0; i<s->nb_streams; i++){
        AVStream *st = s->streams[i];
        if(st->nb_index_entries)
            break;
    }
788 789 790 791
    // DV-in-AVI cannot be non-interleaved, if set this must be
    // a mis-detection.
    if(avi->dv_demux)
        avi->non_interleaved=0;
792 793 794 795 796
    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;
    }

797
    if(avi->non_interleaved) {
Diego Biurrun's avatar
Diego Biurrun committed
798
        av_log(s, AV_LOG_INFO, "non-interleaved AVI\n");
799
        clean_index(s);
800
    }
801

802 803
    ff_metadata_conv_ctx(s, NULL, avi_metadata_conv);
    ff_metadata_conv_ctx(s, NULL, ff_riff_info_conv);
804

Fabrice Bellard's avatar
Fabrice Bellard committed
805 806 807
    return 0;
}

808 809
static int read_gab2_sub(AVStream *st, AVPacket *pkt) {
    if (!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) {
810 811
        uint8_t desc[256];
        int score = AVPROBE_SCORE_MAX / 2, ret;
812 813 814
        AVIStream *ast = st->priv_data;
        AVInputFormat *sub_demuxer;
        AVRational time_base;
815
        AVIOContext *pb = avio_alloc_context( pkt->data + 7,
816 817
                                              pkt->size - 7,
                                              0, NULL, NULL, NULL, NULL);
818
        AVProbeData pd;
819
        unsigned int desc_len = avio_rl32(pb);
820

821 822
        if (desc_len > pb->buf_end - pb->buf_ptr)
            goto error;
823

824
        ret = avio_get_str16le(pb, desc_len, desc, sizeof(desc));
825
        avio_skip(pb, desc_len - ret);
826
        if (*desc)
827
            av_dict_set(&st->metadata, "title", desc, 0);
828

829 830
        avio_rl16(pb);   /* flags? */
        avio_rl32(pb);   /* data size */
831

832
        pd = (AVProbeData) { .buf = pb->buf_ptr, .buf_size = pb->buf_end - pb->buf_ptr };
833
        if (!(sub_demuxer = av_probe_input_format2(&pd, 1, &score)))
834
            goto error;
835

836 837 838 839 840
        if (!(ast->sub_ctx = avformat_alloc_context()))
            goto error;

        ast->sub_ctx->pb      = pb;
        if (!avformat_open_input(&ast->sub_ctx, "", sub_demuxer, NULL)) {
841 842 843 844
            av_read_packet(ast->sub_ctx, &ast->sub_pkt);
            *st->codec = *ast->sub_ctx->streams[0]->codec;
            ast->sub_ctx->streams[0]->codec->extradata = NULL;
            time_base = ast->sub_ctx->streams[0]->time_base;
845
            avpriv_set_pts_info(st, 64, time_base.num, time_base.den);
846 847 848 849
        }
        ast->sub_buffer = pkt->data;
        memset(pkt, 0, sizeof(*pkt));
        return 1;
850 851
error:
        av_freep(&pb);
852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869
    }
    return 0;
}

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

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

    for (i=0; i<s->nb_streams; i++) {
        st  = s->streams[i];
        ast = st->priv_data;
870
        if (st->discard < AVDISCARD_ALL && ast && ast->sub_pkt.data) {
871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888
            ts = av_rescale_q(ast->sub_pkt.dts, st->time_base, AV_TIME_BASE_Q);
            if (ts <= next_ts && ts < ts_min) {
                ts_min = ts;
                sub_st = st;
            }
        }
    }

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

889 890 891 892 893 894 895 896 897
static int get_stream_idx(int *d){
    if(    d[0] >= '0' && d[0] <= '9'
        && d[1] >= '0' && d[1] <= '9'){
        return (d[0] - '0') * 10 + (d[1] - '0');
    }else{
        return 100; //invalid stream ID
    }
}

898
static int avi_sync(AVFormatContext *s, int exit_early)
Fabrice Bellard's avatar
Fabrice Bellard committed
899 900
{
    AVIContext *avi = s->priv_data;
901
    AVIOContext *pb = s->pb;
902 903
    int n;
    unsigned int d[8];
904
    unsigned int size;
905
    int64_t i, sync;
906 907

start_sync:
908
    memset(d, -1, sizeof(d));
909
    for(i=sync=avio_tell(pb); !url_feof(pb); i++) {
910 911 912 913 914 915 916 917 918 919
        int j;

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

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

        n= get_stream_idx(d+2);
//av_log(s, AV_LOG_DEBUG, "%X %X %X %X %X %X %X %X %"PRId64" %d %d\n", d[0], d[1], d[2], d[3], d[4], d[5], d[6], d[7], i, size, n);
920
        if(i + (uint64_t)size > avi->fsize || d[0] > 127)
921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978
            continue;

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

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

        n= get_stream_idx(d);

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

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

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

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


            if(   (st->discard >= AVDISCARD_DEFAULT && size==0)
               /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering
               || st->discard >= AVDISCARD_ALL){
979 980 981
                if (!exit_early) {
                    ast->frame_offset += get_duration(ast, size);
                }
982 983 984 985 986 987 988 989 990 991 992
                avio_skip(pb, size);
                goto start_sync;
            }

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

                avio_rl16(pb); //flags

                for (; k <= last; k++)
993
                    ast->pal[k] = 0xFF<<24 | avio_rb32(pb)>>8;// b + (g << 8) + (r << 16);
994 995 996 997 998 999 1000
                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')*/) {

1001 1002
                if (exit_early)
                    return 0;
1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
//av_log(s, AV_LOG_DEBUG, "OK\n");
                if(d[2]*256+d[3] == ast->prefix)
                    ast->prefix_count++;
                else{
                    ast->prefix= d[2]*256+d[3];
                    ast->prefix_count= 0;
                }

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

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

1026 1027
    if(pb->error)
        return pb->error;
1028 1029 1030 1031 1032 1033 1034 1035
    return AVERROR_EOF;
}

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

1038
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1039
        int size = avpriv_dv_get_packet(avi->dv_demux, pkt);
1040 1041
        if (size >= 0)
            return size;
1042
    }
1043

1044
    if(avi->non_interleaved){
1045
        int best_stream_index = 0;
1046 1047 1048 1049
        AVStream *best_st= NULL;
        AVIStream *best_ast;
        int64_t best_ts= INT64_MAX;
        int i;
1050

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

1057 1058 1059
            if(!st->nb_index_entries)
                continue;

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

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

1066
//            av_log(s, AV_LOG_DEBUG, "%"PRId64" %d/%d %"PRId64"\n", ts, st->time_base.num, st->time_base.den, ast->frame_offset);
1067
            if(ts < best_ts){
1068 1069 1070 1071 1072
                best_ts= ts;
                best_st= st;
                best_stream_index= i;
            }
        }
1073
        if(!best_st)
1074
            return AVERROR_EOF;
1075

1076
        best_ast = best_st->priv_data;
1077
        best_ts = best_ast->frame_offset;
1078 1079
        if(best_ast->remaining)
            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
1080
        else{
1081
            i= av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY);
1082
            if(i>=0)
1083
                best_ast->frame_offset= best_st->index_entries[i].timestamp;
1084
        }
1085

1086
//        av_log(s, AV_LOG_DEBUG, "%d\n", i);
1087 1088
        if(i>=0){
            int64_t pos= best_st->index_entries[i].pos;
1089
            pos += best_ast->packet_size - best_ast->remaining;
1090 1091
            if(avio_seek(s->pb, pos + 8, SEEK_SET) < 0)
              return AVERROR_EOF;
1092
//        av_log(s, AV_LOG_DEBUG, "pos=%"PRId64"\n", pos);
1093

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

1096 1097
            avi->stream_index= best_stream_index;
            if(!best_ast->remaining)
1098
                best_ast->packet_size=
1099
                best_ast->remaining= best_st->index_entries[i].size;
1100
        }
1101 1102
        else
          return AVERROR_EOF;
1103
    }
1104

1105
resync:
1106 1107 1108
    if(avi->stream_index >= 0){
        AVStream *st= s->streams[ avi->stream_index ];
        AVIStream *ast= st->priv_data;
1109
        int size, err;
1110

1111 1112 1113
        if(get_subtitle_pkt(s, st, pkt))
            return 0;

1114
        if(ast->sample_size <= 1) // minorityreport.AVI block_align=1024 sample_size=1 IMA-ADPCM
1115
            size= INT_MAX;
1116
        else if(ast->sample_size < 32)
1117 1118
            // arbitrary multiplier to avoid tiny packets for raw PCM data
            size= 1024*ast->sample_size;
1119 1120 1121 1122 1123
        else
            size= ast->sample_size;

        if(size > ast->remaining)
            size= ast->remaining;
1124
        avi->last_pkt_pos= avio_tell(pb);
1125 1126 1127
        err= av_get_packet(pb, pkt, size);
        if(err<0)
            return err;
1128

1129
        if(ast->has_pal && pkt->data && pkt->size<(unsigned)INT_MAX/2){
1130 1131 1132 1133 1134 1135 1136 1137
            uint8_t *pal;
            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
            if(!pal){
                av_log(s, AV_LOG_ERROR, "Failed to allocate data for palette\n");
            }else{
                memcpy(pal, ast->pal, AVPALETTE_SIZE);
                ast->has_pal = 0;
            }
1138 1139
        }

1140
        if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1141
            dstr = pkt->destruct;
1142
            size = avpriv_dv_produce_packet(avi->dv_demux, pkt,
1143
                                    pkt->data, pkt->size, pkt->pos);
1144
            pkt->destruct = dstr;
1145
            pkt->flags |= AV_PKT_FLAG_KEY;
1146 1147
            if (size < 0)
                av_free_packet(pkt);
1148 1149 1150 1151 1152 1153
        } else if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE
                   && !st->codec->codec_tag && read_gab2_sub(st, pkt)) {
            ast->frame_offset++;
            avi->stream_index = -1;
            ast->remaining = 0;
            goto resync;
1154
        } else {
Diego Biurrun's avatar
Diego Biurrun committed
1155
            /* XXX: How to handle B-frames in AVI? */
1156 1157 1158 1159
            pkt->dts = ast->frame_offset;
//                pkt->dts += ast->start;
            if(ast->sample_size)
                pkt->dts /= ast->sample_size;
1160
//av_log(s, AV_LOG_DEBUG, "dts:%"PRId64" offset:%"PRId64" %d/%d smpl_siz:%d base:%d st:%d size:%d\n", pkt->dts, ast->frame_offset, ast->scale, ast->rate, ast->sample_size, AV_TIME_BASE, avi->stream_index, size);
1161 1162
            pkt->stream_index = avi->stream_index;

1163
            if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
Michael Niedermayer's avatar
Michael Niedermayer committed
1164 1165
                AVIndexEntry *e;
                int index;
1166
                assert(st->index_entries);
1167

1168
                index= av_index_search_timestamp(st, ast->frame_offset, 0);
Michael Niedermayer's avatar
Michael Niedermayer committed
1169
                e= &st->index_entries[index];
1170

Michael Niedermayer's avatar
Michael Niedermayer committed
1171
                if(index >= 0 && e->timestamp == ast->frame_offset){
1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188
                    if (index == st->nb_index_entries-1){
                        int key=1;
                        int i;
                        uint32_t state=-1;
                        for(i=0; i<FFMIN(size,256); i++){
                            if(st->codec->codec_id == CODEC_ID_MPEG4){
                                if(state == 0x1B6){
                                    key= !(pkt->data[i]&0xC0);
                                    break;
                                }
                            }else
                                break;
                            state= (state<<8) + pkt->data[i];
                        }
                        if(!key)
                            e->flags &= ~AVINDEX_KEYFRAME;
                    }
Michael Niedermayer's avatar
Michael Niedermayer committed
1189
                    if (e->flags & AVINDEX_KEYFRAME)
1190
                        pkt->flags |= AV_PKT_FLAG_KEY;
Michael Niedermayer's avatar
Michael Niedermayer committed
1191
                }
1192
            } else {
1193
                pkt->flags |= AV_PKT_FLAG_KEY;
1194
            }
1195
            ast->frame_offset += get_duration(ast, pkt->size);
1196 1197 1198 1199 1200 1201 1202
        }
        ast->remaining -= size;
        if(!ast->remaining){
            avi->stream_index= -1;
            ast->packet_size= 0;
        }

1203
        if(!avi->non_interleaved && pkt->pos >= 0 && ast->seek_pos > pkt->pos){
1204 1205 1206 1207 1208
            av_free_packet(pkt);
            goto resync;
        }
        ast->seek_pos= 0;

1209
        if(!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1){
1210 1211 1212 1213 1214 1215 1216 1217 1218
            int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);

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

1219 1220 1221
        return size;
    }

1222
    if ((err = avi_sync(s, 0)) < 0)
1223 1224
        return err;
    goto resync;
Fabrice Bellard's avatar
Fabrice Bellard committed
1225 1226
}

Diego Biurrun's avatar
Diego Biurrun committed
1227 1228
/* XXX: We make the implicit supposition that the positions are sorted
   for each stream. */
Fabrice Bellard's avatar
Fabrice Bellard committed
1229 1230
static int avi_read_idx1(AVFormatContext *s, int size)
{
1231
    AVIContext *avi = s->priv_data;
1232
    AVIOContext *pb = s->pb;
Fabrice Bellard's avatar
Fabrice Bellard committed
1233 1234 1235
    int nb_index_entries, i;
    AVStream *st;
    AVIStream *ast;
1236
    unsigned int index, tag, flags, pos, len, first_packet = 1;
1237
    unsigned last_pos= -1;
1238
    int64_t idx1_pos, first_packet_pos = 0, data_offset = 0;
1239

Fabrice Bellard's avatar
Fabrice Bellard committed
1240 1241 1242 1243
    nb_index_entries = size / 16;
    if (nb_index_entries <= 0)
        return -1;

1244 1245 1246 1247 1248 1249 1250 1251
    idx1_pos = avio_tell(pb);
    avio_seek(pb, avi->movi_list+4, SEEK_SET);
    if (avi_sync(s, 1) == 0) {
        first_packet_pos = avio_tell(pb) - 8;
    }
    avi->stream_index = -1;
    avio_seek(pb, idx1_pos, SEEK_SET);

Diego Biurrun's avatar
Diego Biurrun committed
1252
    /* Read the entries and sort them in each stream component. */
Fabrice Bellard's avatar
Fabrice Bellard committed
1253
    for(i = 0; i < nb_index_entries; i++) {
1254 1255 1256
        if(url_feof(pb))
            return -1;

1257 1258 1259 1260
        tag = avio_rl32(pb);
        flags = avio_rl32(pb);
        pos = avio_rl32(pb);
        len = avio_rl32(pb);
1261 1262
        av_dlog(s, "%d: tag=0x%x flags=0x%x pos=0x%x len=%d/",
                i, tag, flags, pos, len);
1263

Fabrice Bellard's avatar
Fabrice Bellard committed
1264 1265 1266 1267 1268 1269
        index = ((tag & 0xff) - '0') * 10;
        index += ((tag >> 8) & 0xff) - '0';
        if (index >= s->nb_streams)
            continue;
        st = s->streams[index];
        ast = st->priv_data;
1270

1271 1272 1273 1274 1275 1276
        if(first_packet && first_packet_pos && len) {
            data_offset = first_packet_pos - pos;
            first_packet = 0;
        }
        pos += data_offset;

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

1279

1280 1281
        if(last_pos == pos)
            avi->non_interleaved= 1;
1282
        else if(len || !ast->sample_size)
1283
            av_add_index_entry(st, pos, ast->cum_len, len, 0, (flags&AVIIF_INDEX) ? AVINDEX_KEYFRAME : 0);
1284
        ast->cum_len += get_duration(ast, len);
1285
        last_pos= pos;
Fabrice Bellard's avatar
Fabrice Bellard committed
1286 1287 1288 1289
    }
    return 0;
}

1290 1291 1292 1293
static int guess_ni_flag(AVFormatContext *s){
    int i;
    int64_t last_start=0;
    int64_t first_end= INT64_MAX;
1294
    int64_t oldpos= avio_tell(s->pb);
1295

1296 1297 1298
    for(i=0; i<s->nb_streams; i++){
        AVStream *st = s->streams[i];
        int n= st->nb_index_entries;
1299
        unsigned int size;
1300 1301 1302 1303

        if(n <= 0)
            continue;

1304 1305
        if(n >= 2){
            int64_t pos= st->index_entries[0].pos;
1306
            avio_seek(s->pb, pos + 4, SEEK_SET);
1307
            size= avio_rl32(s->pb);
1308 1309 1310 1311
            if(pos + size > st->index_entries[1].pos)
                last_start= INT64_MAX;
        }

1312 1313 1314 1315 1316
        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;
    }
1317
    avio_seek(s->pb, oldpos, SEEK_SET);
1318 1319 1320
    return last_start > first_end;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
1321 1322 1323
static int avi_load_index(AVFormatContext *s)
{
    AVIContext *avi = s->priv_data;
1324
    AVIOContext *pb = s->pb;
Fabrice Bellard's avatar
Fabrice Bellard committed
1325
    uint32_t tag, size;
1326
    int64_t pos= avio_tell(pb);
1327
    int ret = -1;
1328

1329
    if (avio_seek(pb, avi->movi_end, SEEK_SET) < 0)
1330
        goto the_end; // maybe truncated file
1331
    av_dlog(s, "movi_end=0x%"PRIx64"\n", avi->movi_end);
Fabrice Bellard's avatar
Fabrice Bellard committed
1332 1333 1334
    for(;;) {
        if (url_feof(pb))
            break;
1335 1336
        tag = avio_rl32(pb);
        size = avio_rl32(pb);
1337 1338 1339 1340 1341 1342
        av_dlog(s, "tag=%c%c%c%c size=0x%x\n",
                 tag        & 0xff,
                (tag >>  8) & 0xff,
                (tag >> 16) & 0xff,
                (tag >> 24) & 0xff,
                size);
1343 1344 1345

        if (tag == MKTAG('i', 'd', 'x', '1') &&
            avi_read_idx1(s, size) >= 0) {
1346
            avi->index_loaded=2;
1347
            ret = 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
1348 1349
            break;
        }
1350 1351 1352 1353

        size += (size & 1);
        if (avio_skip(pb, size) < 0)
            break; // something is wrong here
Fabrice Bellard's avatar
Fabrice Bellard committed
1354 1355
    }
 the_end:
1356
    avio_seek(pb, pos, SEEK_SET);
1357
    return ret;
Fabrice Bellard's avatar
Fabrice Bellard committed
1358 1359
}

1360 1361 1362 1363 1364 1365 1366 1367 1368 1369
static void seek_subtitle(AVStream *st, AVStream *st2, int64_t timestamp)
{
    AVIStream *ast2 = st2->priv_data;
    int64_t ts2 = av_rescale_q(timestamp, st->time_base, st2->time_base);
    av_free_packet(&ast2->sub_pkt);
    if (avformat_seek_file(ast2->sub_ctx, 0, INT64_MIN, ts2, ts2, 0) >= 0 ||
        avformat_seek_file(ast2->sub_ctx, 0, ts2, ts2, INT64_MAX, 0) >= 0)
        av_read_packet(ast2->sub_ctx, &ast2->sub_pkt);
}

1370
static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Fabrice Bellard's avatar
Fabrice Bellard committed
1371 1372 1373
{
    AVIContext *avi = s->priv_data;
    AVStream *st;
1374
    int i, index;
1375
    int64_t pos, pos_min;
1376
    AVIStream *ast;
Fabrice Bellard's avatar
Fabrice Bellard committed
1377 1378 1379 1380

    if (!avi->index_loaded) {
        /* we only load the index on demand */
        avi_load_index(s);
1381
        avi->index_loaded |= 1;
Fabrice Bellard's avatar
Fabrice Bellard committed
1382
    }
1383
    assert(stream_index>= 0);
Fabrice Bellard's avatar
Fabrice Bellard committed
1384 1385

    st = s->streams[stream_index];
1386 1387
    ast= st->priv_data;
    index= av_index_search_timestamp(st, timestamp * FFMAX(ast->sample_size, 1), flags);
1388 1389
    if (index<0) {
        if (st->nb_index_entries > 0)
1390
            av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n",
1391 1392 1393
                   timestamp * FFMAX(ast->sample_size, 1),
                   st->index_entries[0].timestamp,
                   st->index_entries[st->nb_index_entries - 1].timestamp);
Fabrice Bellard's avatar
Fabrice Bellard committed
1394
        return -1;
1395
    }
1396

Fabrice Bellard's avatar
Fabrice Bellard committed
1397
    /* find the position */
1398
    pos = st->index_entries[index].pos;
1399
    timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1);
1400

1401
//    av_log(s, AV_LOG_DEBUG, "XX %"PRId64" %d %"PRId64"\n", timestamp, index, st->index_entries[index].timestamp);
Fabrice Bellard's avatar
Fabrice Bellard committed
1402

1403
    if (CONFIG_DV_DEMUXER && avi->dv_demux) {
1404
        /* One and only one real stream for DV in AVI, and it has video  */
1405
        /* offsets. Calling with other stream indexes should have failed */
1406 1407 1408
        /* the av_index_search_timestamp call above.                     */
        assert(stream_index == 0);

1409 1410 1411
        if(avio_seek(s->pb, pos, SEEK_SET) < 0)
            return -1;

1412
        /* Feed the DV video stream version of the timestamp to the */
Diego Biurrun's avatar
Diego Biurrun committed
1413
        /* DV demux so it can synthesize correct timestamps.        */
1414
        ff_dv_offset_reset(avi->dv_demux, timestamp);
1415 1416 1417 1418 1419

        avi->stream_index= -1;
        return 0;
    }

1420
    pos_min= pos;
Fabrice Bellard's avatar
Fabrice Bellard committed
1421
    for(i = 0; i < s->nb_streams; i++) {
1422 1423
        AVStream *st2 = s->streams[i];
        AVIStream *ast2 = st2->priv_data;
1424 1425 1426 1427

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

1428 1429 1430 1431 1432
        if (ast2->sub_ctx) {
            seek_subtitle(st, st2, timestamp);
            continue;
        }

1433 1434
        if (st2->nb_index_entries <= 0)
            continue;
1435

1436
//        assert(st2->codec->block_align);
1437
        assert((int64_t)st2->time_base.num*ast2->rate == (int64_t)st2->time_base.den*ast2->scale);
1438
        index = av_index_search_timestamp(
1439
                st2,
1440
                av_rescale_q(timestamp, st->time_base, st2->time_base) * FFMAX(ast2->sample_size, 1),
1441
                flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
1442 1443
        if(index<0)
            index=0;
1444 1445
        ast2->seek_pos= st2->index_entries[index].pos;
        pos_min= FFMIN(pos_min,ast2->seek_pos);
1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456
    }
    for(i = 0; i < s->nb_streams; i++) {
        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),
1457
                flags | AVSEEK_FLAG_BACKWARD | (st2->codec->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0));
1458 1459
        if(index<0)
            index=0;
1460
        while(!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min)
1461
            index--;
1462
        ast2->frame_offset = st2->index_entries[index].timestamp;
Fabrice Bellard's avatar
Fabrice Bellard committed
1463
    }
1464

Fabrice Bellard's avatar
Fabrice Bellard committed
1465
    /* do the seek */
1466 1467
    if (avio_seek(s->pb, pos_min, SEEK_SET) < 0) {
        av_log(s, AV_LOG_ERROR, "Seek failed\n");
1468
        return -1;
1469
    }
1470
    avi->stream_index= -1;
1471
    avi->dts_max= INT_MIN;
Fabrice Bellard's avatar
Fabrice Bellard committed
1472 1473 1474
    return 0;
}

1475
static int avi_read_close(AVFormatContext *s)
Fabrice Bellard's avatar
Fabrice Bellard committed
1476
{
Michael Niedermayer's avatar
Michael Niedermayer committed
1477 1478 1479 1480 1481
    int i;
    AVIContext *avi = s->priv_data;

    for(i=0;i<s->nb_streams;i++) {
        AVStream *st = s->streams[i];
1482
        AVIStream *ast = st->priv_data;
1483
        if (ast) {
1484 1485
            if (ast->sub_ctx) {
                av_freep(&ast->sub_ctx->pb);
1486
                avformat_close_input(&ast->sub_ctx);
1487 1488 1489
            }
            av_free(ast->sub_buffer);
            av_free_packet(&ast->sub_pkt);
1490
        }
Michael Niedermayer's avatar
Michael Niedermayer committed
1491 1492
    }

1493
    av_free(avi->dv_demux);
1494

Fabrice Bellard's avatar
Fabrice Bellard committed
1495 1496 1497 1498 1499
    return 0;
}

static int avi_probe(AVProbeData *p)
{
1500 1501
    int i;

Fabrice Bellard's avatar
Fabrice Bellard committed
1502
    /* check file header */
1503 1504 1505 1506 1507 1508
    for(i=0; avi_headers[i][0]; i++)
        if(!memcmp(p->buf  , avi_headers[i]  , 4) &&
           !memcmp(p->buf+8, avi_headers[i]+4, 4))
            return AVPROBE_SCORE_MAX;

    return 0;
Fabrice Bellard's avatar
Fabrice Bellard committed
1509 1510
}

1511
AVInputFormat ff_avi_demuxer = {
1512 1513 1514 1515 1516 1517 1518 1519
    .name           = "avi",
    .long_name      = NULL_IF_CONFIG_SMALL("AVI format"),
    .priv_data_size = sizeof(AVIContext),
    .read_probe     = avi_probe,
    .read_header    = avi_read_header,
    .read_packet    = avi_read_packet,
    .read_close     = avi_read_close,
    .read_seek      = avi_read_seek,
1520
    .priv_class = &demuxer_class,
Fabrice Bellard's avatar
Fabrice Bellard committed
1521
};