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

#include <limits.h>
24

B
Baptiste Coudurier 已提交
25
//#define DEBUG
26
//#define MOV_EXPORT_ALL_METADATA
27

28
#include "libavutil/intreadwrite.h"
29
#include "libavutil/intfloat.h"
30
#include "libavutil/mathematics.h"
31
#include "libavutil/avstring.h"
32
#include "libavutil/dict.h"
33
#include "avformat.h"
34
#include "internal.h"
35
#include "avio_internal.h"
36
#include "riff.h"
37
#include "isom.h"
38
#include "libavcodec/get_bits.h"
R
Raivo Hool 已提交
39
#include "id3v1.h"
40
#include "mov_chan.h"
41

42
#if CONFIG_ZLIB
43 44 45
#include <zlib.h>
#endif

46 47
/*
 * First version by Francois Revol revol@free.fr
48
 * Seek function by Gael Chardon gael.dev@4now.net
49 50
 */

51 52
#include "qtpalette.h"

G
Gael Chardon 已提交
53

54 55 56
#undef NDEBUG
#include <assert.h>

57 58 59
/* those functions parse an atom */
/* links atom IDs to parse functions */
typedef struct MOVParseTableEntry {
60
    uint32_t type;
61
    int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
62 63
} MOVParseTableEntry;

64 65
static const MOVParseTableEntry mov_default_parse_table[];

66 67
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
                                             unsigned len, const char *key)
B
Baptiste Coudurier 已提交
68 69 70
{
    char buf[16];

71
    short current, total;
72
    avio_rb16(pb); // unknown
73 74 75 76 77 78 79
    current = avio_rb16(pb);
    total = avio_rb16(pb);
    if (!total)
        snprintf(buf, sizeof(buf), "%d", current);
    else
        snprintf(buf, sizeof(buf), "%d/%d", current, total);
    av_dict_set(&c->fc->metadata, key, buf, 0);
B
Baptiste Coudurier 已提交
80 81 82 83

    return 0;
}

84 85
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
                                            unsigned len, const char *key)
86
{
87
    char buf[16];
88

89 90 91 92
    /* bypass padding bytes */
    avio_r8(pb);
    avio_r8(pb);
    avio_r8(pb);
93

94
    snprintf(buf, sizeof(buf), "%d", avio_r8(pb));
95
    av_dict_set(&c->fc->metadata, key, buf, 0);
96

97
    return 0;
98 99
}

100 101
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
                                        unsigned len, const char *key)
102
{
103
    char buf[16];
104

105
    snprintf(buf, sizeof(buf), "%d", avio_r8(pb));
106
    av_dict_set(&c->fc->metadata, key, buf, 0);
107

108
    return 0;
109 110
}

R
Raivo Hool 已提交
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
                             unsigned len, const char *key)
{
    short genre;
    char buf[20];

    avio_r8(pb); // unknown

    genre = avio_r8(pb);
    if (genre < 1 || genre > ID3v1_GENRE_MAX)
        return 0;
    snprintf(buf, sizeof(buf), "%s", ff_id3v1_genre_str[genre-1]);
    av_dict_set(&c->fc->metadata, key, buf, 0);

    return 0;
}

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
static const uint32_t mac_to_unicode[128] = {
    0x00C4,0x00C5,0x00C7,0x00C9,0x00D1,0x00D6,0x00DC,0x00E1,
    0x00E0,0x00E2,0x00E4,0x00E3,0x00E5,0x00E7,0x00E9,0x00E8,
    0x00EA,0x00EB,0x00ED,0x00EC,0x00EE,0x00EF,0x00F1,0x00F3,
    0x00F2,0x00F4,0x00F6,0x00F5,0x00FA,0x00F9,0x00FB,0x00FC,
    0x2020,0x00B0,0x00A2,0x00A3,0x00A7,0x2022,0x00B6,0x00DF,
    0x00AE,0x00A9,0x2122,0x00B4,0x00A8,0x2260,0x00C6,0x00D8,
    0x221E,0x00B1,0x2264,0x2265,0x00A5,0x00B5,0x2202,0x2211,
    0x220F,0x03C0,0x222B,0x00AA,0x00BA,0x03A9,0x00E6,0x00F8,
    0x00BF,0x00A1,0x00AC,0x221A,0x0192,0x2248,0x2206,0x00AB,
    0x00BB,0x2026,0x00A0,0x00C0,0x00C3,0x00D5,0x0152,0x0153,
    0x2013,0x2014,0x201C,0x201D,0x2018,0x2019,0x00F7,0x25CA,
    0x00FF,0x0178,0x2044,0x20AC,0x2039,0x203A,0xFB01,0xFB02,
    0x2021,0x00B7,0x201A,0x201E,0x2030,0x00C2,0x00CA,0x00C1,
    0x00CB,0x00C8,0x00CD,0x00CE,0x00CF,0x00CC,0x00D3,0x00D4,
    0xF8FF,0x00D2,0x00DA,0x00DB,0x00D9,0x0131,0x02C6,0x02DC,
    0x00AF,0x02D8,0x02D9,0x02DA,0x00B8,0x02DD,0x02DB,0x02C7,
};

147
static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
148 149 150 151 152 153 154
                               char *dst, int dstlen)
{
    char *p = dst;
    char *end = dst+dstlen-1;
    int i;

    for (i = 0; i < len; i++) {
155
        uint8_t t, c = avio_r8(pb);
156 157 158 159 160 161 162 163 164
        if (c < 0x80 && p < end)
            *p++ = c;
        else
            PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
    }
    *p = 0;
    return p - dst;
}

165
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
166 167 168 169 170 171
{
#ifdef MOV_EXPORT_ALL_METADATA
    char tmp_key[5];
#endif
    char str[1024], key2[16], language[4] = {0};
    const char *key = NULL;
172 173
    uint16_t str_size, langcode = 0;
    uint32_t data_type = 0;
174
    int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
175 176 177 178

    switch (atom.type) {
    case MKTAG(0xa9,'n','a','m'): key = "title";     break;
    case MKTAG(0xa9,'a','u','t'):
179
    case MKTAG(0xa9,'A','R','T'): key = "artist";    break;
R
Raivo Hool 已提交
180
    case MKTAG( 'a','A','R','T'): key = "album_artist";    break;
181
    case MKTAG(0xa9,'w','r','t'): key = "composer";  break;
182
    case MKTAG( 'c','p','r','t'):
183 184 185 186
    case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
    case MKTAG(0xa9,'c','m','t'):
    case MKTAG(0xa9,'i','n','f'): key = "comment";   break;
    case MKTAG(0xa9,'a','l','b'): key = "album";     break;
187
    case MKTAG(0xa9,'d','a','y'): key = "date";      break;
188
    case MKTAG(0xa9,'g','e','n'): key = "genre";     break;
R
Raivo Hool 已提交
189 190
    case MKTAG( 'g','n','r','e'): key = "genre";
        parse = mov_metadata_gnre; break;
191
    case MKTAG(0xa9,'t','o','o'):
192
    case MKTAG(0xa9,'s','w','r'): key = "encoder";   break;
193
    case MKTAG(0xa9,'e','n','c'): key = "encoder";   break;
194 195 196 197 198
    case MKTAG( 'd','e','s','c'): key = "description";break;
    case MKTAG( 'l','d','e','s'): key = "synopsis";  break;
    case MKTAG( 't','v','s','h'): key = "show";      break;
    case MKTAG( 't','v','e','n'): key = "episode_id";break;
    case MKTAG( 't','v','n','n'): key = "network";   break;
B
Baptiste Coudurier 已提交
199
    case MKTAG( 't','r','k','n'): key = "track";
200 201 202
        parse = mov_metadata_track_or_disc_number; break;
    case MKTAG( 'd','i','s','k'): key = "disc";
        parse = mov_metadata_track_or_disc_number; break;
203
    case MKTAG( 't','v','e','s'): key = "episode_sort";
204
        parse = mov_metadata_int8_bypass_padding; break;
205
    case MKTAG( 't','v','s','n'): key = "season_number";
206
        parse = mov_metadata_int8_bypass_padding; break;
207
    case MKTAG( 's','t','i','k'): key = "media_type";
208
        parse = mov_metadata_int8_no_padding; break;
209 210 211 212
    case MKTAG( 'h','d','v','d'): key = "hd_video";
        parse = mov_metadata_int8_no_padding; break;
    case MKTAG( 'p','g','a','p'): key = "gapless_playback";
        parse = mov_metadata_int8_no_padding; break;
213 214 215
    }

    if (c->itunes_metadata && atom.size > 8) {
216 217
        int data_size = avio_rb32(pb);
        int tag = avio_rl32(pb);
218
        if (tag == MKTAG('d','a','t','a')) {
219 220
            data_type = avio_rb32(pb); // type
            avio_rb32(pb); // unknown
221 222 223 224
            str_size = data_size - 16;
            atom.size -= 16;
        } else return 0;
    } else if (atom.size > 4 && key && !c->itunes_metadata) {
225 226
        str_size = avio_rb16(pb); // string length
        langcode = avio_rb16(pb);
227
        ff_mov_lang_to_iso639(langcode, language);
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
        atom.size -= 4;
    } else
        str_size = atom.size;

#ifdef MOV_EXPORT_ALL_METADATA
    if (!key) {
        snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
        key = tmp_key;
    }
#endif

    if (!key)
        return 0;
    if (atom.size < 0)
        return -1;

    str_size = FFMIN3(sizeof(str)-1, str_size, atom.size);
B
Baptiste Coudurier 已提交
245 246

    if (parse)
247
        parse(c, pb, str_size, key);
B
Baptiste Coudurier 已提交
248
    else {
249 250 251
        if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded
            mov_read_mac_string(c, pb, str_size, str, sizeof(str));
        } else {
252
            avio_read(pb, str, str_size);
253 254
            str[str_size] = 0;
        }
255
        av_dict_set(&c->fc->metadata, key, str, 0);
B
Baptiste Coudurier 已提交
256 257
        if (*language && strcmp(language, "und")) {
            snprintf(key2, sizeof(key2), "%s-%s", key, language);
258
            av_dict_set(&c->fc->metadata, key2, str, 0);
B
Baptiste Coudurier 已提交
259
        }
B
Baptiste Coudurier 已提交
260
    }
261 262 263
    av_dlog(c->fc, "lang \"%3s\" ", language);
    av_dlog(c->fc, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n",
            key, str, (char*)&atom.type, str_size, atom.size);
264 265 266

    return 0;
}
267

268
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
D
David Conrad 已提交
269 270
{
    int64_t start;
D
David Conrad 已提交
271
    int i, nb_chapters, str_len, version;
D
David Conrad 已提交
272 273 274 275 276
    char str[256+1];

    if ((atom.size -= 5) < 0)
        return 0;

277 278
    version = avio_r8(pb);
    avio_rb24(pb);
D
David Conrad 已提交
279
    if (version)
280 281
        avio_rb32(pb); // ???
    nb_chapters = avio_r8(pb);
D
David Conrad 已提交
282 283 284 285 286

    for (i = 0; i < nb_chapters; i++) {
        if (atom.size < 9)
            return 0;

287 288
        start = avio_rb64(pb);
        str_len = avio_r8(pb);
D
David Conrad 已提交
289 290 291 292

        if ((atom.size -= 9+str_len) < 0)
            return 0;

293
        avio_read(pb, str, str_len);
D
David Conrad 已提交
294
        str[str_len] = 0;
295
        avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
D
David Conrad 已提交
296 297 298 299
    }
    return 0;
}

300
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
301
{
302
    int64_t total_size = 0;
303
    MOVAtom a;
304
    int i;
305

306
    if (atom.size < 0)
B
Baptiste Coudurier 已提交
307
        atom.size = INT64_MAX;
A
Anton Khirnov 已提交
308
    while (total_size + 8 < atom.size && !pb->eof_reached) {
309
        int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
310
        a.size = atom.size;
B
Baptiste Coudurier 已提交
311
        a.type=0;
312
        if (atom.size >= 8) {
313 314
            a.size = avio_rb32(pb);
            a.type = avio_rl32(pb);
315
        }
L
Luca Barbato 已提交
316
        av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
317
                a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size);
318
        total_size += 8;
319
        if (a.size == 1) { /* 64 bit extended size */
320
            a.size = avio_rb64(pb) - 8;
321
            total_size += 8;
322
        }
323 324 325
        if (a.size == 0) {
            a.size = atom.size - total_size;
            if (a.size <= 8)
326
                break;
327 328
        }
        a.size -= 8;
329
        if (a.size < 0)
330
            break;
B
Baptiste Coudurier 已提交
331
        a.size = FFMIN(a.size, atom.size - total_size);
332

333 334 335 336 337
        for (i = 0; mov_default_parse_table[i].type; i++)
            if (mov_default_parse_table[i].type == a.type) {
                parse = mov_default_parse_table[i].parse;
                break;
            }
338

339 340 341 342 343 344
        // container is user data
        if (!parse && (atom.type == MKTAG('u','d','t','a') ||
                       atom.type == MKTAG('i','l','s','t')))
            parse = mov_read_udta_string;

        if (!parse) { /* skip leaf atoms data */
345
            avio_skip(pb, a.size);
346
        } else {
347
            int64_t start_pos = avio_tell(pb);
348
            int64_t left;
349 350 351
            int err = parse(c, pb, a);
            if (err < 0)
                return err;
352
            if (c->found_moov && c->found_mdat &&
353
                (!pb->seekable || start_pos + a.size == avio_size(pb)))
354
                return 0;
355
            left = a.size - avio_tell(pb) + start_pos;
356
            if (left > 0) /* skip garbage at atom end */
357
                avio_skip(pb, left);
358
        }
359

360
        total_size += a.size;
361 362
    }

363
    if (total_size < atom.size && atom.size < 0x7ffff)
364
        avio_skip(pb, atom.size - total_size);
365

366
    return 0;
367 368
}

369
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
370
{
371 372
    AVStream *st;
    MOVStreamContext *sc;
373 374
    int entries, i, j;

375 376 377 378 379
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

380 381
    avio_rb32(pb); // version + flags
    entries = avio_rb32(pb);
382 383 384
    if (entries >= UINT_MAX / sizeof(*sc->drefs))
        return -1;
    sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
385 386 387
    if (!sc->drefs)
        return AVERROR(ENOMEM);
    sc->drefs_count = entries;
388 389

    for (i = 0; i < sc->drefs_count; i++) {
390
        MOVDref *dref = &sc->drefs[i];
391
        uint32_t size = avio_rb32(pb);
392
        int64_t next = avio_tell(pb) + size - 4;
393

394 395 396
        if (size < 12)
            return -1;

397 398
        dref->type = avio_rl32(pb);
        avio_rb32(pb); // version + flags
L
Luca Barbato 已提交
399
        av_dlog(c->fc, "type %.4s size %d\n", (char*)&dref->type, size);
400 401 402 403 404 405

        if (dref->type == MKTAG('a','l','i','s') && size > 150) {
            /* macintosh alias record */
            uint16_t volume_len, len;
            int16_t type;

406
            avio_skip(pb, 10);
407

408
            volume_len = avio_r8(pb);
409
            volume_len = FFMIN(volume_len, 27);
410
            avio_read(pb, dref->volume, 27);
411 412
            dref->volume[volume_len] = 0;
            av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
413

414
            avio_skip(pb, 12);
415

416
            len = avio_r8(pb);
417
            len = FFMIN(len, 63);
418
            avio_read(pb, dref->filename, 63);
419 420 421
            dref->filename[len] = 0;
            av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);

422
            avio_skip(pb, 16);
423 424

            /* read next level up_from_alias/down_to_target */
425 426
            dref->nlvl_from = avio_rb16(pb);
            dref->nlvl_to   = avio_rb16(pb);
427 428 429
            av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
                   dref->nlvl_from, dref->nlvl_to);

430
            avio_skip(pb, 16);
431

432
            for (type = 0; type != -1 && avio_tell(pb) < next; ) {
433 434
                type = avio_rb16(pb);
                len = avio_rb16(pb);
435 436 437 438
                av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
                if (len&1)
                    len += 1;
                if (type == 2) { // absolute path
439
                    av_free(dref->path);
440
                    dref->path = av_mallocz(len+1);
441 442
                    if (!dref->path)
                        return AVERROR(ENOMEM);
443
                    avio_read(pb, dref->path, len);
444
                    if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
445 446 447 448 449 450 451 452
                        len -= volume_len;
                        memmove(dref->path, dref->path+volume_len, len);
                        dref->path[len] = 0;
                    }
                    for (j = 0; j < len; j++)
                        if (dref->path[j] == ':')
                            dref->path[j] = '/';
                    av_log(c->fc, AV_LOG_DEBUG, "path %s\n", dref->path);
453 454 455 456 457
                } else if (type == 0) { // directory name
                    av_free(dref->dir);
                    dref->dir = av_malloc(len+1);
                    if (!dref->dir)
                        return AVERROR(ENOMEM);
458
                    avio_read(pb, dref->dir, len);
459 460 461 462 463
                    dref->dir[len] = 0;
                    for (j = 0; j < len; j++)
                        if (dref->dir[j] == ':')
                            dref->dir[j] = '/';
                    av_log(c->fc, AV_LOG_DEBUG, "dir %s\n", dref->dir);
464
                } else
465
                    avio_skip(pb, len);
466 467
            }
        }
A
Anton Khirnov 已提交
468
        avio_seek(pb, next, SEEK_SET);
469 470 471 472
    }
    return 0;
}

473
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
474
{
475
    AVStream *st;
476
    uint32_t type;
477
    uint32_t av_unused ctype;
478

479 480 481 482 483
    if (c->fc->nb_streams < 1) // meta before first trak
        return 0;

    st = c->fc->streams[c->fc->nb_streams-1];

484 485
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
486 487

    /* component type */
488 489
    ctype = avio_rl32(pb);
    type = avio_rl32(pb); /* component subtype */
490

L
Luca Barbato 已提交
491 492
    av_dlog(c->fc, "ctype= %.4s (0x%08x)\n", (char*)&ctype, ctype);
    av_dlog(c->fc, "stype= %.4s\n", (char*)&type);
493

494
    if     (type == MKTAG('v','i','d','e'))
495
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
496
    else if (type == MKTAG('s','o','u','n'))
497
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
498
    else if (type == MKTAG('m','1','a',' '))
499
        st->codec->codec_id = CODEC_ID_MP2;
500
    else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
501
        st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
502

503 504 505
    avio_rb32(pb); /* component  manufacture */
    avio_rb32(pb); /* component flags */
    avio_rb32(pb); /* component flags mask */
506 507 508 509

    return 0;
}

510
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom)
511
{
512
    AVStream *st;
M
Mans Rullgard 已提交
513
    int tag;
514

515
    if (fc->nb_streams < 1)
516
        return 0;
517
    st = fc->streams[fc->nb_streams-1];
518

519
    avio_rb32(pb); /* version + flags */
M
Mans Rullgard 已提交
520
    ff_mp4_read_descr(fc, pb, &tag);
521
    if (tag == MP4ESDescrTag) {
522
        ff_mp4_parse_es_descr(pb, NULL);
523
    } else
524
        avio_rb16(pb); /* ID */
525

M
Mans Rullgard 已提交
526
    ff_mp4_read_descr(fc, pb, &tag);
527 528
    if (tag == MP4DecConfigDescrTag)
        ff_mp4_read_dec_config_descr(fc, st, pb);
529 530 531
    return 0;
}

532
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
533 534 535 536
{
    return ff_mov_read_esds(c->fc, pb, atom);
}

537
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
538 539
{
    AVStream *st;
540
    int ac3info, acmod, lfeon, bsmod;
541

542 543
    if (c->fc->nb_streams < 1)
        return 0;
544 545
    st = c->fc->streams[c->fc->nb_streams-1];

546
    ac3info = avio_rb24(pb);
547
    bsmod = (ac3info >> 14) & 0x7;
548 549 550
    acmod = (ac3info >> 11) & 0x7;
    lfeon = (ac3info >> 10) & 0x1;
    st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
551 552 553
    st->codec->audio_service_type = bsmod;
    if (st->codec->channels > 1 && bsmod == 0x7)
        st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
554 555 556 557

    return 0;
}

558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    uint8_t version;
    uint32_t flags, layout_tag, bitmap, num_descr;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];

    if (atom.size < 16)
        return 0;

    version = avio_r8(pb);
    flags   = avio_rb24(pb);

    layout_tag = avio_rb32(pb);
    bitmap     = avio_rb32(pb);
    num_descr  = avio_rb32(pb);

    if (atom.size < 16ULL + num_descr * 20ULL)
        return 0;

    av_dlog(c->fc, "chan: size=%ld version=%u flags=%u layout=%u bitmap=%u num_descr=%u\n",
            atom.size, version, flags, layout_tag, bitmap, num_descr);

#if 0
    /* TODO: use the channel descriptions if the layout tag is 0 */
    int i;
    for (i = 0; i < num_descr; i++) {
        uint32_t label, cflags;
        float coords[3];
        label     = avio_rb32(pb);          // mChannelLabel
        cflags    = avio_rb32(pb);          // mChannelFlags
        AV_WN32(&coords[0], avio_rl32(pb)); // mCoordinates[0]
        AV_WN32(&coords[1], avio_rl32(pb)); // mCoordinates[1]
        AV_WN32(&coords[2], avio_rl32(pb)); // mCoordinates[2]
    }
#endif

    st->codec->channel_layout = ff_mov_get_channel_layout(layout_tag, bitmap);

    return 0;
}

603 604 605 606 607 608 609 610 611 612 613 614 615
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];

    ff_get_wav_header(pb, st->codec, atom.size);

    return 0;
}

616
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
617
{
618 619
    const int num = avio_rb32(pb);
    const int den = avio_rb32(pb);
620 621 622 623 624 625
    AVStream *st;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];

626 627 628 629 630 631 632
    if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
        (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
        av_log(c->fc, AV_LOG_WARNING,
               "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
               st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
               num, den);
    } else if (den != 0) {
633 634 635 636 637 638
        st->sample_aspect_ratio.num = num;
        st->sample_aspect_ratio.den = den;
    }
    return 0;
}

639
/* this atom contains actual media data */
640
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
641
{
642
    if (atom.size == 0) /* wrong one (MP4) */
643 644 645 646 647
        return 0;
    c->found_mdat=1;
    return 0; /* now go for moov */
}

648
/* read major brand, minor version and compatible brands and store them as metadata */
649
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
650
{
651 652 653 654 655 656
    uint32_t minor_ver;
    int comp_brand_size;
    char minor_ver_str[11]; /* 32 bit integer -> 10 digits + null */
    char* comp_brands_str;
    uint8_t type[5] = {0};

657
    avio_read(pb, type, 4);
B
Baptiste Coudurier 已提交
658
    if (strcmp(type, "qt  "))
659
        c->isom = 1;
660
    av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
661
    av_dict_set(&c->fc->metadata, "major_brand", type, 0);
662
    minor_ver = avio_rb32(pb); /* minor version */
663
    snprintf(minor_ver_str, sizeof(minor_ver_str), "%d", minor_ver);
664
    av_dict_set(&c->fc->metadata, "minor_version", minor_ver_str, 0);
665 666 667 668 669 670 671

    comp_brand_size = atom.size - 8;
    if (comp_brand_size < 0)
        return -1;
    comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
    if (!comp_brands_str)
        return AVERROR(ENOMEM);
672
    avio_read(pb, comp_brands_str, comp_brand_size);
673
    comp_brands_str[comp_brand_size] = 0;
674
    av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
675 676
    av_freep(&comp_brands_str);

677 678 679
    return 0;
}

680
/* this atom should contain all header atoms */
681
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
682
{
683 684
    if (mov_read_default(c, pb, atom) < 0)
        return -1;
685 686 687 688 689 690
    /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
    /* so we don't parse the whole file if over a network */
    c->found_moov=1;
    return 0; /* now go for mdat */
}

691
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
692
{
693
    c->fragment.moof_offset = avio_tell(pb) - 8;
694
    av_dlog(c->fc, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
B
Baptiste Coudurier 已提交
695 696
    return mov_read_default(c, pb, atom);
}
697

698
static void mov_metadata_creation_time(AVDictionary **metadata, time_t time)
699 700 701
{
    char buffer[32];
    if (time) {
702
        struct tm *ptm;
703
        time -= 2082844800;  /* seconds between 1904-01-01 and Epoch */
704 705 706
        ptm = gmtime(&time);
        if (!ptm) return;
        strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm);
707
        av_dict_set(metadata, "creation_time", buffer, 0);
708 709 710
    }
}

711
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
712
{
713 714 715
    AVStream *st;
    MOVStreamContext *sc;
    int version;
716
    char language[4] = {0};
717
    unsigned lang;
718
    time_t creation_time;
719

720 721 722 723 724
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

725
    version = avio_r8(pb);
726
    if (version > 1)
B
Baptiste Coudurier 已提交
727
        return -1; /* unsupported */
728

729
    avio_rb24(pb); /* flags */
B
clean  
Baptiste Coudurier 已提交
730
    if (version == 1) {
731 732
        creation_time = avio_rb64(pb);
        avio_rb64(pb);
B
clean  
Baptiste Coudurier 已提交
733
    } else {
734 735
        creation_time = avio_rb32(pb);
        avio_rb32(pb); /* modification time */
B
clean  
Baptiste Coudurier 已提交
736
    }
737
    mov_metadata_creation_time(&st->metadata, creation_time);
738

739 740
    sc->time_scale = avio_rb32(pb);
    st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
741

742
    lang = avio_rb16(pb); /* language */
743
    if (ff_mov_lang_to_iso639(lang, language))
744
        av_dict_set(&st->metadata, "language", language, 0);
745
    avio_rb16(pb); /* quality */
746 747 748 749

    return 0;
}

750
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
751
{
752
    time_t creation_time;
753 754
    int version = avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
755

B
Baptiste Coudurier 已提交
756
    if (version == 1) {
757 758
        creation_time = avio_rb64(pb);
        avio_rb64(pb);
B
Baptiste Coudurier 已提交
759
    } else {
760 761
        creation_time = avio_rb32(pb);
        avio_rb32(pb); /* modification time */
B
Baptiste Coudurier 已提交
762
    }
763
    mov_metadata_creation_time(&c->fc->metadata, creation_time);
764
    c->time_scale = avio_rb32(pb); /* time scale */
765

L
Luca Barbato 已提交
766
    av_dlog(c->fc, "time scale = %i\n", c->time_scale);
767

768 769
    c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
    avio_rb32(pb); /* preferred scale */
770

771
    avio_rb16(pb); /* preferred volume */
772

773
    avio_skip(pb, 10); /* reserved */
774

775
    avio_skip(pb, 36); /* display matrix */
776

777 778 779 780 781 782 783
    avio_rb32(pb); /* preview time */
    avio_rb32(pb); /* preview duration */
    avio_rb32(pb); /* poster time */
    avio_rb32(pb); /* selection time */
    avio_rb32(pb); /* selection duration */
    avio_rb32(pb); /* current time */
    avio_rb32(pb); /* next track ID */
784 785 786 787

    return 0;
}

788
static int mov_read_smi(MOVContext *c, AVIOContext *pb, MOVAtom atom)
789
{
790 791 792 793 794
    AVStream *st;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
795

796
    if ((uint64_t)atom.size > (1<<30))
797
        return -1;
798

799 800
    // currently SVQ3 decoder expect full STSD header - so let's fake it
    // this should be fixed and just SMI header should be passed
801
    av_free(st->codec->extradata);
802 803 804
    st->codec->extradata = av_mallocz(atom.size + 0x5a + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
805 806
    st->codec->extradata_size = 0x5a + atom.size;
    memcpy(st->codec->extradata, "SVQ3", 4); // fake
807
    avio_read(pb, st->codec->extradata + 0x5a, atom.size);
L
Luca Barbato 已提交
808
    av_dlog(c->fc, "Reading SMI %"PRId64"  %s\n", atom.size, st->codec->extradata + 0x5a);
809 810
    return 0;
}
811

812
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
813
{
814 815 816 817 818 819
    AVStream *st;
    int little_endian;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
820

821
    little_endian = avio_rb16(pb);
L
Luca Barbato 已提交
822
    av_dlog(c->fc, "enda %d\n", little_endian);
823
    if (little_endian == 1) {
824 825 826 827 828 829 830
        switch (st->codec->codec_id) {
        case CODEC_ID_PCM_S24BE:
            st->codec->codec_id = CODEC_ID_PCM_S24LE;
            break;
        case CODEC_ID_PCM_S32BE:
            st->codec->codec_id = CODEC_ID_PCM_S32LE;
            break;
831 832 833 834 835 836
        case CODEC_ID_PCM_F32BE:
            st->codec->codec_id = CODEC_ID_PCM_F32LE;
            break;
        case CODEC_ID_PCM_F64BE:
            st->codec->codec_id = CODEC_ID_PCM_F64LE;
            break;
837 838 839 840 841 842 843
        default:
            break;
        }
    }
    return 0;
}

844
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
845
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom)
846
{
847 848
    AVStream *st;
    uint64_t size;
849
    uint8_t *buf;
850 851 852 853 854

    if (c->fc->nb_streams < 1) // will happen with jp2 files
        return 0;
    st= c->fc->streams[c->fc->nb_streams-1];
    size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
855
    if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
856
        return -1;
857
    buf= av_realloc(st->codec->extradata, size);
858
    if (!buf)
859 860 861 862 863 864
        return -1;
    st->codec->extradata= buf;
    buf+= st->codec->extradata_size;
    st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE;
    AV_WB32(       buf    , atom.size + 8);
    AV_WL32(       buf + 4, atom.type);
865
    avio_read(pb, buf + 8, atom.size);
866 867 868
    return 0;
}

869
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
R
Roberto Togni 已提交
870
{
871 872 873 874 875
    AVStream *st;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
R
Roberto Togni 已提交
876

877
    if ((uint64_t)atom.size > (1<<30))
R
Roberto Togni 已提交
878
        return -1;
879

880 881
    if (st->codec->codec_id == CODEC_ID_QDM2 || st->codec->codec_id == CODEC_ID_QDMC) {
        // pass all frma atom to codec, needed at least for QDMC and QDM2
882
        av_free(st->codec->extradata);
883 884 885
        st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
        if (!st->codec->extradata)
            return AVERROR(ENOMEM);
886
        st->codec->extradata_size = atom.size;
887
        avio_read(pb, st->codec->extradata, atom.size);
888
    } else if (atom.size > 8) { /* to read frma, esds atoms */
889 890
        if (mov_read_default(c, pb, atom) < 0)
            return -1;
891
    } else
892
        avio_skip(pb, atom.size);
R
Roberto Togni 已提交
893 894 895
    return 0;
}

896 897 898 899
/**
 * This function reads atom content and puts data in extradata without tag
 * nor size unlike mov_read_extradata.
 */
900
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
901
{
902 903 904 905 906
    AVStream *st;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
907

908
    if ((uint64_t)atom.size > (1<<30))
909 910
        return -1;

911
    av_free(st->codec->extradata);
912 913 914
    st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
915
    st->codec->extradata_size = atom.size;
916
    avio_read(pb, st->codec->extradata, atom.size);
917 918 919
    return 0;
}

M
Martin Storsjö 已提交
920 921 922 923 924
/**
 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
 * but can have extradata appended at the end after the 40 bytes belonging
 * to the struct.
 */
925
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
M
Martin Storsjö 已提交
926 927 928 929 930 931 932 933 934
{
    AVStream *st;

    if (c->fc->nb_streams < 1)
        return 0;
    if (atom.size <= 40)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];

935
    if ((uint64_t)atom.size > (1<<30))
M
Martin Storsjö 已提交
936 937 938 939 940 941 942
        return -1;

    av_free(st->codec->extradata);
    st->codec->extradata = av_mallocz(atom.size - 40 + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
    st->codec->extradata_size = atom.size - 40;
943
    avio_skip(pb, 40);
944
    avio_read(pb, st->codec->extradata, atom.size - 40);
M
Martin Storsjö 已提交
945 946 947
    return 0;
}

948
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
949
{
950 951
    AVStream *st;
    MOVStreamContext *sc;
952
    unsigned int i, entries;
953

954 955 956 957 958
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

959 960
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
961

962
    entries = avio_rb32(pb);
963

A
Alex Converse 已提交
964 965
    if (!entries)
        return 0;
966
    if (entries >= UINT_MAX/sizeof(int64_t))
967
        return -1;
968

B
Baptiste Coudurier 已提交
969
    sc->chunk_offsets = av_malloc(entries * sizeof(int64_t));
970
    if (!sc->chunk_offsets)
971 972 973
        return AVERROR(ENOMEM);
    sc->chunk_count = entries;

974
    if      (atom.type == MKTAG('s','t','c','o'))
975
        for (i=0; i<entries; i++)
976
            sc->chunk_offsets[i] = avio_rb32(pb);
977
    else if (atom.type == MKTAG('c','o','6','4'))
978
        for (i=0; i<entries; i++)
979
            sc->chunk_offsets[i] = avio_rb64(pb);
980
    else
981
        return -1;
982

983 984 985
    return 0;
}

986 987 988 989
/**
 * Compute codec id for 'lpcm' tag.
 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
 */
990
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
991 992 993 994
{
    if (flags & 1) { // floating point
        if (flags & 2) { // big endian
            if      (bps == 32) return CODEC_ID_PCM_F32BE;
995
            else if (bps == 64) return CODEC_ID_PCM_F64BE;
996
        } else {
997 998
            if      (bps == 32) return CODEC_ID_PCM_F32LE;
            else if (bps == 64) return CODEC_ID_PCM_F64LE;
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012
        }
    } else {
        if (flags & 2) {
            if      (bps == 8)
                // signed integer
                if (flags & 4)  return CODEC_ID_PCM_S8;
                else            return CODEC_ID_PCM_U8;
            else if (bps == 16) return CODEC_ID_PCM_S16BE;
            else if (bps == 24) return CODEC_ID_PCM_S24BE;
            else if (bps == 32) return CODEC_ID_PCM_S32BE;
        } else {
            if      (bps == 8)
                if (flags & 4)  return CODEC_ID_PCM_S8;
                else            return CODEC_ID_PCM_U8;
B
Baptiste Coudurier 已提交
1013
            else if (bps == 16) return CODEC_ID_PCM_S16LE;
1014 1015 1016 1017
            else if (bps == 24) return CODEC_ID_PCM_S24LE;
            else if (bps == 32) return CODEC_ID_PCM_S32LE;
        }
    }
D
Diego Pettenò 已提交
1018
    return CODEC_ID_NONE;
1019 1020
}

1021
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
1022
{
1023 1024
    AVStream *st;
    MOVStreamContext *sc;
1025
    int j, pseudo_stream_id;
1026

1027 1028 1029 1030 1031
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

1032
    for (pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
1033
        //Parsing Sample description table
1034
        enum CodecID id;
1035
        int dref_id = 1;
1036
        MOVAtom a = { AV_RL32("stsd") };
1037
        int64_t start_pos = avio_tell(pb);
1038 1039
        int size = avio_rb32(pb); /* size */
        uint32_t format = avio_rl32(pb); /* data format */
1040

1041
        if (size >= 16) {
1042 1043 1044
            avio_rb32(pb); /* reserved */
            avio_rb16(pb); /* reserved */
            dref_id = avio_rb16(pb);
1045
        }
1046

1047
        if (st->codec->codec_tag &&
1048
            st->codec->codec_tag != format &&
1049
            (c->fc->video_codec_id ? ff_codec_get_id(codec_movvideo_tags, format) != c->fc->video_codec_id
1050
                                   : st->codec->codec_tag != MKTAG('j','p','e','g'))
1051
           ){
D
Diego Biurrun 已提交
1052 1053 1054
            /* Multiple fourcc, we skip JPEG. This is not correct, we should
             * export it as a separate AVStream but this needs a few changes
             * in the MOV demuxer, patch welcome. */
1055
        multiple_stsd:
B
Baptiste Coudurier 已提交
1056
            av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
1057
            avio_skip(pb, size - (avio_tell(pb) - start_pos));
1058 1059
            continue;
        }
1060 1061 1062
        /* we cannot demux concatenated h264 streams because of different extradata */
        if (st->codec->codec_tag && st->codec->codec_tag == AV_RL32("avc1"))
            goto multiple_stsd;
1063
        sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
1064
        sc->dref_id= dref_id;
1065

1066
        st->codec->codec_tag = format;
1067
        id = ff_codec_get_id(codec_movaudio_tags, format);
1068
        if (id<=0 && ((format&0xFFFF) == 'm'+('s'<<8) || (format&0xFFFF) == 'T'+('S'<<8)))
M
Måns Rullgård 已提交
1069
            id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format)&0xFFFF);
M
Michael Niedermayer 已提交
1070

1071 1072 1073
        if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        } else if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO && /* do not overwrite codec type */
1074
                   format && format != MKTAG('m','p','4','s')) { /* skip old asf mpeg4 tag */
1075
            id = ff_codec_get_id(codec_movvideo_tags, format);
1076
            if (id <= 0)
1077
                id = ff_codec_get_id(ff_codec_bmp_tags, format);
1078
            if (id > 0)
1079
                st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
1080
            else if (st->codec->codec_type == AVMEDIA_TYPE_DATA){
1081
                id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
1082
                if (id > 0)
1083
                    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
1084
            }
1085 1086
        }

L
Luca Barbato 已提交
1087
        av_dlog(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size,
1088 1089
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
                (format >> 24) & 0xff, st->codec->codec_type);
1090

1091
        if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
1092
            unsigned int color_depth, len;
1093 1094
            int color_greyscale;

1095
            st->codec->codec_id = id;
1096 1097 1098 1099 1100
            avio_rb16(pb); /* version */
            avio_rb16(pb); /* revision level */
            avio_rb32(pb); /* vendor */
            avio_rb32(pb); /* temporal quality */
            avio_rb32(pb); /* spatial quality */
1101

1102 1103
            st->codec->width = avio_rb16(pb); /* width */
            st->codec->height = avio_rb16(pb); /* height */
1104

1105 1106 1107 1108
            avio_rb32(pb); /* horiz resolution */
            avio_rb32(pb); /* vert resolution */
            avio_rb32(pb); /* data size, always 0 */
            avio_rb16(pb); /* frames per samples */
1109

1110
            len = avio_r8(pb); /* codec name, pascal string */
1111 1112 1113 1114
            if (len > 31)
                len = 31;
            mov_read_mac_string(c, pb, len, st->codec->codec_name, 32);
            if (len < 31)
1115
                avio_skip(pb, 31 - len);
1116 1117 1118
            /* codec_tag YV12 triggers an UV swap in rawdec.c */
            if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25))
                st->codec->codec_tag=MKTAG('I', '4', '2', '0');
1119

1120 1121
            st->codec->bits_per_coded_sample = avio_rb16(pb); /* depth */
            st->codec->color_table_id = avio_rb16(pb); /* colortable id */
L
Luca Barbato 已提交
1122
            av_dlog(c->fc, "depth %d, ctab id %d\n",
1123
                   st->codec->bits_per_coded_sample, st->codec->color_table_id);
1124
            /* figure out the palette situation */
1125 1126
            color_depth = st->codec->bits_per_coded_sample & 0x1F;
            color_greyscale = st->codec->bits_per_coded_sample & 0x20;
1127 1128

            /* if the depth is 2, 4, or 8 bpp, file is palettized */
1129
            if ((color_depth == 2) || (color_depth == 4) ||
1130
                (color_depth == 8)) {
1131 1132 1133 1134
                /* for palette traversal */
                unsigned int color_start, color_count, color_end;
                unsigned char r, g, b;

1135
                if (color_greyscale) {
1136
                    int color_index, color_dec;
1137
                    /* compute the greyscale palette */
1138
                    st->codec->bits_per_coded_sample = color_depth;
1139 1140 1141 1142 1143
                    color_count = 1 << color_depth;
                    color_index = 255;
                    color_dec = 256 / (color_count - 1);
                    for (j = 0; j < color_count; j++) {
                        r = g = b = color_index;
1144
                        sc->palette[j] =
1145 1146 1147 1148 1149
                            (r << 16) | (g << 8) | (b);
                        color_index -= color_dec;
                        if (color_index < 0)
                            color_index = 0;
                    }
1150
                } else if (st->codec->color_table_id) {
1151
                    const uint8_t *color_table;
1152 1153 1154
                    /* if flag bit 3 is set, use the default palette */
                    color_count = 1 << color_depth;
                    if (color_depth == 2)
M
Michael Niedermayer 已提交
1155
                        color_table = ff_qt_default_palette_4;
1156
                    else if (color_depth == 4)
M
Michael Niedermayer 已提交
1157
                        color_table = ff_qt_default_palette_16;
1158
                    else
M
Michael Niedermayer 已提交
1159
                        color_table = ff_qt_default_palette_256;
1160 1161

                    for (j = 0; j < color_count; j++) {
1162 1163 1164
                        r = color_table[j * 3 + 0];
                        g = color_table[j * 3 + 1];
                        b = color_table[j * 3 + 2];
1165
                        sc->palette[j] =
1166 1167 1168 1169
                            (r << 16) | (g << 8) | (b);
                    }
                } else {
                    /* load the palette from the file */
1170 1171 1172
                    color_start = avio_rb32(pb);
                    color_count = avio_rb16(pb);
                    color_end = avio_rb16(pb);
1173 1174
                    if ((color_start <= 255) &&
                        (color_end <= 255)) {
M
Mike Melanson 已提交
1175 1176 1177 1178
                        for (j = color_start; j <= color_end; j++) {
                            /* each R, G, or B component is 16 bits;
                             * only use the top 8 bits; skip alpha bytes
                             * up front */
1179 1180 1181 1182 1183 1184 1185 1186
                            avio_r8(pb);
                            avio_r8(pb);
                            r = avio_r8(pb);
                            avio_r8(pb);
                            g = avio_r8(pb);
                            avio_r8(pb);
                            b = avio_r8(pb);
                            avio_r8(pb);
1187
                            sc->palette[j] =
M
Mike Melanson 已提交
1188
                                (r << 16) | (g << 8) | (b);
1189
                        }
1190 1191
                    }
                }
1192
                sc->has_palette = 1;
1193
            }
1194
        } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
1195
            int bits_per_sample, flags;
1196
            uint16_t version = avio_rb16(pb);
1197

1198
            st->codec->codec_id = id;
1199 1200
            avio_rb16(pb); /* revision level */
            avio_rb32(pb); /* vendor */
1201

1202
            st->codec->channels = avio_rb16(pb);             /* channel count */
L
Luca Barbato 已提交
1203
            av_dlog(c->fc, "audio channels %d\n", st->codec->channels);
1204
            st->codec->bits_per_coded_sample = avio_rb16(pb);      /* sample size */
1205

1206 1207
            sc->audio_cid = avio_rb16(pb);
            avio_rb16(pb); /* packet size = 0 */
1208

1209
            st->codec->sample_rate = ((avio_rb32(pb) >> 16));
1210

1211
            //Read QT version 1 fields. In version 0 these do not exist.
L
Luca Barbato 已提交
1212
            av_dlog(c->fc, "version =%d, isom =%d\n",version,c->isom);
1213 1214
            if (!c->isom) {
                if (version==1) {
1215 1216 1217 1218
                    sc->samples_per_frame = avio_rb32(pb);
                    avio_rb32(pb); /* bytes per packet */
                    sc->bytes_per_frame = avio_rb32(pb);
                    avio_rb32(pb); /* bytes per sample */
1219
                } else if (version==2) {
1220
                    avio_rb32(pb); /* sizeof struct only */
1221
                    st->codec->sample_rate = av_int2double(avio_rb64(pb)); /* float 64 */
1222 1223 1224 1225 1226 1227
                    st->codec->channels = avio_rb32(pb);
                    avio_rb32(pb); /* always 0x7F000000 */
                    st->codec->bits_per_coded_sample = avio_rb32(pb); /* bits per channel if sound is uncompressed */
                    flags = avio_rb32(pb); /* lpcm format specific flag */
                    sc->bytes_per_frame = avio_rb32(pb); /* bytes per audio packet if constant */
                    sc->samples_per_frame = avio_rb32(pb); /* lpcm frames per audio packet if constant */
1228
                    if (format == MKTAG('l','p','c','m'))
1229
                        st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, flags);
1230 1231 1232
                }
            }

1233
            switch (st->codec->codec_id) {
1234 1235
            case CODEC_ID_PCM_S8:
            case CODEC_ID_PCM_U8:
1236
                if (st->codec->bits_per_coded_sample == 16)
1237 1238
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
                break;
1239
            case CODEC_ID_PCM_S16LE:
1240
            case CODEC_ID_PCM_S16BE:
1241
                if (st->codec->bits_per_coded_sample == 8)
1242
                    st->codec->codec_id = CODEC_ID_PCM_S8;
1243
                else if (st->codec->bits_per_coded_sample == 24)
1244 1245 1246
                    st->codec->codec_id =
                        st->codec->codec_id == CODEC_ID_PCM_S16BE ?
                        CODEC_ID_PCM_S24BE : CODEC_ID_PCM_S24LE;
1247
                break;
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259 1260
            /* set values for old format before stsd version 1 appeared */
            case CODEC_ID_MACE3:
                sc->samples_per_frame = 6;
                sc->bytes_per_frame = 2*st->codec->channels;
                break;
            case CODEC_ID_MACE6:
                sc->samples_per_frame = 6;
                sc->bytes_per_frame = 1*st->codec->channels;
                break;
            case CODEC_ID_ADPCM_IMA_QT:
                sc->samples_per_frame = 64;
                sc->bytes_per_frame = 34*st->codec->channels;
                break;
1261 1262 1263 1264
            case CODEC_ID_GSM:
                sc->samples_per_frame = 160;
                sc->bytes_per_frame = 33;
                break;
1265 1266
            default:
                break;
1267
            }
1268

1269 1270
            bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
            if (bits_per_sample) {
1271
                st->codec->bits_per_coded_sample = bits_per_sample;
1272 1273
                sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
            }
1274
        } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
1275 1276
            // ttxt stsd contains display flags, justification, background
            // color, fonts, and default styles, so fake an atom to read it
1277
            MOVAtom fake_atom = { .size = size - (avio_tell(pb) - start_pos) };
1278
            if (format != AV_RL32("mp4s")) // mp4s contains a regular esds atom
R
Reimar Döffinger 已提交
1279
                mov_read_glbl(c, pb, fake_atom);
1280
            st->codec->codec_id= id;
1281 1282
            st->codec->width = sc->width;
            st->codec->height = sc->height;
1283 1284
        } else {
            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
1285
            avio_skip(pb, size - (avio_tell(pb) - start_pos));
1286
        }
1287
        /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
1288
        a.size = size - (avio_tell(pb) - start_pos);
1289 1290 1291 1292
        if (a.size > 8) {
            if (mov_read_default(c, pb, a) < 0)
                return -1;
        } else if (a.size > 0)
1293
            avio_skip(pb, a.size);
1294
    }
1295

1296
    if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
1297
        st->codec->sample_rate= sc->time_scale;
1298

1299
    /* special codec parameters handling */
1300
    switch (st->codec->codec_id) {
1301
#if CONFIG_DV_DEMUXER
1302
    case CODEC_ID_DVAUDIO:
1303
        c->dv_fctx = avformat_alloc_context();
1304
        c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
1305 1306 1307 1308 1309 1310 1311
        if (!c->dv_demux) {
            av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
            return -1;
        }
        sc->dv_audio_container = 1;
        st->codec->codec_id = CODEC_ID_PCM_S16LE;
        break;
1312
#endif
1313
    /* no ifdef since parameters are always those */
1314
    case CODEC_ID_QCELP:
1315 1316 1317
        // force sample rate for qcelp when not stored in mov
        if (st->codec->codec_tag != MKTAG('Q','c','l','p'))
            st->codec->sample_rate = 8000;
1318
        st->codec->frame_size= 160;
1319
        st->codec->channels= 1; /* really needed */
1320
        break;
1321 1322
    case CODEC_ID_AMR_NB:
        st->codec->channels= 1; /* really needed */
1323
        /* force sample rate for amr, stsd in 3gp does not store sample rate */
C
Carl Eugen Hoyos 已提交
1324 1325 1326 1327 1328 1329 1330 1331
        st->codec->sample_rate = 8000;
        /* force frame_size, too, samples_per_frame isn't always set properly */
        st->codec->frame_size  = 160;
        break;
    case CODEC_ID_AMR_WB:
        st->codec->channels    = 1;
        st->codec->sample_rate = 16000;
        st->codec->frame_size  = 320;
1332
        break;
1333
    case CODEC_ID_MP2:
1334
    case CODEC_ID_MP3:
1335
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO; /* force type after stsd for m1a hdlr */
A
Aurelien Jacobs 已提交
1336
        st->need_parsing = AVSTREAM_PARSE_FULL;
1337
        break;
1338
    case CODEC_ID_GSM:
1339 1340
    case CODEC_ID_ADPCM_MS:
    case CODEC_ID_ADPCM_IMA_WAV:
1341
        st->codec->frame_size = sc->samples_per_frame;
1342 1343
        st->codec->block_align = sc->bytes_per_frame;
        break;
1344
    case CODEC_ID_ALAC:
1345
        if (st->codec->extradata_size == 36) {
1346 1347
            st->codec->frame_size = AV_RB32(st->codec->extradata+12);
            st->codec->channels   = AV_RB8 (st->codec->extradata+21);
1348
            st->codec->sample_rate = AV_RB32(st->codec->extradata+32);
1349
        }
1350
        break;
1351 1352 1353
    default:
        break;
    }
1354

1355 1356 1357
    return 0;
}

1358
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1359 1360 1361
{
    int entries;

1362 1363 1364
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
1365 1366 1367 1368

    return ff_mov_read_stsd_entries(c, pb, entries);
}

1369
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1370
{
1371 1372
    AVStream *st;
    MOVStreamContext *sc;
1373
    unsigned int i, entries;
1374

1375 1376 1377 1378 1379
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

1380 1381
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1382

1383
    entries = avio_rb32(pb);
1384

L
Luca Barbato 已提交
1385
    av_dlog(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1386

A
Alex Converse 已提交
1387 1388
    if (!entries)
        return 0;
1389
    if (entries >= UINT_MAX / sizeof(*sc->stsc_data))
1390
        return -1;
1391 1392
    sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
    if (!sc->stsc_data)
1393 1394 1395
        return AVERROR(ENOMEM);
    sc->stsc_count = entries;

1396
    for (i=0; i<entries; i++) {
1397 1398 1399
        sc->stsc_data[i].first = avio_rb32(pb);
        sc->stsc_data[i].count = avio_rb32(pb);
        sc->stsc_data[i].id = avio_rb32(pb);
1400 1401 1402 1403
    }
    return 0;
}

1404
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1405 1406 1407 1408 1409 1410 1411 1412 1413 1414
{
    AVStream *st;
    MOVStreamContext *sc;
    unsigned i, entries;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

1415
    avio_rb32(pb); // version + flags
1416

1417
    entries = avio_rb32(pb);
1418 1419 1420 1421 1422 1423 1424 1425
    if (entries >= UINT_MAX / sizeof(*sc->stps_data))
        return -1;
    sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data));
    if (!sc->stps_data)
        return AVERROR(ENOMEM);
    sc->stps_count = entries;

    for (i = 0; i < entries; i++) {
1426
        sc->stps_data[i] = avio_rb32(pb);
L
Luca Barbato 已提交
1427
        //av_dlog(c->fc, "stps %d\n", sc->stps_data[i]);
1428 1429 1430 1431 1432
    }

    return 0;
}

1433
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1434
{
1435 1436
    AVStream *st;
    MOVStreamContext *sc;
1437
    unsigned int i, entries;
1438

1439 1440 1441 1442 1443
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

1444 1445
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1446

1447
    entries = avio_rb32(pb);
1448

L
Luca Barbato 已提交
1449
    av_dlog(c->fc, "keyframe_count = %d\n", entries);
1450

1451
    if (entries >= UINT_MAX / sizeof(int))
1452
        return -1;
B
Baptiste Coudurier 已提交
1453
    sc->keyframes = av_malloc(entries * sizeof(int));
1454
    if (!sc->keyframes)
1455 1456 1457
        return AVERROR(ENOMEM);
    sc->keyframe_count = entries;

1458
    for (i=0; i<entries; i++) {
1459
        sc->keyframes[i] = avio_rb32(pb);
L
Luca Barbato 已提交
1460
        //av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
1461 1462 1463 1464
    }
    return 0;
}

1465
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1466
{
1467 1468
    AVStream *st;
    MOVStreamContext *sc;
1469 1470 1471
    unsigned int i, entries, sample_size, field_size, num_bytes;
    GetBitContext gb;
    unsigned char* buf;
1472

1473 1474 1475 1476 1477
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

1478 1479
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1480

1481
    if (atom.type == MKTAG('s','t','s','z')) {
1482
        sample_size = avio_rb32(pb);
1483 1484 1485
        if (!sc->sample_size) /* do not overwrite value computed in stsd */
            sc->sample_size = sample_size;
        field_size = 32;
1486 1487
    } else {
        sample_size = 0;
1488 1489
        avio_rb24(pb); /* reserved */
        field_size = avio_r8(pb);
1490
    }
1491
    entries = avio_rb32(pb);
1492

L
Luca Barbato 已提交
1493
    av_dlog(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, entries);
1494

1495
    sc->sample_count = entries;
1496 1497 1498
    if (sample_size)
        return 0;

1499 1500 1501 1502 1503
    if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
        av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %d\n", field_size);
        return -1;
    }

A
Alex Converse 已提交
1504 1505
    if (!entries)
        return 0;
1506
    if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size)
1507
        return -1;
B
Baptiste Coudurier 已提交
1508
    sc->sample_sizes = av_malloc(entries * sizeof(int));
1509
    if (!sc->sample_sizes)
1510 1511
        return AVERROR(ENOMEM);

1512 1513
    num_bytes = (entries*field_size+4)>>3;

1514
    buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE);
1515 1516 1517 1518 1519
    if (!buf) {
        av_freep(&sc->sample_sizes);
        return AVERROR(ENOMEM);
    }

1520
    if (avio_read(pb, buf, num_bytes) < num_bytes) {
1521 1522 1523 1524 1525 1526 1527
        av_freep(&sc->sample_sizes);
        av_free(buf);
        return -1;
    }

    init_get_bits(&gb, buf, 8*num_bytes);

1528
    for (i=0; i<entries; i++)
1529 1530 1531
        sc->sample_sizes[i] = get_bits_long(&gb, field_size);

    av_free(buf);
1532 1533 1534
    return 0;
}

1535
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1536
{
1537 1538
    AVStream *st;
    MOVStreamContext *sc;
1539
    unsigned int i, entries;
1540 1541
    int64_t duration=0;
    int64_t total_sample_count=0;
1542

1543 1544 1545 1546 1547
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

1548 1549 1550
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
1551

1552 1553
    av_dlog(c->fc, "track[%i].stts.entries = %i\n",
            c->fc->nb_streams-1, entries);
1554

A
Alex Converse 已提交
1555 1556 1557
    if (!entries)
        return 0;
    if (entries >= UINT_MAX / sizeof(*sc->stts_data))
L
Luca Barbato 已提交
1558
        return AVERROR(EINVAL);
1559

1560
    sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));
1561
    if (!sc->stts_data)
1562
        return AVERROR(ENOMEM);
1563

1564
    sc->stts_count = entries;
1565

1566
    for (i=0; i<entries; i++) {
M
cleanup  
Michael Niedermayer 已提交
1567 1568
        int sample_duration;
        int sample_count;
1569

1570 1571
        sample_count=avio_rb32(pb);
        sample_duration = avio_rb32(pb);
1572 1573 1574
        sc->stts_data[i].count= sample_count;
        sc->stts_data[i].duration= sample_duration;

1575 1576
        av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n",
                sample_count, sample_duration);
1577

B
Baptiste Coudurier 已提交
1578
        duration+=(int64_t)sample_duration*sample_count;
1579 1580 1581
        total_sample_count+=sample_count;
    }

1582
    st->nb_frames= total_sample_count;
1583
    if (duration)
1584
        st->duration= duration;
1585 1586 1587
    return 0;
}

1588
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
M
Michael Niedermayer 已提交
1589
{
1590 1591
    AVStream *st;
    MOVStreamContext *sc;
M
Michael Niedermayer 已提交
1592 1593
    unsigned int i, entries;

1594 1595 1596 1597 1598
    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;

1599 1600 1601
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
1602

L
Luca Barbato 已提交
1603
    av_dlog(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
1604

A
Alex Converse 已提交
1605 1606
    if (!entries)
        return 0;
1607
    if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
M
Michael Niedermayer 已提交
1608
        return -1;
1609
    sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
1610
    if (!sc->ctts_data)
1611 1612
        return AVERROR(ENOMEM);
    sc->ctts_count = entries;
1613

1614
    for (i=0; i<entries; i++) {
1615 1616
        int count    =avio_rb32(pb);
        int duration =avio_rb32(pb);
1617 1618 1619

        sc->ctts_data[i].count   = count;
        sc->ctts_data[i].duration= duration;
1620 1621
        if (duration < 0)
            sc->dts_shift = FFMAX(sc->dts_shift, -duration);
M
Michael Niedermayer 已提交
1622
    }
1623

L
Luca Barbato 已提交
1624
    av_dlog(c->fc, "dts shift %d\n", sc->dts_shift);
1625

M
Michael Niedermayer 已提交
1626 1627 1628
    return 0;
}

1629 1630 1631
static void mov_build_index(MOVContext *mov, AVStream *st)
{
    MOVStreamContext *sc = st->priv_data;
1632
    int64_t current_offset;
1633 1634 1635 1636
    int64_t current_dts = 0;
    unsigned int stts_index = 0;
    unsigned int stsc_index = 0;
    unsigned int stss_index = 0;
1637
    unsigned int stps_index = 0;
1638
    unsigned int i, j;
1639
    uint64_t stream_size = 0;
1640

1641
    /* adjust first dts according to edit list */
1642
    if (sc->time_offset && mov->time_scale > 0) {
1643 1644 1645
        if (sc->time_offset < 0)
            sc->time_offset = av_rescale(sc->time_offset, sc->time_scale, mov->time_scale);
        current_dts = -sc->time_offset;
1646
        if (sc->ctts_data && sc->stts_data && sc->stts_data[0].duration &&
1647
            sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) {
1648 1649 1650 1651 1652
            /* more than 16 frames delay, dts are likely wrong
               this happens with files created by iMovie */
            sc->wrong_dts = 1;
            st->codec->has_b_frames = 1;
        }
1653 1654
    }

1655
    /* only use old uncompressed audio chunk demuxing when stts specifies it */
1656
    if (!(st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1657
          sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
1658 1659
        unsigned int current_sample = 0;
        unsigned int stts_sample = 0;
1660
        unsigned int sample_size;
1661 1662 1663
        unsigned int distance = 0;
        int key_off = sc->keyframes && sc->keyframes[0] == 1;

1664 1665
        current_dts -= sc->dts_shift;

A
Alex Converse 已提交
1666 1667
        if (!sc->sample_count)
            return;
1668 1669 1670 1671 1672 1673 1674
        if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries))
            return;
        st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries));
        if (!st->index_entries)
            return;
        st->index_entries_allocated_size = sc->sample_count*sizeof(*st->index_entries);

1675 1676
        for (i = 0; i < sc->chunk_count; i++) {
            current_offset = sc->chunk_offsets[i];
1677
            while (stsc_index + 1 < sc->stsc_count &&
1678
                i + 1 == sc->stsc_data[stsc_index + 1].first)
1679
                stsc_index++;
1680
            for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
1681
                int keyframe = 0;
1682 1683
                if (current_sample >= sc->sample_count) {
                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
1684
                    return;
1685
                }
1686 1687 1688

                if (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index]) {
                    keyframe = 1;
1689 1690
                    if (stss_index + 1 < sc->keyframe_count)
                        stss_index++;
1691 1692 1693 1694
                } else if (sc->stps_count && current_sample+key_off == sc->stps_data[stps_index]) {
                    keyframe = 1;
                    if (stps_index + 1 < sc->stps_count)
                        stps_index++;
1695
                }
1696 1697
                if (keyframe)
                    distance = 0;
1698
                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
1699
                if (sc->pseudo_stream_id == -1 ||
1700
                   sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
1701 1702 1703 1704 1705 1706
                    AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
                    e->pos = current_offset;
                    e->timestamp = current_dts;
                    e->size = sample_size;
                    e->min_distance = distance;
                    e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
L
Luca Barbato 已提交
1707
                    av_dlog(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
1708 1709 1710
                            "size %d, distance %d, keyframe %d\n", st->index, current_sample,
                            current_offset, current_dts, sample_size, distance, keyframe);
                }
1711

1712
                current_offset += sample_size;
1713
                stream_size += sample_size;
1714
                current_dts += sc->stts_data[stts_index].duration;
1715 1716 1717 1718 1719 1720 1721 1722 1723
                distance++;
                stts_sample++;
                current_sample++;
                if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
                    stts_sample = 0;
                    stts_index++;
                }
            }
        }
1724 1725
        if (st->duration > 0)
            st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;
1726
    } else {
1727
        unsigned chunk_samples, total = 0;
1728

1729 1730 1731
        // compute total chunk count
        for (i = 0; i < sc->stsc_count; i++) {
            unsigned count, chunk_count;
1732

1733
            chunk_samples = sc->stsc_data[i].count;
1734 1735 1736 1737 1738
            if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
                av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
                return;
            }

1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754
            if (sc->samples_per_frame >= 160) { // gsm
                count = chunk_samples / sc->samples_per_frame;
            } else if (sc->samples_per_frame > 1) {
                unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
                count = (chunk_samples+samples-1) / samples;
            } else {
                count = (chunk_samples+1023) / 1024;
            }

            if (i < sc->stsc_count - 1)
                chunk_count = sc->stsc_data[i+1].first - sc->stsc_data[i].first;
            else
                chunk_count = sc->chunk_count - (sc->stsc_data[i].first - 1);
            total += chunk_count * count;
        }

L
Luca Barbato 已提交
1755
        av_dlog(mov->fc, "chunk count %d\n", total);
1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770
        if (total >= UINT_MAX / sizeof(*st->index_entries))
            return;
        st->index_entries = av_malloc(total*sizeof(*st->index_entries));
        if (!st->index_entries)
            return;
        st->index_entries_allocated_size = total*sizeof(*st->index_entries);

        // populate index
        for (i = 0; i < sc->chunk_count; i++) {
            current_offset = sc->chunk_offsets[i];
            if (stsc_index + 1 < sc->stsc_count &&
                i + 1 == sc->stsc_data[stsc_index + 1].first)
                stsc_index++;
            chunk_samples = sc->stsc_data[stsc_index].count;

1771
            while (chunk_samples > 0) {
1772
                AVIndexEntry *e;
1773 1774 1775 1776 1777 1778 1779 1780 1781 1782
                unsigned size, samples;

                if (sc->samples_per_frame >= 160) { // gsm
                    samples = sc->samples_per_frame;
                    size = sc->bytes_per_frame;
                } else {
                    if (sc->samples_per_frame > 1) {
                        samples = FFMIN((1024 / sc->samples_per_frame)*
                                        sc->samples_per_frame, chunk_samples);
                        size = (samples / sc->samples_per_frame) * sc->bytes_per_frame;
1783
                    } else {
1784 1785
                        samples = FFMIN(1024, chunk_samples);
                        size = samples * sc->sample_size;
1786 1787
                    }
                }
1788

1789 1790 1791 1792 1793 1794 1795 1796 1797 1798
                if (st->nb_index_entries >= total) {
                    av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total);
                    return;
                }
                e = &st->index_entries[st->nb_index_entries++];
                e->pos = current_offset;
                e->timestamp = current_dts;
                e->size = size;
                e->min_distance = 0;
                e->flags = AVINDEX_KEYFRAME;
L
Luca Barbato 已提交
1799
                av_dlog(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "
1800
                        "size %d, duration %d\n", st->index, i, current_offset, current_dts,
1801 1802 1803
                        size, samples);

                current_offset += size;
1804
                current_dts += samples;
1805
                chunk_samples -= samples;
1806 1807 1808 1809
            }
        }
    }
}
1810

1811 1812
static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref,
                         AVIOInterruptCB *int_cb)
1813
{
1814 1815
    /* try relative path, we do not try the absolute because it can leak information about our
       system to an attacker */
1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837
    if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
        char filename[1024];
        char *src_path;
        int i, l;

        /* find a source dir */
        src_path = strrchr(src, '/');
        if (src_path)
            src_path++;
        else
            src_path = src;

        /* find a next level down to target */
        for (i = 0, l = strlen(ref->path) - 1; l >= 0; l--)
            if (ref->path[l] == '/') {
                if (i == ref->nlvl_to - 1)
                    break;
                else
                    i++;
            }

        /* compose filename if next level down to target was found */
1838
        if (i == ref->nlvl_to - 1 && src_path - src  < sizeof(filename)) {
1839 1840 1841 1842 1843 1844 1845 1846
            memcpy(filename, src, src_path - src);
            filename[src_path - src] = 0;

            for (i = 1; i < ref->nlvl_from; i++)
                av_strlcat(filename, "../", 1024);

            av_strlcat(filename, ref->path + l + 1, 1024);

1847
            if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL))
1848 1849 1850 1851 1852
                return 0;
        }
    }

    return AVERROR(ENOENT);
M
Mans Rullgard 已提交
1853
}
1854

1855
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1856 1857 1858
{
    AVStream *st;
    MOVStreamContext *sc;
1859
    int ret;
1860

1861
    st = avformat_new_stream(c->fc, NULL);
B
Baptiste Coudurier 已提交
1862
    if (!st) return AVERROR(ENOMEM);
1863
    st->id = c->fc->nb_streams;
B
Baptiste Coudurier 已提交
1864
    sc = av_mallocz(sizeof(MOVStreamContext));
1865
    if (!sc) return AVERROR(ENOMEM);
1866 1867

    st->priv_data = sc;
1868
    st->codec->codec_type = AVMEDIA_TYPE_DATA;
1869
    sc->ffindex = st->index;
1870

1871 1872 1873 1874
    if ((ret = mov_read_default(c, pb, atom)) < 0)
        return ret;

    /* sanity checks */
1875 1876
    if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
                            (!sc->sample_size && !sc->sample_count))) {
1877 1878
        av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
               st->index);
1879 1880
        return 0;
    }
1881

1882
    if (sc->time_scale <= 0) {
1883
        av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", st->index);
1884
        sc->time_scale = c->time_scale;
1885
        if (sc->time_scale <= 0)
1886 1887
            sc->time_scale = 1;
    }
1888

1889
    avpriv_set_pts_info(st, 64, 1, sc->time_scale);
1890

1891
    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1892 1893 1894
        !st->codec->frame_size && sc->stts_count == 1) {
        st->codec->frame_size = av_rescale(sc->stts_data[0].duration,
                                           st->codec->sample_rate, sc->time_scale);
L
Luca Barbato 已提交
1895
        av_dlog(c->fc, "frame size %d\n", st->codec->frame_size);
1896
    }
1897 1898 1899 1900

    mov_build_index(c, st);

    if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
1901
        MOVDref *dref = &sc->drefs[sc->dref_id - 1];
1902
        if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback) < 0)
1903 1904 1905 1906 1907
            av_log(c->fc, AV_LOG_ERROR,
                   "stream %d, error opening alias: path='%s', dir='%s', "
                   "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n",
                   st->index, dref->path, dref->dir, dref->filename,
                   dref->volume, dref->nlvl_from, dref->nlvl_to);
1908 1909 1910
    } else
        sc->pb = c->fc->pb;

1911
    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
1912 1913 1914 1915
        if (!st->sample_aspect_ratio.num &&
            (st->codec->width != sc->width || st->codec->height != sc->height)) {
            st->sample_aspect_ratio = av_d2q(((double)st->codec->height * sc->width) /
                                             ((double)st->codec->width * sc->height), INT_MAX);
1916 1917 1918 1919
        }

        av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
                  sc->time_scale*st->nb_frames, st->duration, INT_MAX);
1920 1921 1922 1923

        if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
            av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
                      sc->time_scale, sc->stts_data[0].duration, INT_MAX);
1924 1925
    }

1926
    switch (st->codec->codec_id) {
1927
#if CONFIG_H261_DECODER
1928 1929
    case CODEC_ID_H261:
#endif
1930
#if CONFIG_H263_DECODER
1931 1932
    case CODEC_ID_H263:
#endif
1933 1934 1935
#if CONFIG_H264_DECODER
    case CODEC_ID_H264:
#endif
1936
#if CONFIG_MPEG4_DECODER
1937 1938
    case CODEC_ID_MPEG4:
#endif
1939
        st->codec->width = 0; /* let decoder init width/height */
1940 1941 1942
        st->codec->height= 0;
        break;
    }
B
Baptiste Coudurier 已提交
1943 1944 1945

    /* Do not need those anymore. */
    av_freep(&sc->chunk_offsets);
1946
    av_freep(&sc->stsc_data);
B
Baptiste Coudurier 已提交
1947 1948 1949
    av_freep(&sc->sample_sizes);
    av_freep(&sc->keyframes);
    av_freep(&sc->stts_data);
1950
    av_freep(&sc->stps_data);
B
Baptiste Coudurier 已提交
1951

1952
    return 0;
1953 1954
}

1955
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1956 1957 1958 1959 1960 1961 1962 1963
{
    int ret;
    c->itunes_metadata = 1;
    ret = mov_read_default(c, pb, atom);
    c->itunes_metadata = 0;
    return ret;
}

1964
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1965
{
1966
    while (atom.size > 8) {
1967
        uint32_t tag = avio_rl32(pb);
1968 1969
        atom.size -= 4;
        if (tag == MKTAG('h','d','l','r')) {
A
Anton Khirnov 已提交
1970
            avio_seek(pb, -8, SEEK_CUR);
1971 1972 1973 1974 1975
            atom.size += 8;
            return mov_read_default(c, pb, atom);
        }
    }
    return 0;
1976 1977
}

1978
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1979
{
1980 1981 1982 1983 1984
    int i;
    int width;
    int height;
    int64_t disp_transform[2];
    int display_matrix[3][2];
1985 1986 1987 1988 1989 1990 1991 1992
    AVStream *st;
    MOVStreamContext *sc;
    int version;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;
1993

1994 1995
    version = avio_r8(pb);
    avio_rb24(pb); /* flags */
1996 1997 1998 1999 2000 2001 2002
    /*
    MOV_TRACK_ENABLED 0x0001
    MOV_TRACK_IN_MOVIE 0x0002
    MOV_TRACK_IN_PREVIEW 0x0004
    MOV_TRACK_IN_POSTER 0x0008
    */

B
Baptiste Coudurier 已提交
2003
    if (version == 1) {
2004 2005
        avio_rb64(pb);
        avio_rb64(pb);
B
Baptiste Coudurier 已提交
2006
    } else {
2007 2008
        avio_rb32(pb); /* creation time */
        avio_rb32(pb); /* modification time */
B
Baptiste Coudurier 已提交
2009
    }
2010 2011
    st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
    avio_rb32(pb); /* reserved */
2012

2013
    /* highlevel (considering edits) duration in movie timebase */
2014 2015 2016
    (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
    avio_rb32(pb); /* reserved */
    avio_rb32(pb); /* reserved */
2017

2018 2019 2020 2021
    avio_rb16(pb); /* layer */
    avio_rb16(pb); /* alternate group */
    avio_rb16(pb); /* volume */
    avio_rb16(pb); /* reserved */
2022

2023 2024 2025 2026
    //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
    // they're kept in fixed point format through all calculations
    // ignore u,v,z b/c we don't need the scale factor to calc aspect ratio
    for (i = 0; i < 3; i++) {
2027 2028 2029
        display_matrix[i][0] = avio_rb32(pb);   // 16.16 fixed point
        display_matrix[i][1] = avio_rb32(pb);   // 16.16 fixed point
        avio_rb32(pb);           // 2.30 fixed point (not used)
2030
    }
2031

2032 2033
    width = avio_rb32(pb);       // 16.16 fixed point track width
    height = avio_rb32(pb);      // 16.16 fixed point track height
2034 2035
    sc->width = width >> 16;
    sc->height = height >> 16;
2036

2037
    // transform the display width/height according to the matrix
2038
    // skip this if the display matrix is the default identity matrix
2039
    // or if it is rotating the picture, ex iPhone 3GS
2040 2041
    // to keep the same scale, use [width height 1<<16]
    if (width && height &&
2042 2043 2044 2045 2046
        ((display_matrix[0][0] != 65536  ||
          display_matrix[1][1] != 65536) &&
         !display_matrix[0][1] &&
         !display_matrix[1][0] &&
         !display_matrix[2][0] && !display_matrix[2][1])) {
2047 2048 2049 2050 2051 2052 2053
        for (i = 0; i < 2; i++)
            disp_transform[i] =
                (int64_t)  width  * display_matrix[0][i] +
                (int64_t)  height * display_matrix[1][i] +
                ((int64_t) display_matrix[2][i] << 16);

        //sample aspect ratio is new width/height divided by old width/height
2054
        st->sample_aspect_ratio = av_d2q(
2055 2056 2057
            ((double) disp_transform[0] * height) /
            ((double) disp_transform[1] * width), INT_MAX);
    }
2058 2059 2060
    return 0;
}

2061
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
2062 2063 2064 2065 2066
{
    MOVFragment *frag = &c->fragment;
    MOVTrackExt *trex = NULL;
    int flags, track_id, i;

2067 2068
    avio_r8(pb); /* version */
    flags = avio_rb24(pb);
B
Baptiste Coudurier 已提交
2069

2070
    track_id = avio_rb32(pb);
2071
    if (!track_id)
B
Baptiste Coudurier 已提交
2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083
        return -1;
    frag->track_id = track_id;
    for (i = 0; i < c->trex_count; i++)
        if (c->trex_data[i].track_id == frag->track_id) {
            trex = &c->trex_data[i];
            break;
        }
    if (!trex) {
        av_log(c->fc, AV_LOG_ERROR, "could not find corresponding trex\n");
        return -1;
    }

2084
    if (flags & 0x01) frag->base_data_offset = avio_rb64(pb);
B
Baptiste Coudurier 已提交
2085
    else              frag->base_data_offset = frag->moof_offset;
2086
    if (flags & 0x02) frag->stsd_id          = avio_rb32(pb);
B
Baptiste Coudurier 已提交
2087 2088
    else              frag->stsd_id          = trex->stsd_id;

2089 2090 2091
    frag->duration = flags & 0x08 ? avio_rb32(pb) : trex->duration;
    frag->size     = flags & 0x10 ? avio_rb32(pb) : trex->size;
    frag->flags    = flags & 0x20 ? avio_rb32(pb) : trex->flags;
L
Luca Barbato 已提交
2092
    av_dlog(c->fc, "frag flags 0x%x\n", frag->flags);
B
Baptiste Coudurier 已提交
2093 2094 2095
    return 0;
}

2096
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
D
David Conrad 已提交
2097
{
2098
    c->chapter_track = avio_rb32(pb);
D
David Conrad 已提交
2099 2100 2101
    return 0;
}

2102
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
2103 2104 2105 2106 2107
{
    MOVTrackExt *trex;

    if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
        return -1;
2108 2109
    trex = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data));
    if (!trex)
B
Baptiste Coudurier 已提交
2110
        return AVERROR(ENOMEM);
2111
    c->trex_data = trex;
B
Baptiste Coudurier 已提交
2112
    trex = &c->trex_data[c->trex_count++];
2113 2114 2115 2116 2117 2118 2119
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    trex->track_id = avio_rb32(pb);
    trex->stsd_id  = avio_rb32(pb);
    trex->duration = avio_rb32(pb);
    trex->size     = avio_rb32(pb);
    trex->flags    = avio_rb32(pb);
B
Baptiste Coudurier 已提交
2120 2121 2122
    return 0;
}

2123
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
2124 2125
{
    MOVFragment *frag = &c->fragment;
2126
    AVStream *st = NULL;
2127
    MOVStreamContext *sc;
2128
    MOVStts *ctts_data;
B
Baptiste Coudurier 已提交
2129 2130 2131 2132 2133 2134
    uint64_t offset;
    int64_t dts;
    int data_offset = 0;
    unsigned entries, first_sample_flags = frag->flags;
    int flags, distance, i;

2135 2136 2137 2138 2139 2140 2141 2142
    for (i = 0; i < c->fc->nb_streams; i++) {
        if (c->fc->streams[i]->id == frag->track_id) {
            st = c->fc->streams[i];
            break;
        }
    }
    if (!st) {
        av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %d\n", frag->track_id);
2143
        return -1;
2144
    }
2145
    sc = st->priv_data;
B
Baptiste Coudurier 已提交
2146 2147
    if (sc->pseudo_stream_id+1 != frag->stsd_id)
        return 0;
2148 2149 2150
    avio_r8(pb); /* version */
    flags = avio_rb24(pb);
    entries = avio_rb32(pb);
L
Luca Barbato 已提交
2151
    av_dlog(c->fc, "flags 0x%x entries %d\n", flags, entries);
2152 2153 2154 2155 2156 2157 2158 2159 2160 2161

    /* Always assume the presence of composition time offsets.
     * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following.
     *  1) in the initial movie, there are no samples.
     *  2) in the first movie fragment, there is only one sample without composition time offset.
     *  3) in the subsequent movie fragments, there are samples with composition time offset. */
    if (!sc->ctts_count && sc->sample_count)
    {
        /* Complement ctts table if moov atom doesn't have ctts atom. */
        ctts_data = av_malloc(sizeof(*sc->ctts_data));
2162
        if (!ctts_data)
B
Baptiste Coudurier 已提交
2163
            return AVERROR(ENOMEM);
2164
        sc->ctts_data = ctts_data;
2165 2166 2167
        sc->ctts_data[sc->ctts_count].count = sc->sample_count;
        sc->ctts_data[sc->ctts_count].duration = 0;
        sc->ctts_count++;
B
Baptiste Coudurier 已提交
2168
    }
2169 2170 2171 2172 2173 2174 2175 2176 2177 2178
    if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
        return -1;
    ctts_data = av_realloc(sc->ctts_data,
                           (entries+sc->ctts_count)*sizeof(*sc->ctts_data));
    if (!ctts_data)
        return AVERROR(ENOMEM);
    sc->ctts_data = ctts_data;

    if (flags & 0x001) data_offset        = avio_rb32(pb);
    if (flags & 0x004) first_sample_flags = avio_rb32(pb);
2179
    dts = st->duration - sc->time_offset;
B
Baptiste Coudurier 已提交
2180 2181
    offset = frag->base_data_offset + data_offset;
    distance = 0;
L
Luca Barbato 已提交
2182
    av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags);
B
Baptiste Coudurier 已提交
2183 2184 2185 2186 2187 2188
    for (i = 0; i < entries; i++) {
        unsigned sample_size = frag->size;
        int sample_flags = i ? frag->flags : first_sample_flags;
        unsigned sample_duration = frag->duration;
        int keyframe;

2189 2190 2191
        if (flags & 0x100) sample_duration = avio_rb32(pb);
        if (flags & 0x200) sample_size     = avio_rb32(pb);
        if (flags & 0x400) sample_flags    = avio_rb32(pb);
2192 2193 2194
        sc->ctts_data[sc->ctts_count].count = 1;
        sc->ctts_data[sc->ctts_count].duration = (flags & 0x800) ? avio_rb32(pb) : 0;
        sc->ctts_count++;
2195
        if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO ||
B
Baptiste Coudurier 已提交
2196 2197 2198 2199
             (flags & 0x004 && !i && !sample_flags) || sample_flags & 0x2000000))
            distance = 0;
        av_add_index_entry(st, offset, dts, sample_size, distance,
                           keyframe ? AVINDEX_KEYFRAME : 0);
L
Luca Barbato 已提交
2200
        av_dlog(c->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
B
Baptiste Coudurier 已提交
2201 2202 2203
                "size %d, distance %d, keyframe %d\n", st->index, sc->sample_count+i,
                offset, dts, sample_size, distance, keyframe);
        distance++;
2204
        dts += sample_duration;
B
Baptiste Coudurier 已提交
2205 2206 2207
        offset += sample_size;
    }
    frag->moof_offset = offset;
2208
    st->duration = dts + sc->time_offset;
B
Baptiste Coudurier 已提交
2209 2210 2211
    return 0;
}

2212 2213 2214
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
/* like the files created with Adobe Premiere 5.0, for samples see */
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
2215
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2216 2217 2218 2219 2220
{
    int err;

    if (atom.size < 8)
        return 0; /* continue */
2221
    if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
2222
        avio_skip(pb, atom.size - 4);
2223 2224
        return 0;
    }
2225
    atom.type = avio_rl32(pb);
2226
    atom.size -= 8;
2227
    if (atom.type != MKTAG('m','d','a','t')) {
2228
        avio_skip(pb, atom.size);
2229 2230 2231 2232 2233 2234
        return 0;
    }
    err = mov_read_mdat(c, pb, atom);
    return err;
}

2235
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2236
{
2237
#if CONFIG_ZLIB
2238
    AVIOContext ctx;
2239 2240
    uint8_t *cmov_data;
    uint8_t *moov_data; /* uncompressed data */
2241
    long cmov_len, moov_len;
2242
    int ret = -1;
2243

2244 2245
    avio_rb32(pb); /* dcom atom */
    if (avio_rl32(pb) != MKTAG('d','c','o','m'))
2246
        return -1;
2247
    if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
B
Benoit Fouet 已提交
2248
        av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !");
2249 2250
        return -1;
    }
2251 2252
    avio_rb32(pb); /* cmvd atom */
    if (avio_rl32(pb) != MKTAG('c','m','v','d'))
2253
        return -1;
2254
    moov_len = avio_rb32(pb); /* uncompressed size */
2255
    cmov_len = atom.size - 6 * 4;
2256

B
Baptiste Coudurier 已提交
2257
    cmov_data = av_malloc(cmov_len);
2258
    if (!cmov_data)
2259
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
2260
    moov_data = av_malloc(moov_len);
2261 2262
    if (!moov_data) {
        av_free(cmov_data);
2263
        return AVERROR(ENOMEM);
2264
    }
2265
    avio_read(pb, cmov_data, cmov_len);
2266
    if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
2267
        goto free_and_return;
2268
    if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
2269
        goto free_and_return;
2270
    atom.type = MKTAG('m','o','o','v');
2271 2272
    atom.size = moov_len;
    ret = mov_read_default(c, &ctx, atom);
2273
free_and_return:
2274 2275 2276
    av_free(moov_data);
    av_free(cmov_data);
    return ret;
2277 2278 2279
#else
    av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
    return -1;
2280
#endif
2281
}
2282

G
Gael Chardon 已提交
2283
/* edit list atom */
2284
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
G
Gael Chardon 已提交
2285
{
2286
    MOVStreamContext *sc;
2287
    int i, edit_count, version;
B
Baptiste Coudurier 已提交
2288

2289 2290 2291 2292
    if (c->fc->nb_streams < 1)
        return 0;
    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;

2293
    version = avio_r8(pb); /* version */
2294 2295
    avio_rb24(pb); /* flags */
    edit_count = avio_rb32(pb); /* entries */
B
Baptiste Coudurier 已提交
2296

2297
    if ((uint64_t)edit_count*12+8 > atom.size)
2298 2299
        return -1;

2300
    for (i=0; i<edit_count; i++){
2301 2302 2303 2304 2305 2306 2307
        int64_t time;
        int64_t duration;
        if (version == 1) {
            duration = avio_rb64(pb);
            time     = avio_rb64(pb);
        } else {
            duration = avio_rb32(pb); /* segment duration */
Y
Yusuke Nakamura 已提交
2308
            time     = (int32_t)avio_rb32(pb); /* media time */
2309
        }
2310
        avio_rb32(pb); /* Media rate */
2311 2312
        if (i == 0 && time >= -1) {
            sc->time_offset = time != -1 ? time : -duration;
2313
        }
B
Baptiste Coudurier 已提交
2314
    }
2315

2316
    if (edit_count > 1)
2317 2318 2319
        av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, "
               "a/v desync might occur, patch welcome\n");

L
Luca Barbato 已提交
2320
    av_dlog(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count);
B
Baptiste Coudurier 已提交
2321
    return 0;
G
Gael Chardon 已提交
2322 2323
}

2324
static const MOVParseTableEntry mov_default_parse_table[] = {
2325
{ MKTAG('a','v','s','s'), mov_read_extradata },
D
David Conrad 已提交
2326
{ MKTAG('c','h','p','l'), mov_read_chpl },
2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337
{ MKTAG('c','o','6','4'), mov_read_stco },
{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
{ MKTAG('d','i','n','f'), mov_read_default },
{ MKTAG('d','r','e','f'), mov_read_dref },
{ MKTAG('e','d','t','s'), mov_read_default },
{ MKTAG('e','l','s','t'), mov_read_elst },
{ MKTAG('e','n','d','a'), mov_read_enda },
{ MKTAG('f','i','e','l'), mov_read_extradata },
{ MKTAG('f','t','y','p'), mov_read_ftyp },
{ MKTAG('g','l','b','l'), mov_read_glbl },
{ MKTAG('h','d','l','r'), mov_read_hdlr },
2338
{ MKTAG('i','l','s','t'), mov_read_ilst },
2339 2340 2341 2342
{ MKTAG('j','p','2','h'), mov_read_extradata },
{ MKTAG('m','d','a','t'), mov_read_mdat },
{ MKTAG('m','d','h','d'), mov_read_mdhd },
{ MKTAG('m','d','i','a'), mov_read_default },
2343
{ MKTAG('m','e','t','a'), mov_read_meta },
2344 2345 2346 2347 2348 2349 2350 2351
{ MKTAG('m','i','n','f'), mov_read_default },
{ MKTAG('m','o','o','f'), mov_read_moof },
{ MKTAG('m','o','o','v'), mov_read_moov },
{ MKTAG('m','v','e','x'), mov_read_default },
{ MKTAG('m','v','h','d'), mov_read_mvhd },
{ MKTAG('S','M','I',' '), mov_read_smi }, /* Sorenson extension ??? */
{ MKTAG('a','l','a','c'), mov_read_extradata }, /* alac specific atom */
{ MKTAG('a','v','c','C'), mov_read_glbl },
2352
{ MKTAG('p','a','s','p'), mov_read_pasp },
2353 2354
{ MKTAG('s','t','b','l'), mov_read_default },
{ MKTAG('s','t','c','o'), mov_read_stco },
2355
{ MKTAG('s','t','p','s'), mov_read_stps },
M
Martin Storsjö 已提交
2356
{ MKTAG('s','t','r','f'), mov_read_strf },
2357 2358 2359 2360 2361
{ MKTAG('s','t','s','c'), mov_read_stsc },
{ MKTAG('s','t','s','d'), mov_read_stsd }, /* sample description */
{ MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */
{ MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */
{ MKTAG('s','t','t','s'), mov_read_stts },
2362
{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
2363 2364 2365 2366
{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
{ MKTAG('t','r','a','k'), mov_read_trak },
{ MKTAG('t','r','a','f'), mov_read_default },
D
David Conrad 已提交
2367 2368
{ MKTAG('t','r','e','f'), mov_read_default },
{ MKTAG('c','h','a','p'), mov_read_chap },
2369 2370
{ MKTAG('t','r','e','x'), mov_read_trex },
{ MKTAG('t','r','u','n'), mov_read_trun },
B
Baptiste Coudurier 已提交
2371
{ MKTAG('u','d','t','a'), mov_read_default },
2372 2373
{ MKTAG('w','a','v','e'), mov_read_wave },
{ MKTAG('e','s','d','s'), mov_read_esds },
2374
{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
2375
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
2376
{ MKTAG('w','f','e','x'), mov_read_wfex },
2377
{ MKTAG('c','m','o','v'), mov_read_cmov },
2378
{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
B
Baptiste Coudurier 已提交
2379
{ 0, NULL }
2380 2381
};

F
Fabrice Bellard 已提交
2382 2383
static int mov_probe(AVProbeData *p)
{
2384 2385
    unsigned int offset;
    uint32_t tag;
2386
    int score = 0;
2387

F
Fabrice Bellard 已提交
2388
    /* check file header */
2389
    offset = 0;
2390
    for (;;) {
2391 2392
        /* ignore invalid offset */
        if ((offset + 8) > (unsigned int)p->buf_size)
2393
            return score;
2394
        tag = AV_RL32(p->buf + offset + 4);
2395
        switch(tag) {
2396
        /* check for obvious tags */
2397 2398 2399 2400 2401
        case MKTAG('j','P',' ',' '): /* jpeg 2000 signature */
        case MKTAG('m','o','o','v'):
        case MKTAG('m','d','a','t'):
        case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
        case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
2402
        case MKTAG('f','t','y','p'):
2403
            return AVPROBE_SCORE_MAX;
2404
        /* those are more common words, so rate then a bit less */
2405 2406 2407 2408 2409
        case MKTAG('e','d','i','w'): /* xdcam files have reverted first tags */
        case MKTAG('w','i','d','e'):
        case MKTAG('f','r','e','e'):
        case MKTAG('j','u','n','k'):
        case MKTAG('p','i','c','t'):
2410
            return AVPROBE_SCORE_MAX - 5;
B
Baptiste Coudurier 已提交
2411
        case MKTAG(0x82,0x82,0x7f,0x7d):
2412 2413 2414
        case MKTAG('s','k','i','p'):
        case MKTAG('u','u','i','d'):
        case MKTAG('p','r','f','l'):
2415
            offset = AV_RB32(p->buf+offset) + offset;
2416 2417
            /* if we only find those cause probedata is too small at least rate them */
            score = AVPROBE_SCORE_MAX - 50;
2418 2419 2420
            break;
        default:
            /* unrecognized tag */
2421
            return score;
2422
        }
2423
    }
F
Fabrice Bellard 已提交
2424 2425
}

D
David Conrad 已提交
2426 2427 2428 2429 2430 2431 2432
// must be done after parsing all trak because there's no order requirement
static void mov_read_chapters(AVFormatContext *s)
{
    MOVContext *mov = s->priv_data;
    AVStream *st = NULL;
    MOVStreamContext *sc;
    int64_t cur_pos;
2433
    int i;
D
David Conrad 已提交
2434 2435 2436 2437 2438 2439 2440 2441 2442 2443 2444 2445 2446

    for (i = 0; i < s->nb_streams; i++)
        if (s->streams[i]->id == mov->chapter_track) {
            st = s->streams[i];
            break;
        }
    if (!st) {
        av_log(s, AV_LOG_ERROR, "Referenced QT chapter track not found\n");
        return;
    }

    st->discard = AVDISCARD_ALL;
    sc = st->priv_data;
2447
    cur_pos = avio_tell(sc->pb);
D
David Conrad 已提交
2448 2449 2450 2451

    for (i = 0; i < st->nb_index_entries; i++) {
        AVIndexEntry *sample = &st->index_entries[i];
        int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration;
2452 2453 2454
        uint8_t *title;
        uint16_t ch;
        int len, title_len;
D
David Conrad 已提交
2455

A
Anton Khirnov 已提交
2456
        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
D
David Conrad 已提交
2457 2458 2459 2460 2461
            av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
            goto finish;
        }

        // the first two bytes are the length of the title
2462
        len = avio_rb16(sc->pb);
D
David Conrad 已提交
2463 2464
        if (len > sample->size-2)
            continue;
2465 2466 2467
        title_len = 2*len + 1;
        if (!(title = av_mallocz(title_len)))
            goto finish;
D
David Conrad 已提交
2468 2469 2470 2471

        // The samples could theoretically be in any encoding if there's an encd
        // atom following, but in practice are only utf-8 or utf-16, distinguished
        // instead by the presence of a BOM
2472 2473 2474 2475 2476 2477 2478 2479 2480 2481 2482
        if (!len) {
            title[0] = 0;
        } else {
            ch = avio_rb16(sc->pb);
            if (ch == 0xfeff)
                avio_get_str16be(sc->pb, len, title, title_len);
            else if (ch == 0xfffe)
                avio_get_str16le(sc->pb, len, title, title_len);
            else {
                AV_WB16(title, ch);
                if (len == 1 || len == 2)
2483
                    title[len] = 0;
2484 2485 2486
                else
                    avio_get_str(sc->pb, len - 2, title + 2, title_len - 2);
            }
D
David Conrad 已提交
2487 2488
        }

2489
        avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
2490
        av_freep(&title);
D
David Conrad 已提交
2491 2492
    }
finish:
A
Anton Khirnov 已提交
2493
    avio_seek(sc->pb, cur_pos, SEEK_SET);
D
David Conrad 已提交
2494 2495
}

Z
Zdenek Kabelac 已提交
2496
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
2497
{
2498
    MOVContext *mov = s->priv_data;
2499
    AVIOContext *pb = s->pb;
B
Baptiste Coudurier 已提交
2500
    int err;
2501
    MOVAtom atom = { AV_RL32("root") };
2502 2503

    mov->fc = s;
2504
    /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
2505
    if (pb->seekable)
A
Anton Khirnov 已提交
2506
        atom.size = avio_size(pb);
2507
    else
B
Baptiste Coudurier 已提交
2508
        atom.size = INT64_MAX;
2509 2510

    /* check MOV header */
B
Baptiste Coudurier 已提交
2511 2512 2513 2514 2515 2516
    if ((err = mov_read_default(mov, pb, atom)) < 0) {
        av_log(s, AV_LOG_ERROR, "error reading header: %d\n", err);
        return err;
    }
    if (!mov->found_moov) {
        av_log(s, AV_LOG_ERROR, "moov atom not found\n");
2517
        return -1;
2518
    }
2519
    av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
2520

2521
    if (pb->seekable && mov->chapter_track > 0)
D
David Conrad 已提交
2522 2523
        mov_read_chapters(s);

2524 2525 2526
    return 0;
}

2527
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
2528
{
2529
    AVIndexEntry *sample = NULL;
2530
    int64_t best_dts = INT64_MAX;
2531
    int i;
B
Baptiste Coudurier 已提交
2532
    for (i = 0; i < s->nb_streams; i++) {
2533 2534
        AVStream *avst = s->streams[i];
        MOVStreamContext *msc = avst->priv_data;
2535
        if (msc->pb && msc->current_sample < avst->nb_index_entries) {
2536
            AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
2537
            int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
L
Luca Barbato 已提交
2538
            av_dlog(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
2539 2540
            if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) ||
                (s->pb->seekable &&
2541
                 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
B
Baptiste Coudurier 已提交
2542
                 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
2543
                  (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
2544 2545
                sample = current_sample;
                best_dts = dts;
2546
                *st = avst;
2547
            }
2548 2549
        }
    }
2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560 2561
    return sample;
}

static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    MOVContext *mov = s->priv_data;
    MOVStreamContext *sc;
    AVIndexEntry *sample;
    AVStream *st = NULL;
    int ret;
 retry:
    sample = mov_find_next_sample(s, &st);
2562 2563
    if (!sample) {
        mov->found_mdat = 0;
2564
        if (s->pb->seekable||
2565
            mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
A
Anton Khirnov 已提交
2566
            s->pb->eof_reached)
B
Baptiste Coudurier 已提交
2567
            return AVERROR_EOF;
2568
        av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
2569 2570
        goto retry;
    }
2571
    sc = st->priv_data;
2572 2573
    /* must be done just before reading, to avoid infinite loop on sample */
    sc->current_sample++;
2574 2575

    if (st->discard != AVDISCARD_ALL) {
A
Anton Khirnov 已提交
2576
        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
R
Reimar Döffinger 已提交
2577 2578 2579 2580 2581
            av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
                   sc->ffindex, sample->pos);
            return -1;
        }
        ret = av_get_packet(sc->pb, pkt, sample->size);
2582 2583
        if (ret < 0)
            return ret;
2584 2585 2586 2587 2588 2589 2590 2591 2592 2593 2594
        if (sc->has_palette) {
            uint8_t *pal;

            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
            if (!pal) {
                av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
            } else {
                memcpy(pal, sc->palette, AVPALETTE_SIZE);
                sc->has_palette = 0;
            }
        }
R
Reimar Döffinger 已提交
2595 2596
#if CONFIG_DV_DEMUXER
        if (mov->dv_demux && sc->dv_audio_container) {
2597
            avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);
R
Reimar Döffinger 已提交
2598 2599
            av_free(pkt->data);
            pkt->size = 0;
2600
            ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
R
Reimar Döffinger 已提交
2601 2602 2603
            if (ret < 0)
                return ret;
        }
2604
#endif
2605 2606
    }

2607 2608 2609
    pkt->stream_index = sc->ffindex;
    pkt->dts = sample->timestamp;
    if (sc->ctts_data) {
2610
        pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
2611
        /* update ctts context */
2612 2613 2614 2615 2616
        sc->ctts_sample++;
        if (sc->ctts_index < sc->ctts_count &&
            sc->ctts_data[sc->ctts_index].count == sc->ctts_sample) {
            sc->ctts_index++;
            sc->ctts_sample = 0;
2617
        }
2618 2619
        if (sc->wrong_dts)
            pkt->dts = AV_NOPTS_VALUE;
2620
    } else {
2621
        int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
2622 2623
            st->index_entries[sc->current_sample].timestamp : st->duration;
        pkt->duration = next_dts - pkt->dts;
2624
        pkt->pts = pkt->dts;
2625
    }
2626 2627
    if (st->discard == AVDISCARD_ALL)
        goto retry;
2628
    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
2629
    pkt->pos = sample->pos;
L
Luca Barbato 已提交
2630
    av_dlog(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64", duration %d\n",
2631
            pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration);
2632 2633
    return 0;
}
2634

2635
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
2636 2637 2638 2639
{
    MOVStreamContext *sc = st->priv_data;
    int sample, time_sample;
    int i;
2640

2641
    sample = av_index_search_timestamp(st, timestamp, flags);
L
Luca Barbato 已提交
2642
    av_dlog(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
2643 2644
    if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
        sample = 0;
2645 2646 2647
    if (sample < 0) /* not sure what to do */
        return -1;
    sc->current_sample = sample;
L
Luca Barbato 已提交
2648
    av_dlog(s, "stream %d, found sample %d\n", st->index, sc->current_sample);
2649 2650 2651 2652
    /* adjust ctts index */
    if (sc->ctts_data) {
        time_sample = 0;
        for (i = 0; i < sc->ctts_count; i++) {
2653 2654
            int next = time_sample + sc->ctts_data[i].count;
            if (next > sc->current_sample) {
2655 2656
                sc->ctts_index = i;
                sc->ctts_sample = sc->current_sample - time_sample;
2657
                break;
2658
            }
2659
            time_sample = next;
2660 2661
        }
    }
2662
    return sample;
2663 2664
}

2665
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
G
Gael Chardon 已提交
2666
{
2667 2668 2669 2670
    AVStream *st;
    int64_t seek_timestamp, timestamp;
    int sample;
    int i;
G
Gael Chardon 已提交
2671

2672
    if (stream_index >= s->nb_streams)
G
Gael Chardon 已提交
2673
        return -1;
2674 2675
    if (sample_time < 0)
        sample_time = 0;
G
Gael Chardon 已提交
2676

2677
    st = s->streams[stream_index];
2678
    sample = mov_seek_stream(s, st, sample_time, flags);
2679
    if (sample < 0)
G
Gael Chardon 已提交
2680 2681
        return -1;

2682 2683
    /* adjust seek timestamp to found sample timestamp */
    seek_timestamp = st->index_entries[sample].timestamp;
G
Gael Chardon 已提交
2684

2685 2686
    for (i = 0; i < s->nb_streams; i++) {
        st = s->streams[i];
2687
        if (stream_index == i)
2688
            continue;
G
Gael Chardon 已提交
2689

2690
        timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
2691
        mov_seek_stream(s, st, timestamp, flags);
2692
    }
G
Gael Chardon 已提交
2693 2694 2695
    return 0;
}

Z
Zdenek Kabelac 已提交
2696
static int mov_read_close(AVFormatContext *s)
2697
{
2698
    MOVContext *mov = s->priv_data;
2699 2700 2701
    int i, j;

    for (i = 0; i < s->nb_streams; i++) {
2702 2703
        AVStream *st = s->streams[i];
        MOVStreamContext *sc = st->priv_data;
2704

2705
        av_freep(&sc->ctts_data);
2706
        for (j = 0; j < sc->drefs_count; j++) {
2707
            av_freep(&sc->drefs[j].path);
2708 2709
            av_freep(&sc->drefs[j].dir);
        }
2710 2711
        av_freep(&sc->drefs);
        if (sc->pb && sc->pb != s->pb)
2712
            avio_close(sc->pb);
2713
    }
2714 2715

    if (mov->dv_demux) {
2716
        for (i = 0; i < mov->dv_fctx->nb_streams; i++) {
2717 2718 2719 2720 2721 2722
            av_freep(&mov->dv_fctx->streams[i]->codec);
            av_freep(&mov->dv_fctx->streams[i]);
        }
        av_freep(&mov->dv_fctx);
        av_freep(&mov->dv_demux);
    }
2723

B
Baptiste Coudurier 已提交
2724
    av_freep(&mov->trex_data);
2725

2726 2727 2728
    return 0;
}

2729
AVInputFormat ff_mov_demuxer = {
2730 2731 2732 2733 2734 2735 2736 2737
    .name           = "mov,mp4,m4a,3gp,3g2,mj2",
    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
    .priv_data_size = sizeof(MOVContext),
    .read_probe     = mov_probe,
    .read_header    = mov_read_header,
    .read_packet    = mov_read_packet,
    .read_close     = mov_read_close,
    .read_seek      = mov_read_seek,
2738
};