mov.c 140.7 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 7 8
 * first version by Francois Revol <revol@free.fr>
 * seek function by Gael Chardon <gael.dev@4now.net>
 *
9 10 11
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
F
Fabrice Bellard 已提交
12 13
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
14
 * version 2.1 of the License, or (at your option) any later version.
15
 *
16
 * FFmpeg is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
F
Fabrice Bellard 已提交
18 19
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
20
 *
F
Fabrice Bellard 已提交
21
 * You should have received a copy of the GNU Lesser General Public
22
 * License along with FFmpeg; if not, write to the Free Software
23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
 */
25

26
#include <inttypes.h>
27
#include <limits.h>
28
#include <stdint.h>
29

30
#include "libavutil/attributes.h"
31
#include "libavutil/channel_layout.h"
32
#include "libavutil/display.h"
33
#include "libavutil/intreadwrite.h"
34
#include "libavutil/intfloat.h"
35
#include "libavutil/mathematics.h"
36
#include "libavutil/time_internal.h"
37
#include "libavutil/avstring.h"
38
#include "libavutil/dict.h"
39
#include "libavutil/opt.h"
40
#include "libavutil/timecode.h"
41
#include "libavcodec/ac3tab.h"
42
#include "avformat.h"
43
#include "internal.h"
44
#include "avio_internal.h"
45
#include "riff.h"
46
#include "isom.h"
47
#include "libavcodec/get_bits.h"
R
Raivo Hool 已提交
48
#include "id3v1.h"
49
#include "mov_chan.h"
50
#include "replaygain.h"
51

52
#if CONFIG_ZLIB
53 54 55
#include <zlib.h>
#endif

56 57
#include "qtpalette.h"

G
Gael Chardon 已提交
58

59 60 61
#undef NDEBUG
#include <assert.h>

62 63 64
/* those functions parse an atom */
/* links atom IDs to parse functions */
typedef struct MOVParseTableEntry {
65
    uint32_t type;
66
    int (*parse)(MOVContext *ctx, AVIOContext *pb, MOVAtom atom);
67 68
} MOVParseTableEntry;

69
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
70
static int mov_read_mfra(MOVContext *c, AVIOContext *f);
71

72 73
static int mov_metadata_track_or_disc_number(MOVContext *c, AVIOContext *pb,
                                             unsigned len, const char *key)
B
Baptiste Coudurier 已提交
74 75 76
{
    char buf[16];

77
    short current, total = 0;
78
    avio_rb16(pb); // unknown
79
    current = avio_rb16(pb);
80 81
    if (len >= 6)
        total = avio_rb16(pb);
82 83 84 85
    if (!total)
        snprintf(buf, sizeof(buf), "%d", current);
    else
        snprintf(buf, sizeof(buf), "%d/%d", current, total);
86
    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
87
    av_dict_set(&c->fc->metadata, key, buf, 0);
B
Baptiste Coudurier 已提交
88 89 90 91

    return 0;
}

92 93
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
                                            unsigned len, const char *key)
94
{
95 96 97 98
    /* bypass padding bytes */
    avio_r8(pb);
    avio_r8(pb);
    avio_r8(pb);
99

100
    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
101
    av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
102

103
    return 0;
104 105
}

106 107
static int mov_metadata_int8_no_padding(MOVContext *c, AVIOContext *pb,
                                        unsigned len, const char *key)
108
{
109
    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
110
    av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
111

112
    return 0;
113 114
}

R
Raivo Hool 已提交
115
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
116 117
                             unsigned len, const char *key)
{
R
Raivo Hool 已提交
118
    short genre;
119

R
Raivo Hool 已提交
120
    avio_r8(pb); // unknown
121

R
Raivo Hool 已提交
122 123 124
    genre = avio_r8(pb);
    if (genre < 1 || genre > ID3v1_GENRE_MAX)
        return 0;
125
    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
126
    av_dict_set(&c->fc->metadata, key, ff_id3v1_genre_str[genre-1], 0);
R
Raivo Hool 已提交
127 128

    return 0;
129 130
}

131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
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,
};

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

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

A
Anton Khirnov 已提交
168 169 170 171 172
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
{
    AVPacket pkt;
    AVStream *st;
    MOVStreamContext *sc;
173
    enum AVCodecID id;
A
Anton Khirnov 已提交
174 175 176
    int ret;

    switch (type) {
177 178 179
    case 0xd:  id = AV_CODEC_ID_MJPEG; break;
    case 0xe:  id = AV_CODEC_ID_PNG;   break;
    case 0x1b: id = AV_CODEC_ID_BMP;   break;
A
Anton Khirnov 已提交
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
    default:
        av_log(c->fc, AV_LOG_WARNING, "Unknown cover type: 0x%x.\n", type);
        avio_skip(pb, len);
        return 0;
    }

    st = avformat_new_stream(c->fc, NULL);
    if (!st)
        return AVERROR(ENOMEM);
    sc = av_mallocz(sizeof(*sc));
    if (!sc)
        return AVERROR(ENOMEM);
    st->priv_data = sc;

    ret = av_get_packet(pb, &pkt, len);
    if (ret < 0)
        return ret;

    st->disposition              |= AV_DISPOSITION_ATTACHED_PIC;

    st->attached_pic              = pkt;
    st->attached_pic.stream_index = st->index;
    st->attached_pic.flags       |= AV_PKT_FLAG_KEY;

    st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
    st->codec->codec_id   = id;

    return 0;
}

210 211 212 213 214 215 216 217 218 219 220
static int mov_metadata_raw(MOVContext *c, AVIOContext *pb,
                            unsigned len, const char *key)
{
    char *value = av_malloc(len + 1);
    if (!value)
        return AVERROR(ENOMEM);
    avio_read(pb, value, len);
    value[len] = 0;
    return av_dict_set(&c->fc->metadata, key, value, AV_DICT_DONT_STRDUP_VAL);
}

221 222 223 224 225
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
{
    char language[4] = { 0 };
    char buf[100];
    uint16_t langcode = 0;
226
    double longitude, latitude;
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
    const char *key = "location";

    if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4)
        return AVERROR_INVALIDDATA;

    avio_skip(pb, 4); // version+flags
    langcode = avio_rb16(pb);
    ff_mov_lang_to_iso639(langcode, language);
    len -= 6;

    len -= avio_get_str(pb, len, buf, sizeof(buf)); // place name
    if (len < 1)
        return AVERROR_INVALIDDATA;
    avio_skip(pb, 1); // role
    len -= 1;

    if (len < 14)
        return AVERROR_INVALIDDATA;
    longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
    latitude  = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);

    // Try to output in the same format as the ?xyz field
    snprintf(buf, sizeof(buf), "%+08.4f%+09.4f/", latitude, longitude);
    if (*language && strcmp(language, "und")) {
        char key2[16];
        snprintf(key2, sizeof(key2), "%s-%s", key, language);
        av_dict_set(&c->fc->metadata, key2, buf, 0);
    }
255
    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
256 257 258
    return av_dict_set(&c->fc->metadata, key, buf, 0);
}

259
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
260 261
{
    char tmp_key[5];
262
    char key2[32], language[4] = {0};
263
    char *str = NULL;
264
    const char *key = NULL;
265
    uint16_t langcode = 0;
266
    uint32_t data_type = 0, str_size, str_size_alloc;
267
    int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
268 269

    switch (atom.type) {
R
Raivo Hool 已提交
270
    case MKTAG( 'a','A','R','T'): key = "album_artist";    break;
271 272
    case MKTAG( 'c','p','i','l'): key = "compilation";
        parse = mov_metadata_int8_no_padding; break;
273 274
    case MKTAG( 'c','p','r','t'): key = "copyright"; break;
    case MKTAG( 'd','e','s','c'): key = "description"; break;
275 276
    case MKTAG( 'd','i','s','k'): key = "disc";
        parse = mov_metadata_track_or_disc_number; break;
R
Raivo Hool 已提交
277 278
    case MKTAG( 'g','n','r','e'): key = "genre";
        parse = mov_metadata_gnre; break;
279 280
    case MKTAG( 'h','d','v','d'): key = "hd_video";
        parse = mov_metadata_int8_no_padding; break;
281
    case MKTAG( 'l','d','e','s'): key = "synopsis";  break;
282 283
    case MKTAG( 'l','o','c','i'):
        return mov_metadata_loci(c, pb, atom.size);
284 285
    case MKTAG( 'p','g','a','p'): key = "gapless_playback";
        parse = mov_metadata_int8_no_padding; break;
286 287 288 289
    case MKTAG( '@','P','R','M'):
        return mov_metadata_raw(c, pb, atom.size, "premiere_version");
    case MKTAG( '@','P','R','Q'):
        return mov_metadata_raw(c, pb, atom.size, "quicktime_version");
290 291
    case MKTAG( 's','t','i','k'): key = "media_type";
        parse = mov_metadata_int8_no_padding; break;
B
Baptiste Coudurier 已提交
292
    case MKTAG( 't','r','k','n'): key = "track";
293
        parse = mov_metadata_track_or_disc_number; break;
294
    case MKTAG( 't','v','e','n'): key = "episode_id"; break;
295
    case MKTAG( 't','v','e','s'): key = "episode_sort";
296
        parse = mov_metadata_int8_bypass_padding; break;
297 298
    case MKTAG( 't','v','n','n'): key = "network";   break;
    case MKTAG( 't','v','s','h'): key = "show";      break;
299
    case MKTAG( 't','v','s','n'): key = "season_number";
300
        parse = mov_metadata_int8_bypass_padding; break;
M
Marek Fort 已提交
301 302
    case MKTAG( 'X','M','P','_'):
        return mov_metadata_raw(c, pb, atom.size, "xmp");
303 304 305 306 307 308 309 310
    case MKTAG(0xa9,'A','R','T'): key = "artist";    break;
    case MKTAG(0xa9,'a','l','b'): key = "album";     break;
    case MKTAG(0xa9,'a','u','t'): key = "artist";    break;
    case MKTAG(0xa9,'c','m','t'): key = "comment";   break;
    case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
    case MKTAG(0xa9,'d','a','y'): key = "date";      break;
    case MKTAG(0xa9,'e','n','c'): key = "encoder";   break;
    case MKTAG(0xa9,'g','e','n'): key = "genre";     break;
311
    case MKTAG(0xa9,'g','r','p'): key = "grouping";  break;
312
    case MKTAG(0xa9,'i','n','f'): key = "comment";   break;
313 314 315
    case MKTAG(0xa9,'l','y','r'): key = "lyrics";    break;
    case MKTAG(0xa9,'m','a','k'): key = "make";      break;
    case MKTAG(0xa9,'m','o','d'): key = "model";     break;
316 317 318 319 320
    case MKTAG(0xa9,'n','a','m'): key = "title";     break;
    case MKTAG(0xa9,'s','w','r'): key = "encoder";   break;
    case MKTAG(0xa9,'t','o','o'): key = "encoder";   break;
    case MKTAG(0xa9,'w','r','t'): key = "composer";  break;
    case MKTAG(0xa9,'x','y','z'): key = "location";  break;
321 322 323
    }

    if (c->itunes_metadata && atom.size > 8) {
324 325
        int data_size = avio_rb32(pb);
        int tag = avio_rl32(pb);
326
        if (tag == MKTAG('d','a','t','a')) {
327 328
            data_type = avio_rb32(pb); // type
            avio_rb32(pb); // unknown
329 330
            str_size = data_size - 16;
            atom.size -= 16;
A
Anton Khirnov 已提交
331 332 333 334 335 336

            if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
                int ret = mov_read_covr(c, pb, data_type, str_size);
                if (ret < 0) {
                    av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
                }
337
                return ret;
A
Anton Khirnov 已提交
338
            }
339 340
        } else return 0;
    } else if (atom.size > 4 && key && !c->itunes_metadata) {
341 342
        str_size = avio_rb16(pb); // string length
        langcode = avio_rb16(pb);
343
        ff_mov_lang_to_iso639(langcode, language);
344 345 346 347
        atom.size -= 4;
    } else
        str_size = atom.size;

348
    if (c->export_all && !key) {
349 350 351 352 353 354 355
        snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
        key = tmp_key;
    }

    if (!key)
        return 0;
    if (atom.size < 0)
356
        return AVERROR_INVALIDDATA;
357

358 359 360 361 362
    str_size_alloc = str_size << 1; // worst-case requirement for output string in case of utf8 coded input
    str = av_malloc(str_size_alloc);
    if (!str)
        return AVERROR(ENOMEM);

B
Baptiste Coudurier 已提交
363
    if (parse)
364
        parse(c, pb, str_size, key);
B
Baptiste Coudurier 已提交
365
    else {
366
        if (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff))) { // MAC Encoded
367
            mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
368
        } else {
369
            int ret = avio_read(pb, str, str_size);
370 371
            if (ret != str_size) {
                av_freep(&str);
372
                return ret < 0 ? ret : AVERROR_INVALIDDATA;
373
            }
374 375
            str[str_size] = 0;
        }
376
        c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
377
        av_dict_set(&c->fc->metadata, key, str, 0);
B
Baptiste Coudurier 已提交
378 379
        if (*language && strcmp(language, "und")) {
            snprintf(key2, sizeof(key2), "%s-%s", key, language);
380
            av_dict_set(&c->fc->metadata, key2, str, 0);
B
Baptiste Coudurier 已提交
381
        }
B
Baptiste Coudurier 已提交
382
    }
383 384
    av_dlog(c->fc, "lang \"%3s\" ", language);
    av_dlog(c->fc, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n",
385 386 387
            key, str, (char*)&atom.type, str_size_alloc, atom.size);

    av_freep(&str);
388 389
    return 0;
}
390

391
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
D
David Conrad 已提交
392 393
{
    int64_t start;
D
David Conrad 已提交
394
    int i, nb_chapters, str_len, version;
D
David Conrad 已提交
395 396 397 398 399
    char str[256+1];

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

400 401
    version = avio_r8(pb);
    avio_rb24(pb);
D
David Conrad 已提交
402
    if (version)
403 404
        avio_rb32(pb); // ???
    nb_chapters = avio_r8(pb);
D
David Conrad 已提交
405 406 407 408 409

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

410 411
        start = avio_rb64(pb);
        str_len = avio_r8(pb);
D
David Conrad 已提交
412 413 414 415

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

416
        avio_read(pb, str, str_len);
D
David Conrad 已提交
417
        str[str_len] = 0;
418
        avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
D
David Conrad 已提交
419 420 421 422
    }
    return 0;
}

423
#define MIN_DATA_ENTRY_BOX_SIZE 12
424
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
425
{
426 427
    AVStream *st;
    MOVStreamContext *sc;
428 429
    int entries, i, j;

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

435 436
    avio_rb32(pb); // version + flags
    entries = avio_rb32(pb);
437 438
    if (entries >  (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
        entries >= UINT_MAX / sizeof(*sc->drefs))
439
        return AVERROR_INVALIDDATA;
440
    av_free(sc->drefs);
441
    sc->drefs_count = 0;
442
    sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
443 444 445
    if (!sc->drefs)
        return AVERROR(ENOMEM);
    sc->drefs_count = entries;
446 447

    for (i = 0; i < sc->drefs_count; i++) {
448
        MOVDref *dref = &sc->drefs[i];
449
        uint32_t size = avio_rb32(pb);
450
        int64_t next = avio_tell(pb) + size - 4;
451

452
        if (size < 12)
453
            return AVERROR_INVALIDDATA;
454

455 456
        dref->type = avio_rl32(pb);
        avio_rb32(pb); // version + flags
L
Luca Barbato 已提交
457
        av_dlog(c->fc, "type %.4s size %d\n", (char*)&dref->type, size);
458 459 460 461 462 463

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

464
            avio_skip(pb, 10);
465

466
            volume_len = avio_r8(pb);
467
            volume_len = FFMIN(volume_len, 27);
468
            avio_read(pb, dref->volume, 27);
469 470
            dref->volume[volume_len] = 0;
            av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
471

472
            avio_skip(pb, 12);
473

474
            len = avio_r8(pb);
475
            len = FFMIN(len, 63);
476
            avio_read(pb, dref->filename, 63);
477 478 479
            dref->filename[len] = 0;
            av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);

480
            avio_skip(pb, 16);
481 482

            /* read next level up_from_alias/down_to_target */
483 484
            dref->nlvl_from = avio_rb16(pb);
            dref->nlvl_to   = avio_rb16(pb);
485 486 487
            av_log(c->fc, AV_LOG_DEBUG, "nlvl from %d, nlvl to %d\n",
                   dref->nlvl_from, dref->nlvl_to);

488
            avio_skip(pb, 16);
489

490
            for (type = 0; type != -1 && avio_tell(pb) < next; ) {
491
                if(avio_feof(pb))
492
                    return AVERROR_EOF;
493 494
                type = avio_rb16(pb);
                len = avio_rb16(pb);
495 496 497 498
                av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
                if (len&1)
                    len += 1;
                if (type == 2) { // absolute path
499
                    av_free(dref->path);
500
                    dref->path = av_mallocz(len+1);
501 502
                    if (!dref->path)
                        return AVERROR(ENOMEM);
503
                    avio_read(pb, dref->path, len);
504
                    if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
505 506 507 508 509 510 511 512
                        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);
513 514 515 516 517
                } else if (type == 0) { // directory name
                    av_free(dref->dir);
                    dref->dir = av_malloc(len+1);
                    if (!dref->dir)
                        return AVERROR(ENOMEM);
518 519
                    if (avio_read(pb, dref->dir, len) != len)
                        return AVERROR_INVALIDDATA;
520 521 522 523 524
                    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);
525
                } else
526
                    avio_skip(pb, len);
527 528
            }
        }
A
Anton Khirnov 已提交
529
        avio_seek(pb, next, SEEK_SET);
530 531 532 533
    }
    return 0;
}

534
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
535
{
536
    AVStream *st;
537
    uint32_t type;
538
    uint32_t av_unused ctype;
539 540
    int title_size;
    char *title_str;
541

542 543 544 545 546
    if (c->fc->nb_streams < 1) // meta before first trak
        return 0;

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

547 548
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
549 550

    /* component type */
551 552
    ctype = avio_rl32(pb);
    type = avio_rl32(pb); /* component subtype */
553

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

557
    if     (type == MKTAG('v','i','d','e'))
558
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
559
    else if (type == MKTAG('s','o','u','n'))
560
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
561
    else if (type == MKTAG('m','1','a',' '))
562
        st->codec->codec_id = AV_CODEC_ID_MP2;
563
    else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
564
        st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
565

566 567 568
    avio_rb32(pb); /* component  manufacture */
    avio_rb32(pb); /* component flags */
    avio_rb32(pb); /* component flags mask */
569

570 571 572 573 574 575 576
    title_size = atom.size - 24;
    if (title_size > 0) {
        title_str = av_malloc(title_size + 1); /* Add null terminator */
        if (!title_str)
            return AVERROR(ENOMEM);
        avio_read(pb, title_str, title_size);
        title_str[title_size] = 0;
577 578 579
        if (title_str[0])
            av_dict_set(&st->metadata, "handler_name", title_str +
                        (!c->isom && title_str[0] == title_size - 1), 0);
580 581 582
        av_freep(&title_str);
    }

583 584 585
    return 0;
}

586
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
587
{
588
    AVStream *st;
589
    int tag;
590

591
    if (fc->nb_streams < 1)
592
        return 0;
593
    st = fc->streams[fc->nb_streams-1];
594

595
    avio_rb32(pb); /* version + flags */
596
    ff_mp4_read_descr(fc, pb, &tag);
597
    if (tag == MP4ESDescrTag) {
598
        ff_mp4_parse_es_descr(pb, NULL);
599
    } else
600
        avio_rb16(pb); /* ID */
601

602
    ff_mp4_read_descr(fc, pb, &tag);
603 604
    if (tag == MP4DecConfigDescrTag)
        ff_mp4_read_dec_config_descr(fc, st, pb);
605 606 607
    return 0;
}

608
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
609
{
610
    return ff_mov_read_esds(c->fc, pb);
611 612
}

613
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
614 615
{
    AVStream *st;
616
    int ac3info, acmod, lfeon, bsmod;
617

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

622
    ac3info = avio_rb24(pb);
623
    bsmod = (ac3info >> 14) & 0x7;
624 625 626
    acmod = (ac3info >> 11) & 0x7;
    lfeon = (ac3info >> 10) & 0x1;
    st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
627 628 629
    st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
    if (lfeon)
        st->codec->channel_layout |= AV_CH_LOW_FREQUENCY;
630 631 632
    st->codec->audio_service_type = bsmod;
    if (st->codec->channels > 1 && bsmod == 0x7)
        st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;
633 634 635 636

    return 0;
}

637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    int eac3info, acmod, lfeon, bsmod;

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

    /* No need to parse fields for additional independent substreams and its
     * associated dependent substreams since libavcodec's E-AC-3 decoder
     * does not support them yet. */
    avio_rb16(pb); /* data_rate and num_ind_sub */
    eac3info = avio_rb24(pb);
    bsmod = (eac3info >> 12) & 0x1f;
    acmod = (eac3info >>  9) & 0x7;
    lfeon = (eac3info >>  8) & 0x1;
    st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
    if (lfeon)
        st->codec->channel_layout |= AV_CH_LOW_FREQUENCY;
    st->codec->channels = av_get_channel_layout_nb_channels(st->codec->channel_layout);
    st->codec->audio_service_type = bsmod;
    if (st->codec->channels > 1 && bsmod == 0x7)
        st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE;

    return 0;
}

665 666 667 668 669 670 671 672 673 674 675
static int mov_read_chan(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];

    if (atom.size < 16)
        return 0;

676 677 678
    /* skip version and flags */
    avio_skip(pb, 4);

679
    ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
680 681 682 683

    return 0;
}

684 685 686
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
687
    int ret;
688 689 690 691 692

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

693
    if ((ret = ff_get_wav_header(pb, st->codec, atom.size)) < 0)
694
        av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
695

696
    return ret;
697 698
}

699
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
700
{
701 702
    const int num = avio_rb32(pb);
    const int den = avio_rb32(pb);
703 704 705 706 707 708
    AVStream *st;

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

709 710 711 712 713 714 715
    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) {
716 717 718 719 720 721
        st->sample_aspect_ratio.num = num;
        st->sample_aspect_ratio.den = den;
    }
    return 0;
}

722
/* this atom contains actual media data */
723
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
724
{
725
    if (atom.size == 0) /* wrong one (MP4) */
726 727 728 729 730
        return 0;
    c->found_mdat=1;
    return 0; /* now go for moov */
}

731
/* read major brand, minor version and compatible brands and store them as metadata */
732
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
733
{
734 735 736 737 738
    uint32_t minor_ver;
    int comp_brand_size;
    char* comp_brands_str;
    uint8_t type[5] = {0};

739
    avio_read(pb, type, 4);
B
Baptiste Coudurier 已提交
740
    if (strcmp(type, "qt  "))
741
        c->isom = 1;
742
    av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
743
    av_dict_set(&c->fc->metadata, "major_brand", type, 0);
744
    minor_ver = avio_rb32(pb); /* minor version */
745
    av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
746 747 748

    comp_brand_size = atom.size - 8;
    if (comp_brand_size < 0)
749
        return AVERROR_INVALIDDATA;
750 751 752
    comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
    if (!comp_brands_str)
        return AVERROR(ENOMEM);
753
    avio_read(pb, comp_brands_str, comp_brand_size);
754
    comp_brands_str[comp_brand_size] = 0;
755
    av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
756 757
    av_freep(&comp_brands_str);

758 759 760
    return 0;
}

761
/* this atom should contain all header atoms */
762
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
763
{
764 765
    int ret;

766 767 768 769 770 771
    if (c->found_moov) {
        av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
        avio_skip(pb, atom.size);
        return 0;
    }

772 773
    if ((ret = mov_read_default(c, pb, atom)) < 0)
        return ret;
774 775 776 777 778 779
    /* 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 */
}

780
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
781
{
782 783 784
    if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
        c->has_looked_for_mfra = 1;
        if (pb->seekable) {
785
            int ret;
786 787 788 789 790 791 792 793 794 795 796
            av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
                    "for a mfra\n");
            if ((ret = mov_read_mfra(c, pb)) < 0) {
                av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
                        "read the mfra (may be a live ismv)\n");
            }
        } else {
            av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
                    "seekable, can not look for mfra\n");
        }
    }
797
    c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
798
    av_dlog(c->fc, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
B
Baptiste Coudurier 已提交
799 800
    return mov_read_default(c, pb, atom);
}
801

802
static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time)
803 804 805
{
    char buffer[32];
    if (time) {
806
        struct tm *ptm, tmbuf;
807
        time_t timet;
808 809
        if(time >= 2082844800)
            time -= 2082844800;  /* seconds between 1904-01-01 and Epoch */
810
        timet = time;
811
        ptm = gmtime_r(&timet, &tmbuf);
812
        if (!ptm) return;
813 814
        if (strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm))
            av_dict_set(metadata, "creation_time", buffer, 0);
815 816 817
    }
}

818
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
819
{
820 821 822
    AVStream *st;
    MOVStreamContext *sc;
    int version;
823
    char language[4] = {0};
824
    unsigned lang;
825
    int64_t creation_time;
826

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

832 833 834 835 836
    if (sc->time_scale) {
        av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
        return AVERROR_INVALIDDATA;
    }

837
    version = avio_r8(pb);
838
    if (version > 1) {
839
        avpriv_request_sample(c->fc, "Version %d", version);
840 841
        return AVERROR_PATCHWELCOME;
    }
842
    avio_rb24(pb); /* flags */
B
clean  
Baptiste Coudurier 已提交
843
    if (version == 1) {
844 845
        creation_time = avio_rb64(pb);
        avio_rb64(pb);
B
clean  
Baptiste Coudurier 已提交
846
    } else {
847 848
        creation_time = avio_rb32(pb);
        avio_rb32(pb); /* modification time */
B
clean  
Baptiste Coudurier 已提交
849
    }
850
    mov_metadata_creation_time(&st->metadata, creation_time);
851

852 853
    sc->time_scale = avio_rb32(pb);
    st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
854

855
    lang = avio_rb16(pb); /* language */
856
    if (ff_mov_lang_to_iso639(lang, language))
857
        av_dict_set(&st->metadata, "language", language, 0);
858
    avio_rb16(pb); /* quality */
859 860 861 862

    return 0;
}

863
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
864
{
865
    int64_t creation_time;
866 867
    int version = avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
868

B
Baptiste Coudurier 已提交
869
    if (version == 1) {
870 871
        creation_time = avio_rb64(pb);
        avio_rb64(pb);
B
Baptiste Coudurier 已提交
872
    } else {
873 874
        creation_time = avio_rb32(pb);
        avio_rb32(pb); /* modification time */
B
Baptiste Coudurier 已提交
875
    }
876
    mov_metadata_creation_time(&c->fc->metadata, creation_time);
877
    c->time_scale = avio_rb32(pb); /* time scale */
878

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

881
    c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
882 883
    // set the AVCodecContext duration because the duration of individual tracks
    // may be inaccurate
884
    if (c->time_scale > 0 && !c->trex_data)
885
        c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
886
    avio_rb32(pb); /* preferred scale */
887

888
    avio_rb16(pb); /* preferred volume */
889

890
    avio_skip(pb, 10); /* reserved */
891

892
    avio_skip(pb, 36); /* display matrix */
893

894 895 896 897 898 899 900
    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 */
901 902 903
    return 0;
}

904
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
905
{
906 907 908 909 910 911
    AVStream *st;
    int little_endian;

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

913
    little_endian = avio_rb16(pb) & 0xFF;
L
Luca Barbato 已提交
914
    av_dlog(c->fc, "enda %d\n", little_endian);
915
    if (little_endian == 1) {
916
        switch (st->codec->codec_id) {
917 918
        case AV_CODEC_ID_PCM_S24BE:
            st->codec->codec_id = AV_CODEC_ID_PCM_S24LE;
919
            break;
920 921
        case AV_CODEC_ID_PCM_S32BE:
            st->codec->codec_id = AV_CODEC_ID_PCM_S32LE;
922
            break;
923 924
        case AV_CODEC_ID_PCM_F32BE:
            st->codec->codec_id = AV_CODEC_ID_PCM_F32LE;
925
            break;
926 927
        case AV_CODEC_ID_PCM_F64BE:
            st->codec->codec_id = AV_CODEC_ID_PCM_F64LE;
928
            break;
929 930 931 932 933 934 935
        default:
            break;
        }
    }
    return 0;
}

936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    char color_parameter_type[5] = { 0 };
    int color_primaries, color_trc, color_matrix;

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

    avio_read(pb, color_parameter_type, 4);
    if (strncmp(color_parameter_type, "nclx", 4) &&
        strncmp(color_parameter_type, "nclc", 4)) {
        av_log(c->fc, AV_LOG_WARNING, "unsupported color_parameter_type %s\n",
               color_parameter_type);
        return 0;
    }

    color_primaries = avio_rb16(pb);
    color_trc = avio_rb16(pb);
    color_matrix = avio_rb16(pb);

958
    av_dlog(c->fc, "%s: pri %d trc %d matrix %d",
959 960 961 962
            color_parameter_type, color_primaries, color_trc, color_matrix);

    if (c->isom) {
        uint8_t color_range = avio_r8(pb) >> 7;
963
        av_dlog(c->fc, " full %"PRIu8"", color_range);
964 965 966 967 968 969 970 971
        if (color_range)
            st->codec->color_range = AVCOL_RANGE_JPEG;
        else
            st->codec->color_range = AVCOL_RANGE_MPEG;
        /* 14496-12 references JPEG XR specs (rather than the more complete
         * 23001-8) so some adjusting is required */
        if (color_primaries >= AVCOL_PRI_FILM)
            color_primaries = AVCOL_PRI_UNSPECIFIED;
972 973
        if ((color_trc >= AVCOL_TRC_LINEAR &&
             color_trc <= AVCOL_TRC_LOG_SQRT) ||
974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999
            color_trc >= AVCOL_TRC_BT2020_10)
            color_trc = AVCOL_TRC_UNSPECIFIED;
        if (color_matrix >= AVCOL_SPC_BT2020_NCL)
            color_matrix = AVCOL_SPC_UNSPECIFIED;
        st->codec->color_primaries = color_primaries;
        st->codec->color_trc = color_trc;
        st->codec->colorspace = color_matrix;
    } else {
        /* color primaries, Table 4-4 */
        switch (color_primaries) {
        case 1: st->codec->color_primaries = AVCOL_PRI_BT709; break;
        case 5: st->codec->color_primaries = AVCOL_PRI_SMPTE170M; break;
        case 6: st->codec->color_primaries = AVCOL_PRI_SMPTE240M; break;
        }
        /* color transfer, Table 4-5 */
        switch (color_trc) {
        case 1: st->codec->color_trc = AVCOL_TRC_BT709; break;
        case 7: st->codec->color_trc = AVCOL_TRC_SMPTE240M; break;
        }
        /* color matrix, Table 4-6 */
        switch (color_matrix) {
        case 1: st->codec->colorspace = AVCOL_SPC_BT709; break;
        case 6: st->codec->colorspace = AVCOL_SPC_BT470BG; break;
        case 7: st->codec->colorspace = AVCOL_SPC_SMPTE240M; break;
        }
    }
1000
    av_dlog(c->fc, "\n");
1001 1002 1003 1004

    return 0;
}

1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    unsigned mov_field_order;
    enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;

    if (c->fc->nb_streams < 1) // will happen with jp2 files
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    if (atom.size < 2)
        return AVERROR_INVALIDDATA;
    mov_field_order = avio_rb16(pb);
    if ((mov_field_order & 0xFF00) == 0x0100)
        decoded_field_order = AV_FIELD_PROGRESSIVE;
    else if ((mov_field_order & 0xFF00) == 0x0200) {
        switch (mov_field_order & 0xFF) {
        case 0x01: decoded_field_order = AV_FIELD_TT;
                   break;
        case 0x06: decoded_field_order = AV_FIELD_BB;
                   break;
        case 0x09: decoded_field_order = AV_FIELD_TB;
                   break;
        case 0x0E: decoded_field_order = AV_FIELD_BT;
                   break;
        }
    }
    if (decoded_field_order == AV_FIELD_UNKNOWN && mov_field_order) {
        av_log(NULL, AV_LOG_ERROR, "Unknown MOV field order 0x%04x\n", mov_field_order);
    }
    st->codec->field_order = decoded_field_order;

    return 0;
}

1039
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
1040
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1041
                              enum AVCodecID codec_id)
1042
{
1043 1044
    AVStream *st;
    uint64_t size;
1045
    uint8_t *buf;
1046
    int err;
1047 1048 1049 1050

    if (c->fc->nb_streams < 1) // will happen with jp2 files
        return 0;
    st= c->fc->streams[c->fc->nb_streams-1];
1051 1052 1053 1054

    if (st->codec->codec_id != codec_id)
        return 0; /* unexpected codec_id - don't mess with extradata */

1055
    size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
1056
    if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
1057
        return AVERROR_INVALIDDATA;
1058 1059
    if ((err = av_reallocp(&st->codec->extradata, size)) < 0) {
        st->codec->extradata_size = 0;
1060
        return err;
1061
    }
1062
    buf = st->codec->extradata + st->codec->extradata_size;
1063 1064 1065
    st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE;
    AV_WB32(       buf    , atom.size + 8);
    AV_WL32(       buf + 4, atom.type);
1066 1067 1068 1069 1070 1071 1072
    err = avio_read(pb, buf + 8, atom.size);
    if (err < 0) {
        return err;
    } else if (err < atom.size) {
        av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
        st->codec->extradata_size -= atom.size - err;
    }
1073
    memset(buf + 8 + err, 0, FF_INPUT_BUFFER_PADDING_SIZE);
1074 1075 1076
    return 0;
}

1077 1078 1079
/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1080
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1081 1082 1083 1084
}

static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1085
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1086 1087 1088 1089
}

static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1090
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1091 1092
}

C
Carl Eugen Hoyos 已提交
1093
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1094
{
1095 1096 1097 1098
    int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
    if(ret == 0)
        ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
    return ret;
1099 1100
}

1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);

    if (!ret && c->fc->nb_streams >= 1) {
        AVCodecContext *avctx = c->fc->streams[c->fc->nb_streams-1]->codec;
        if (avctx->extradata_size >= 40) {
            avctx->height = AV_RB16(&avctx->extradata[36]);
            avctx->width  = AV_RB16(&avctx->extradata[38]);
        }
    }
    return ret;
}

1115 1116
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1117 1118 1119 1120 1121 1122 1123 1124 1125 1126 1127
    if (c->fc->nb_streams >= 1) {
        AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec;
        if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
            codec->codec_id == AV_CODEC_ID_H264 &&
            atom.size > 11) {
            avio_skip(pb, 10);
            /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
            if (avio_rb16(pb) == 0xd4d)
                codec->width = 1440;
            return 0;
        }
1128 1129 1130 1131 1132
    }

    return mov_read_avid(c, pb, atom);
}

P
Piotr Bandurski 已提交
1133 1134
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1135
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
P
Piotr Bandurski 已提交
1136 1137
}

1138
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
R
Roberto Togni 已提交
1139
{
1140 1141 1142 1143 1144
    AVStream *st;

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

1146
    if ((uint64_t)atom.size > (1<<30))
1147
        return AVERROR_INVALIDDATA;
1148

1149 1150 1151
    if (st->codec->codec_id == AV_CODEC_ID_QDM2 ||
        st->codec->codec_id == AV_CODEC_ID_QDMC ||
        st->codec->codec_id == AV_CODEC_ID_SPEEX) {
1152
        // pass all frma atom to codec, needed at least for QDMC and QDM2
1153
        av_free(st->codec->extradata);
1154
        if (ff_get_extradata(st->codec, pb, atom.size) < 0)
1155
            return AVERROR(ENOMEM);
1156
    } else if (atom.size > 8) { /* to read frma, esds atoms */
1157 1158 1159
        int ret;
        if ((ret = mov_read_default(c, pb, atom)) < 0)
            return ret;
1160
    } else
1161
        avio_skip(pb, atom.size);
R
Roberto Togni 已提交
1162 1163 1164
    return 0;
}

1165 1166 1167 1168
/**
 * This function reads atom content and puts data in extradata without tag
 * nor size unlike mov_read_extradata.
 */
1169
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1170
{
1171 1172 1173 1174 1175
    AVStream *st;

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

1177
    if ((uint64_t)atom.size > (1<<30))
1178
        return AVERROR_INVALIDDATA;
1179

1180
    if (atom.size >= 10) {
1181
        // Broken files created by legacy versions of libavformat will
1182 1183 1184 1185 1186 1187 1188
        // wrap a whole fiel atom inside of a glbl atom.
        unsigned size = avio_rb32(pb);
        unsigned type = avio_rl32(pb);
        avio_seek(pb, -8, SEEK_CUR);
        if (type == MKTAG('f','i','e','l') && size == atom.size)
            return mov_read_default(c, pb, atom);
    }
1189 1190 1191 1192
    if (st->codec->extradata_size > 1 && st->codec->extradata) {
        av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n");
        return 0;
    }
1193
    av_free(st->codec->extradata);
1194
    if (ff_get_extradata(st->codec, pb, atom.size) < 0)
1195
        return AVERROR(ENOMEM);
1196

1197 1198 1199
    return 0;
}

M
Martin Storsjö 已提交
1200 1201 1202 1203
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    uint8_t profile_level;
1204
    int ret;
M
Martin Storsjö 已提交
1205 1206 1207 1208 1209 1210 1211 1212 1213

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

    if (atom.size >= (1<<28) || atom.size < 7)
        return AVERROR_INVALIDDATA;

    profile_level = avio_r8(pb);
1214
    if ((profile_level & 0xf0) != 0xc0)
M
Martin Storsjö 已提交
1215 1216 1217
        return 0;

    avio_seek(pb, 6, SEEK_CUR);
1218 1219 1220
    av_free(st->codec->extradata);
    if ((ret = ff_get_extradata(st->codec, pb, atom.size - 7)) < 0)
        return ret;
1221

M
Martin Storsjö 已提交
1222 1223 1224
    return 0;
}

M
Martin Storsjö 已提交
1225 1226 1227 1228 1229
/**
 * 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.
 */
1230
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
M
Martin Storsjö 已提交
1231 1232 1233 1234 1235 1236 1237 1238 1239
{
    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];

1240
    if ((uint64_t)atom.size > (1<<30))
1241
        return AVERROR_INVALIDDATA;
M
Martin Storsjö 已提交
1242

1243
    avio_skip(pb, 40);
M
Martin Storsjö 已提交
1244
    av_free(st->codec->extradata);
1245
    if (ff_get_extradata(st->codec, pb, atom.size - 40) < 0)
M
Martin Storsjö 已提交
1246 1247 1248 1249
        return AVERROR(ENOMEM);
    return 0;
}

1250
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1251
{
1252 1253
    AVStream *st;
    MOVStreamContext *sc;
1254
    unsigned int i, entries;
1255

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

1261 1262
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1263

1264
    entries = avio_rb32(pb);
1265

A
Alex Converse 已提交
1266 1267
    if (!entries)
        return 0;
1268

1269
    if (sc->chunk_offsets)
1270
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1271 1272
    av_free(sc->chunk_offsets);
    sc->chunk_count = 0;
1273
    sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
1274
    if (!sc->chunk_offsets)
1275 1276 1277
        return AVERROR(ENOMEM);
    sc->chunk_count = entries;

1278
    if      (atom.type == MKTAG('s','t','c','o'))
1279
        for (i = 0; i < entries && !pb->eof_reached; i++)
1280
            sc->chunk_offsets[i] = avio_rb32(pb);
1281
    else if (atom.type == MKTAG('c','o','6','4'))
1282
        for (i = 0; i < entries && !pb->eof_reached; i++)
1283
            sc->chunk_offsets[i] = avio_rb64(pb);
1284
    else
1285
        return AVERROR_INVALIDDATA;
1286

1287 1288 1289 1290 1291
    sc->chunk_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

1292 1293 1294
    return 0;
}

1295 1296 1297 1298
/**
 * Compute codec id for 'lpcm' tag.
 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
 */
1299
enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
1300
{
1301 1302 1303 1304 1305 1306
    /* lpcm flags:
     * 0x1 = float
     * 0x2 = big-endian
     * 0x4 = signed
     */
    return ff_get_pcm_codec_id(bps, flags & 1, flags & 2, flags & 4 ? -1 : 0);
1307 1308
}

1309 1310 1311 1312 1313 1314 1315 1316 1317 1318 1319 1320 1321 1322 1323 1324 1325 1326 1327
static int mov_codec_id(AVStream *st, uint32_t format)
{
    int id = ff_codec_get_id(ff_codec_movaudio_tags, format);

    if (id <= 0 &&
        ((format & 0xFFFF) == 'm' + ('s' << 8) ||
         (format & 0xFFFF) == 'T' + ('S' << 8)))
        id = ff_codec_get_id(ff_codec_wav_tags, av_bswap32(format) & 0xFFFF);

    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 &&
               /* skip old asf mpeg4 tag */
               format && format != MKTAG('m','p','4','s')) {
        id = ff_codec_get_id(ff_codec_movvideo_tags, format);
        if (id <= 0)
            id = ff_codec_get_id(ff_codec_bmp_tags, format);
        if (id > 0)
            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
1328 1329 1330
        else if (st->codec->codec_type == AVMEDIA_TYPE_DATA ||
                    (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
                    st->codec->codec_id == AV_CODEC_ID_NONE)) {
1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341
            id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
            if (id > 0)
                st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
        }
    }

    st->codec->codec_tag = format;

    return id;
}

1342 1343 1344
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
                                 AVStream *st, MOVStreamContext *sc)
{
1345
    uint8_t codec_name[32];
1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 1363 1364 1365 1366
    unsigned int color_depth, len, j;
    int color_greyscale;
    int color_table_id;

    avio_rb16(pb); /* version */
    avio_rb16(pb); /* revision level */
    avio_rb32(pb); /* vendor */
    avio_rb32(pb); /* temporal quality */
    avio_rb32(pb); /* spatial quality */

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

    avio_rb32(pb); /* horiz resolution */
    avio_rb32(pb); /* vert resolution */
    avio_rb32(pb); /* data size, always 0 */
    avio_rb16(pb); /* frames per samples */

    len = avio_r8(pb); /* codec name, pascal string */
    if (len > 31)
        len = 31;
1367
    mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
1368 1369
    if (len < 31)
        avio_skip(pb, 31 - len);
1370 1371 1372 1373

    if (codec_name[0])
        av_dict_set(&st->metadata, "encoder", codec_name, 0);

1374
    /* codec_tag YV12 triggers an UV swap in rawdec.c */
1375
    if (!memcmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
1376
        st->codec->codec_tag = MKTAG('I', '4', '2', '0');
1377 1378 1379
        st->codec->width &= ~1;
        st->codec->height &= ~1;
    }
1380 1381
    /* Flash Media Server uses tag H263 with Sorenson Spark */
    if (st->codec->codec_tag == MKTAG('H','2','6','3') &&
1382
        !memcmp(codec_name, "Sorenson H263", 13))
1383 1384 1385 1386 1387 1388 1389 1390 1391
        st->codec->codec_id = AV_CODEC_ID_FLV1;

    st->codec->bits_per_coded_sample = avio_rb16(pb); /* depth */
    color_table_id = avio_rb16(pb); /* colortable id */
    av_dlog(c->fc, "depth %d, ctab id %d\n",
            st->codec->bits_per_coded_sample, color_table_id);
    /* figure out the palette situation */
    color_depth     = st->codec->bits_per_coded_sample & 0x1F;
    color_greyscale = st->codec->bits_per_coded_sample & 0x20;
1392 1393 1394
    /* Do not create a greyscale palette for cinepak */
    if (color_greyscale && st->codec->codec_id == AV_CODEC_ID_CINEPAK)
        return;
1395 1396 1397 1398 1399

    /* if the depth is 2, 4, or 8 bpp, file is palettized */
    if ((color_depth == 2) || (color_depth == 4) || (color_depth == 8)) {
        /* for palette traversal */
        unsigned int color_start, color_count, color_end;
1400
        unsigned char a, r, g, b;
1401 1402 1403 1404

        if (color_greyscale) {
            int color_index, color_dec;
            /* compute the greyscale palette */
1405
            st->codec->bits_per_coded_sample = color_depth;
1406 1407 1408 1409 1410
            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;
1411
                sc->palette[j] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430
                color_index -= color_dec;
                if (color_index < 0)
                    color_index = 0;
            }
        } else if (color_table_id) {
            const uint8_t *color_table;
            /* if flag bit 3 is set, use the default palette */
            color_count = 1 << color_depth;
            if (color_depth == 2)
                color_table = ff_qt_default_palette_4;
            else if (color_depth == 4)
                color_table = ff_qt_default_palette_16;
            else
                color_table = ff_qt_default_palette_256;

            for (j = 0; j < color_count; j++) {
                r = color_table[j * 3 + 0];
                g = color_table[j * 3 + 1];
                b = color_table[j * 3 + 2];
1431
                sc->palette[j] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
1432 1433 1434 1435 1436 1437 1438 1439
            }
        } else {
            /* load the palette from the file */
            color_start = avio_rb32(pb);
            color_count = avio_rb16(pb);
            color_end   = avio_rb16(pb);
            if ((color_start <= 255) && (color_end <= 255)) {
                for (j = color_start; j <= color_end; j++) {
1440 1441 1442
                    /* each A, R, G, or B component is 16 bits;
                        * only use the top 8 bits */
                    a = avio_r8(pb);
1443 1444 1445 1446 1447 1448 1449
                    avio_r8(pb);
                    r = avio_r8(pb);
                    avio_r8(pb);
                    g = avio_r8(pb);
                    avio_r8(pb);
                    b = avio_r8(pb);
                    avio_r8(pb);
1450
                    sc->palette[j] = (a << 24 ) | (r << 16) | (g << 8) | (b);
1451 1452 1453 1454 1455 1456 1457
                }
            }
        }
        sc->has_palette = 1;
    }
}

1458 1459 1460 1461 1462
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
                                 AVStream *st, MOVStreamContext *sc)
{
    int bits_per_sample, flags;
    uint16_t version = avio_rb16(pb);
1463
    AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
1464 1465 1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478

    avio_rb16(pb); /* revision level */
    avio_rb32(pb); /* vendor */

    st->codec->channels              = avio_rb16(pb); /* channel count */
    st->codec->bits_per_coded_sample = avio_rb16(pb); /* sample size */
    av_dlog(c->fc, "audio channels %d\n", st->codec->channels);

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

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

    // Read QT version 1 fields. In version 0 these do not exist.
    av_dlog(c->fc, "version =%d, isom =%d\n", version, c->isom);
1479 1480 1481
    if (!c->isom ||
        (compatible_brands && strstr(compatible_brands->value, "qt  "))) {

1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517
        if (version == 1) {
            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 */
        } else if (version == 2) {
            avio_rb32(pb); /* sizeof struct only */
            st->codec->sample_rate = av_int2double(avio_rb64(pb));
            st->codec->channels    = avio_rb32(pb);
            avio_rb32(pb); /* always 0x7F000000 */
            st->codec->bits_per_coded_sample = avio_rb32(pb);

            flags = avio_rb32(pb); /* lpcm format specific flag */
            sc->bytes_per_frame   = avio_rb32(pb);
            sc->samples_per_frame = avio_rb32(pb);
            if (st->codec->codec_tag == MKTAG('l','p','c','m'))
                st->codec->codec_id =
                    ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample,
                                             flags);
        }
    }

    switch (st->codec->codec_id) {
    case AV_CODEC_ID_PCM_S8:
    case AV_CODEC_ID_PCM_U8:
        if (st->codec->bits_per_coded_sample == 16)
            st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
        break;
    case AV_CODEC_ID_PCM_S16LE:
    case AV_CODEC_ID_PCM_S16BE:
        if (st->codec->bits_per_coded_sample == 8)
            st->codec->codec_id = AV_CODEC_ID_PCM_S8;
        else if (st->codec->bits_per_coded_sample == 24)
            st->codec->codec_id =
                st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
                AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
1518 1519 1520 1521
        else if (st->codec->bits_per_coded_sample == 32)
             st->codec->codec_id =
                st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
                AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550
        break;
    /* set values for old format before stsd version 1 appeared */
    case AV_CODEC_ID_MACE3:
        sc->samples_per_frame = 6;
        sc->bytes_per_frame   = 2 * st->codec->channels;
        break;
    case AV_CODEC_ID_MACE6:
        sc->samples_per_frame = 6;
        sc->bytes_per_frame   = 1 * st->codec->channels;
        break;
    case AV_CODEC_ID_ADPCM_IMA_QT:
        sc->samples_per_frame = 64;
        sc->bytes_per_frame   = 34 * st->codec->channels;
        break;
    case AV_CODEC_ID_GSM:
        sc->samples_per_frame = 160;
        sc->bytes_per_frame   = 33;
        break;
    default:
        break;
    }

    bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
    if (bits_per_sample) {
        st->codec->bits_per_coded_sample = bits_per_sample;
        sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
    }
}

1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
                                    AVStream *st, MOVStreamContext *sc,
                                    int size)
{
    // ttxt stsd contains display flags, justification, background
    // color, fonts, and default styles, so fake an atom to read it
    MOVAtom fake_atom = { .size = size };
    // mp4s contains a regular esds atom
    if (st->codec->codec_tag != AV_RL32("mp4s"))
        mov_read_glbl(c, pb, fake_atom);
    st->codec->width  = sc->width;
    st->codec->height = sc->height;
}

1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598
static uint32_t yuv_to_rgba(uint32_t ycbcr)
{
    uint8_t r, g, b;
    int y, cb, cr;

    y  = (ycbcr >> 16) & 0xFF;
    cr = (ycbcr >> 8)  & 0xFF;
    cb =  ycbcr        & 0xFF;

    b = av_clip_uint8(1.164 * (y - 16)                      + 2.018 * (cb - 128));
    g = av_clip_uint8(1.164 * (y - 16) - 0.813 * (cr - 128) - 0.391 * (cb - 128));
    r = av_clip_uint8(1.164 * (y - 16) + 1.596 * (cr - 128));

    return (r << 16) | (g << 8) | b;
}

static int mov_rewrite_dvd_sub_extradata(AVStream *st)
{
    char buf[256] = {0};
    uint8_t *src = st->codec->extradata;
    int i;

    if (st->codec->extradata_size != 64)
        return 0;

    if (st->codec->width > 0 &&  st->codec->height > 0)
        snprintf(buf, sizeof(buf), "size: %dx%d\n",
                 st->codec->width, st->codec->height);
    av_strlcat(buf, "palette: ", sizeof(buf));

    for (i = 0; i < 16; i++) {
        uint32_t yuv = AV_RB32(src + i * 4);
        uint32_t rgba = yuv_to_rgba(yuv);

1599
        av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615
    }

    if (av_strlcat(buf, "\n", sizeof(buf)) >= sizeof(buf))
        return 0;

    av_freep(&st->codec->extradata);
    st->codec->extradata_size = 0;
    st->codec->extradata = av_mallocz(strlen(buf) + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
    st->codec->extradata_size = strlen(buf);
    memcpy(st->codec->extradata, buf, st->codec->extradata_size);

    return 0;
}

L
Luca Barbato 已提交
1616 1617 1618 1619 1620
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
                                AVStream *st, MOVStreamContext *sc,
                                int size)
{
    if (st->codec->codec_tag == MKTAG('t','m','c','d')) {
1621
        if (ff_get_extradata(st->codec, pb, size) < 0)
L
Luca Barbato 已提交
1622
            return AVERROR(ENOMEM);
1623 1624 1625 1626 1627 1628 1629 1630 1631
        if (size > 16) {
            MOVStreamContext *tmcd_ctx = st->priv_data;
            int val;
            val = AV_RB32(st->codec->extradata + 4);
            tmcd_ctx->tmcd_flags = val;
            if (val & 1)
                st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE;
            st->codec->time_base.den = st->codec->extradata[16]; /* number of frame */
            st->codec->time_base.num = 1;
1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651
            if (size > 30) {
                uint32_t len = AV_RB32(st->codec->extradata + 18); /* name atom length */
                uint32_t format = AV_RB32(st->codec->extradata + 22);
                if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
                    uint16_t str_size = AV_RB16(st->codec->extradata + 26); /* string length */
                    if (str_size > 0 && size >= (int)str_size + 26) {
                        char *reel_name = av_malloc(str_size + 1);
                        if (!reel_name)
                            return AVERROR(ENOMEM);
                        memcpy(reel_name, st->codec->extradata + 30, str_size);
                        reel_name[str_size] = 0; /* Add null terminator */
                        /* don't add reel_name if emtpy string */
                        if (*reel_name == 0) {
                            av_free(reel_name);
                        } else {
                            av_dict_set(&st->metadata, "reel_name", reel_name,  AV_DICT_DONT_STRDUP_VAL);
                        }
                    }
                }
            }
1652
        }
L
Luca Barbato 已提交
1653 1654 1655 1656 1657 1658 1659
    } else {
        /* other codec type, just skip (rtp, mp4s ...) */
        avio_skip(pb, size);
    }
    return 0;
}

1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
                                   AVStream *st, MOVStreamContext *sc)
{
    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
        !st->codec->sample_rate && sc->time_scale > 1)
        st->codec->sample_rate = sc->time_scale;

    /* special codec parameters handling */
    switch (st->codec->codec_id) {
#if CONFIG_DV_DEMUXER
    case AV_CODEC_ID_DVAUDIO:
        c->dv_fctx  = avformat_alloc_context();
        c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
        if (!c->dv_demux) {
            av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
            return AVERROR(ENOMEM);
        }
        sc->dv_audio_container = 1;
        st->codec->codec_id    = AV_CODEC_ID_PCM_S16LE;
        break;
#endif
    /* no ifdef since parameters are always those */
    case AV_CODEC_ID_QCELP:
        st->codec->channels = 1;
        // 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;
1687 1688 1689 1690
        // FIXME: Why is the following needed for some files?
        sc->samples_per_frame = 160;
        if (!sc->bytes_per_frame)
            sc->bytes_per_frame = 35;
1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710
        break;
    case AV_CODEC_ID_AMR_NB:
        st->codec->channels    = 1;
        /* force sample rate for amr, stsd in 3gp does not store sample rate */
        st->codec->sample_rate = 8000;
        break;
    case AV_CODEC_ID_AMR_WB:
        st->codec->channels    = 1;
        st->codec->sample_rate = 16000;
        break;
    case AV_CODEC_ID_MP2:
    case AV_CODEC_ID_MP3:
        /* force type after stsd for m1a hdlr */
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->need_parsing      = AVSTREAM_PARSE_FULL;
        break;
    case AV_CODEC_ID_GSM:
    case AV_CODEC_ID_ADPCM_MS:
    case AV_CODEC_ID_ADPCM_IMA_WAV:
    case AV_CODEC_ID_ILBC:
1711 1712 1713
    case AV_CODEC_ID_MACE3:
    case AV_CODEC_ID_MACE6:
    case AV_CODEC_ID_QDM2:
1714 1715 1716 1717 1718 1719 1720 1721
        st->codec->block_align = sc->bytes_per_frame;
        break;
    case AV_CODEC_ID_ALAC:
        if (st->codec->extradata_size == 36) {
            st->codec->channels    = AV_RB8 (st->codec->extradata + 21);
            st->codec->sample_rate = AV_RB32(st->codec->extradata + 32);
        }
        break;
1722
    case AV_CODEC_ID_AC3:
1723
    case AV_CODEC_ID_EAC3:
1724
    case AV_CODEC_ID_MPEG1VIDEO:
1725 1726 1727 1728 1729 1730 1731 1732 1733
    case AV_CODEC_ID_VC1:
        st->need_parsing = AVSTREAM_PARSE_FULL;
        break;
    default:
        break;
    }
    return 0;
}

1734 1735
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
                                  int codec_tag, int format,
1736
                                  int64_t size)
1737 1738 1739 1740 1741 1742
{
    int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);

    if (codec_tag &&
         (codec_tag != format &&
          (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
1743
                                 : codec_tag != MKTAG('j','p','e','g')))) {
1744 1745 1746 1747 1748 1749 1750 1751
        /* 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. */

        av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
        avio_skip(pb, size);
        return 1;
    }
Y
Yusuke Nakamura 已提交
1752 1753 1754 1755
    if ( codec_tag == AV_RL32("avc1") ||
         codec_tag == AV_RL32("hvc1") ||
         codec_tag == AV_RL32("hev1")
    )
1756
        av_log(c->fc, AV_LOG_WARNING, "Concatenated H.264 or H.265 might not play correctly.\n");
1757 1758 1759 1760

    return 0;
}

1761
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
1762
{
1763 1764
    AVStream *st;
    MOVStreamContext *sc;
1765
    int pseudo_stream_id;
1766

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

1772 1773 1774
    for (pseudo_stream_id = 0;
         pseudo_stream_id < entries && !pb->eof_reached;
         pseudo_stream_id++) {
1775
        //Parsing Sample description table
1776
        enum AVCodecID id;
L
Luca Barbato 已提交
1777
        int ret, dref_id = 1;
1778
        MOVAtom a = { AV_RL32("stsd") };
1779
        int64_t start_pos = avio_tell(pb);
1780
        int64_t size = avio_rb32(pb); /* size */
1781
        uint32_t format = avio_rl32(pb); /* data format */
1782

1783
        if (size >= 16) {
1784 1785 1786
            avio_rb32(pb); /* reserved */
            avio_rb16(pb); /* reserved */
            dref_id = avio_rb16(pb);
1787
        }else if (size <= 7){
M
Michael Niedermayer 已提交
1788
            av_log(c->fc, AV_LOG_ERROR, "invalid size %"PRId64" in stsd\n", size);
1789
            return AVERROR_INVALIDDATA;
1790
        }
1791

1792 1793
        if (mov_skip_multiple_stsd(c, pb, st->codec->codec_tag, format,
                                   size - (avio_tell(pb) - start_pos)))
1794
            continue;
1795

1796
        sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
1797
        sc->dref_id= dref_id;
1798

1799
        id = mov_codec_id(st, format);
1800

1801
        av_dlog(c->fc, "size=%"PRId64" 4CC= %c%c%c%c codec_type=%d\n", size,
1802 1803
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
                (format >> 24) & 0xff, st->codec->codec_type);
1804

1805
        if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
1806
            st->codec->codec_id = id;
1807
            mov_parse_stsd_video(c, pb, st, sc);
1808
        } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
1809
            st->codec->codec_id = id;
1810
            mov_parse_stsd_audio(c, pb, st, sc);
1811
        } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
1812 1813 1814
            st->codec->codec_id = id;
            mov_parse_stsd_subtitle(c, pb, st, sc,
                                    size - (avio_tell(pb) - start_pos));
1815
        } else {
L
Luca Barbato 已提交
1816 1817 1818 1819
            ret = mov_parse_stsd_data(c, pb, st, sc,
                                      size - (avio_tell(pb) - start_pos));
            if (ret < 0)
                return ret;
1820
        }
Y
Yusuke Nakamura 已提交
1821
        /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
1822
        a.size = size - (avio_tell(pb) - start_pos);
1823
        if (a.size > 8) {
1824 1825
            if ((ret = mov_read_default(c, pb, a)) < 0)
                return ret;
1826
        } else if (a.size > 0)
1827
            avio_skip(pb, a.size);
1828
    }
1829

1830 1831 1832
    if (pb->eof_reached)
        return AVERROR_EOF;

1833
    return mov_finalize_stsd_codec(c, pb, st, sc);
1834 1835
}

1836
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1837 1838 1839
{
    int entries;

1840 1841 1842
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
1843 1844 1845 1846

    return ff_mov_read_stsd_entries(c, pb, entries);
}

1847
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1848
{
1849 1850
    AVStream *st;
    MOVStreamContext *sc;
1851
    unsigned int i, entries;
1852

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

1858 1859
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1860

1861
    entries = avio_rb32(pb);
1862

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

A
Alex Converse 已提交
1865 1866
    if (!entries)
        return 0;
1867
    if (sc->stsc_data)
1868
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
1869 1870
    av_free(sc->stsc_data);
    sc->stsc_count = 0;
1871
    sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
1872
    if (!sc->stsc_data)
1873 1874
        return AVERROR(ENOMEM);

1875
    for (i = 0; i < entries && !pb->eof_reached; i++) {
1876 1877 1878
        sc->stsc_data[i].first = avio_rb32(pb);
        sc->stsc_data[i].count = avio_rb32(pb);
        sc->stsc_data[i].id = avio_rb32(pb);
1879
    }
1880 1881 1882 1883 1884 1885

    sc->stsc_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

1886 1887 1888
    return 0;
}

1889
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1890 1891 1892 1893 1894 1895 1896 1897 1898 1899
{
    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;

1900
    avio_rb32(pb); // version + flags
1901

1902
    entries = avio_rb32(pb);
1903
    if (sc->stps_data)
1904
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
1905 1906 1907
    av_free(sc->stps_data);
    sc->stps_count = 0;
    sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
1908 1909 1910
    if (!sc->stps_data)
        return AVERROR(ENOMEM);

1911
    for (i = 0; i < entries && !pb->eof_reached; i++) {
1912
        sc->stps_data[i] = avio_rb32(pb);
L
Luca Barbato 已提交
1913
        //av_dlog(c->fc, "stps %d\n", sc->stps_data[i]);
1914 1915
    }

1916 1917 1918 1919 1920
    sc->stps_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

1921 1922 1923
    return 0;
}

1924
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1925
{
1926 1927
    AVStream *st;
    MOVStreamContext *sc;
1928
    unsigned int i, entries;
1929

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

1935 1936
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1937

1938
    entries = avio_rb32(pb);
1939

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

1942
    if (!entries)
1943 1944
    {
        sc->keyframe_absent = 1;
1945
        if (!st->need_parsing && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
1946
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
1947
        return 0;
1948
    }
1949
    if (sc->keyframes)
1950
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
1951 1952 1953
    av_free(sc->keyframes);
    sc->keyframe_count = 0;
    sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
1954
    if (!sc->keyframes)
1955 1956
        return AVERROR(ENOMEM);

1957
    for (i = 0; i < entries && !pb->eof_reached; i++) {
1958
        sc->keyframes[i] = avio_rb32(pb);
L
Luca Barbato 已提交
1959
        //av_dlog(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
1960
    }
1961 1962 1963 1964 1965 1966

    sc->keyframe_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

1967 1968 1969
    return 0;
}

1970
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1971
{
1972 1973
    AVStream *st;
    MOVStreamContext *sc;
1974 1975 1976
    unsigned int i, entries, sample_size, field_size, num_bytes;
    GetBitContext gb;
    unsigned char* buf;
1977

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

1983 1984
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1985

1986
    if (atom.type == MKTAG('s','t','s','z')) {
1987
        sample_size = avio_rb32(pb);
1988 1989
        if (!sc->sample_size) /* do not overwrite value computed in stsd */
            sc->sample_size = sample_size;
1990
        sc->stsz_sample_size = sample_size;
1991
        field_size = 32;
1992 1993
    } else {
        sample_size = 0;
1994 1995
        avio_rb24(pb); /* reserved */
        field_size = avio_r8(pb);
1996
    }
1997
    entries = avio_rb32(pb);
1998

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

2001
    sc->sample_count = entries;
2002 2003 2004
    if (sample_size)
        return 0;

2005 2006
    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);
2007
        return AVERROR_INVALIDDATA;
2008 2009
    }

A
Alex Converse 已提交
2010 2011
    if (!entries)
        return 0;
2012
    if (entries >= (UINT_MAX - 4) / field_size)
2013
        return AVERROR_INVALIDDATA;
2014
    if (sc->sample_sizes)
2015
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2016 2017 2018
    av_free(sc->sample_sizes);
    sc->sample_count = 0;
    sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2019
    if (!sc->sample_sizes)
2020 2021
        return AVERROR(ENOMEM);

2022 2023
    num_bytes = (entries*field_size+4)>>3;

2024
    buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE);
2025 2026 2027 2028 2029
    if (!buf) {
        av_freep(&sc->sample_sizes);
        return AVERROR(ENOMEM);
    }

2030
    if (avio_read(pb, buf, num_bytes) < num_bytes) {
2031 2032
        av_freep(&sc->sample_sizes);
        av_free(buf);
2033
        return AVERROR_INVALIDDATA;
2034 2035 2036 2037
    }

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

2038
    for (i = 0; i < entries && !pb->eof_reached; i++) {
2039
        sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2040 2041
        sc->data_size += sc->sample_sizes[i];
    }
2042

2043 2044 2045 2046 2047
    sc->sample_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

2048
    av_free(buf);
2049 2050 2051
    return 0;
}

2052
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2053
{
2054 2055
    AVStream *st;
    MOVStreamContext *sc;
2056
    unsigned int i, entries;
2057 2058
    int64_t duration=0;
    int64_t total_sample_count=0;
2059

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

2065 2066 2067
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
2068

2069 2070
    av_dlog(c->fc, "track[%i].stts.entries = %i\n",
            c->fc->nb_streams-1, entries);
2071

2072
    if (sc->stts_data)
2073
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2074
    av_free(sc->stts_data);
2075 2076
    sc->stts_count = 0;
    sc->stts_data = av_malloc_array(entries, sizeof(*sc->stts_data));
2077
    if (!sc->stts_data)
2078
        return AVERROR(ENOMEM);
2079

2080
    for (i = 0; i < entries && !pb->eof_reached; i++) {
M
cleanup  
Michael Niedermayer 已提交
2081 2082
        int sample_duration;
        int sample_count;
2083

2084 2085
        sample_count=avio_rb32(pb);
        sample_duration = avio_rb32(pb);
2086

2087 2088
        /* sample_duration < 0 is invalid based on the spec */
        if (sample_duration < 0) {
2089 2090
            av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta %d in STTS, at %d st:%d\n",
                   sample_duration, i, c->fc->nb_streams-1);
2091 2092
            sample_duration = 1;
        }
2093 2094 2095 2096
        if (sample_count < 0) {
            av_log(c->fc, AV_LOG_ERROR, "Invalid sample_count=%d\n", sample_count);
            return AVERROR_INVALIDDATA;
        }
2097 2098 2099
        sc->stts_data[i].count= sample_count;
        sc->stts_data[i].duration= sample_duration;

2100 2101
        av_dlog(c->fc, "sample_count=%d, sample_duration=%d\n",
                sample_count, sample_duration);
2102

2103 2104 2105 2106 2107 2108
        if (   i+1 == entries
            && i
            && sample_count == 1
            && total_sample_count > 100
            && sample_duration/10 > duration / total_sample_count)
            sample_duration = duration / total_sample_count;
B
Baptiste Coudurier 已提交
2109
        duration+=(int64_t)sample_duration*sample_count;
2110 2111 2112
        total_sample_count+=sample_count;
    }

2113 2114
    sc->stts_count = i;

2115 2116 2117
    sc->duration_for_fps  += duration;
    sc->nb_frames_for_fps += total_sample_count;

2118 2119 2120
    if (pb->eof_reached)
        return AVERROR_EOF;

2121
    st->nb_frames= total_sample_count;
2122
    if (duration)
2123
        st->duration= duration;
2124
    sc->track_end = duration;
2125 2126 2127
    return 0;
}

2128 2129 2130 2131 2132 2133 2134
static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
{
    if (duration < 0) {
        sc->dts_shift = FFMAX(sc->dts_shift, -duration);
    }
}

2135
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
M
Michael Niedermayer 已提交
2136
{
2137 2138
    AVStream *st;
    MOVStreamContext *sc;
M
Michael Niedermayer 已提交
2139 2140
    unsigned int i, entries;

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

2146 2147 2148
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
2149

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

A
Alex Converse 已提交
2152 2153
    if (!entries)
        return 0;
2154
    if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
2155
        return AVERROR_INVALIDDATA;
2156
    sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
2157
    if (!sc->ctts_data)
2158
        return AVERROR(ENOMEM);
2159

2160
    for (i = 0; i < entries && !pb->eof_reached; i++) {
2161 2162
        int count    =avio_rb32(pb);
        int duration =avio_rb32(pb);
2163 2164 2165

        sc->ctts_data[i].count   = count;
        sc->ctts_data[i].duration= duration;
M
Michael Niedermayer 已提交
2166

2167 2168 2169
        av_dlog(c->fc, "count=%d, duration=%d\n",
                count, duration);

M
Michael Niedermayer 已提交
2170 2171 2172 2173 2174 2175 2176
        if (FFABS(duration) > (1<<28) && i+2<entries) {
            av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
            av_freep(&sc->ctts_data);
            sc->ctts_count = 0;
            return 0;
        }

2177 2178
        if (i+2<entries)
            mov_update_dts_shift(sc, duration);
M
Michael Niedermayer 已提交
2179
    }
2180

2181 2182 2183 2184 2185
    sc->ctts_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

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

M
Michael Niedermayer 已提交
2188 2189 2190
    return 0;
}

2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205 2206 2207 2208 2209 2210 2211 2212 2213 2214
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    MOVStreamContext *sc;
    unsigned int i, entries;
    uint8_t version;
    uint32_t grouping_type;

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

    version = avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    grouping_type = avio_rl32(pb);
    if (grouping_type != MKTAG( 'r','a','p',' '))
        return 0; /* only support 'rap ' grouping */
    if (version == 1)
        avio_rb32(pb); /* grouping_type_parameter */

    entries = avio_rb32(pb);
    if (!entries)
        return 0;
2215
    if (sc->rap_group)
2216
        av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
2217 2218 2219
    av_free(sc->rap_group);
    sc->rap_group_count = 0;
    sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232
    if (!sc->rap_group)
        return AVERROR(ENOMEM);

    for (i = 0; i < entries && !pb->eof_reached; i++) {
        sc->rap_group[i].count = avio_rb32(pb); /* sample_count */
        sc->rap_group[i].index = avio_rb32(pb); /* group_description_index */
    }

    sc->rap_group_count = i;

    return pb->eof_reached ? AVERROR_EOF : 0;
}

2233 2234 2235
static void mov_build_index(MOVContext *mov, AVStream *st)
{
    MOVStreamContext *sc = st->priv_data;
2236
    int64_t current_offset;
2237 2238 2239 2240
    int64_t current_dts = 0;
    unsigned int stts_index = 0;
    unsigned int stsc_index = 0;
    unsigned int stss_index = 0;
2241
    unsigned int stps_index = 0;
2242
    unsigned int i, j;
2243
    uint64_t stream_size = 0;
2244

2245
    /* adjust first dts according to edit list */
2246 2247 2248 2249
    if ((sc->empty_duration || sc->start_time) && mov->time_scale > 0) {
        if (sc->empty_duration)
            sc->empty_duration = av_rescale(sc->empty_duration, sc->time_scale, mov->time_scale);
        sc->time_offset = sc->start_time - sc->empty_duration;
2250
        current_dts = -sc->time_offset;
2251
        if (sc->ctts_count>0 && sc->stts_count>0 &&
2252
            sc->ctts_data[0].duration / FFMAX(sc->stts_data[0].duration, 1) > 16) {
2253 2254 2255 2256 2257
            /* 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;
        }
2258 2259
    }

2260
    /* only use old uncompressed audio chunk demuxing when stts specifies it */
2261
    if (!(st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
2262
          sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
2263 2264
        unsigned int current_sample = 0;
        unsigned int stts_sample = 0;
2265
        unsigned int sample_size;
2266
        unsigned int distance = 0;
2267 2268 2269
        unsigned int rap_group_index = 0;
        unsigned int rap_group_sample = 0;
        int rap_group_present = sc->rap_group_count && sc->rap_group;
2270
        int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
2271

2272 2273
        current_dts -= sc->dts_shift;

2274
        if (!sc->sample_count || st->nb_index_entries)
A
Alex Converse 已提交
2275
            return;
2276
        if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
2277
            return;
2278 2279 2280 2281
        if (av_reallocp_array(&st->index_entries,
                              st->nb_index_entries + sc->sample_count,
                              sizeof(*st->index_entries)) < 0) {
            st->nb_index_entries = 0;
2282
            return;
2283
        }
2284
        st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
2285

2286
        for (i = 0; i < sc->chunk_count; i++) {
2287
            int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
2288
            current_offset = sc->chunk_offsets[i];
2289
            while (stsc_index + 1 < sc->stsc_count &&
2290
                i + 1 == sc->stsc_data[stsc_index + 1].first)
2291
                stsc_index++;
2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 2302

            if (next_offset > current_offset && sc->sample_size>0 && sc->sample_size < sc->stsz_sample_size &&
                sc->stsc_data[stsc_index].count * (int64_t)sc->stsz_sample_size > next_offset - current_offset) {
                av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too large), ignoring\n", sc->stsz_sample_size);
                sc->stsz_sample_size = sc->sample_size;
            }
            if (sc->stsz_sample_size>0 && sc->stsz_sample_size < sc->sample_size) {
                av_log(mov->fc, AV_LOG_WARNING, "STSZ sample size %d invalid (too small), ignoring\n", sc->stsz_sample_size);
                sc->stsz_sample_size = sc->sample_size;
            }

2303
            for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
2304
                int keyframe = 0;
2305 2306
                if (current_sample >= sc->sample_count) {
                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
2307
                    return;
2308
                }
2309

2310
                if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
2311
                    keyframe = 1;
2312 2313
                    if (stss_index + 1 < sc->keyframe_count)
                        stss_index++;
2314 2315 2316 2317
                } 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++;
2318
                }
2319 2320 2321 2322 2323 2324 2325 2326
                if (rap_group_present && rap_group_index < sc->rap_group_count) {
                    if (sc->rap_group[rap_group_index].index > 0)
                        keyframe = 1;
                    if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
                        rap_group_sample = 0;
                        rap_group_index++;
                    }
                }
2327 2328 2329
                if (sc->keyframe_absent
                    && !sc->stps_count
                    && !rap_group_present
2330
                    && (st->codec->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
2331
                     keyframe = 1;
2332 2333
                if (keyframe)
                    distance = 0;
2334
                sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
2335
                if (sc->pseudo_stream_id == -1 ||
2336
                   sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
2337 2338 2339 2340 2341 2342
                    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 已提交
2343
                    av_dlog(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
2344 2345
                            "size %d, distance %d, keyframe %d\n", st->index, current_sample,
                            current_offset, current_dts, sample_size, distance, keyframe);
2346
                    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
2347
                        ff_rfps_add_frame(mov->fc, st, current_dts);
2348
                }
2349

2350
                current_offset += sample_size;
2351
                stream_size += sample_size;
2352
                current_dts += sc->stts_data[stts_index].duration;
2353 2354 2355 2356 2357 2358 2359 2360 2361
                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++;
                }
            }
        }
2362 2363
        if (st->duration > 0)
            st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;
2364
    } else {
2365
        unsigned chunk_samples, total = 0;
2366

2367 2368 2369
        // compute total chunk count
        for (i = 0; i < sc->stsc_count; i++) {
            unsigned count, chunk_count;
2370

2371
            chunk_samples = sc->stsc_data[i].count;
2372 2373
            if (i != sc->stsc_count - 1 &&
                sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
2374 2375 2376 2377
                av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
                return;
            }

2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393
            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 已提交
2394
        av_dlog(mov->fc, "chunk count %d\n", total);
2395
        if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
2396
            return;
2397 2398 2399 2400
        if (av_reallocp_array(&st->index_entries,
                              st->nb_index_entries + total,
                              sizeof(*st->index_entries)) < 0) {
            st->nb_index_entries = 0;
2401
            return;
2402
        }
2403
        st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
2404 2405 2406 2407 2408 2409 2410 2411 2412

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

2413
            while (chunk_samples > 0) {
2414
                AVIndexEntry *e;
2415 2416 2417 2418 2419 2420 2421 2422 2423 2424
                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;
2425
                    } else {
2426 2427
                        samples = FFMIN(1024, chunk_samples);
                        size = samples * sc->sample_size;
2428 2429
                    }
                }
2430

2431 2432 2433 2434 2435 2436 2437 2438 2439 2440
                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 已提交
2441
                av_dlog(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "
2442
                        "size %d, duration %d\n", st->index, i, current_offset, current_dts,
2443 2444 2445
                        size, samples);

                current_offset += size;
2446
                current_dts += samples;
2447
                chunk_samples -= samples;
2448 2449 2450 2451
            }
        }
    }
}
2452

2453
static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref,
2454
                         AVIOInterruptCB *int_cb, int use_absolute_path, AVFormatContext *fc)
2455
{
2456 2457
    /* try relative path, we do not try the absolute because it can leak information about our
       system to an attacker */
2458 2459
    if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
        char filename[1024];
2460
        const char *src_path;
2461 2462 2463 2464 2465 2466 2467 2468 2469 2470 2471 2472 2473 2474 2475 2476 2477 2478 2479
        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 */
2480
        if (i == ref->nlvl_to - 1 && src_path - src  < sizeof(filename)) {
2481 2482 2483 2484 2485 2486 2487 2488
            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);

2489
            if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL))
2490 2491
                return 0;
        }
2492 2493 2494 2495 2496
    } else if (use_absolute_path) {
        av_log(fc, AV_LOG_WARNING, "Using absolute path on user request, "
               "this is a possible security issue\n");
        if (!avio_open2(pb, ref->path, AVIO_FLAG_READ, int_cb, NULL))
            return 0;
2497 2498 2499
    }

    return AVERROR(ENOENT);
M
Mans Rullgard 已提交
2500
}
2501

2502 2503 2504 2505 2506 2507 2508 2509 2510 2511
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
{
    if (sc->time_scale <= 0) {
        av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
        sc->time_scale = c->time_scale;
        if (sc->time_scale <= 0)
            sc->time_scale = 1;
    }
}

2512
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2513 2514 2515
{
    AVStream *st;
    MOVStreamContext *sc;
2516
    int ret;
2517

2518
    st = avformat_new_stream(c->fc, NULL);
B
Baptiste Coudurier 已提交
2519
    if (!st) return AVERROR(ENOMEM);
2520
    st->id = c->fc->nb_streams;
B
Baptiste Coudurier 已提交
2521
    sc = av_mallocz(sizeof(MOVStreamContext));
2522
    if (!sc) return AVERROR(ENOMEM);
2523 2524

    st->priv_data = sc;
2525
    st->codec->codec_type = AVMEDIA_TYPE_DATA;
2526
    sc->ffindex = st->index;
2527

2528 2529 2530 2531
    if ((ret = mov_read_default(c, pb, atom)) < 0)
        return ret;

    /* sanity checks */
2532 2533
    if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
                            (!sc->sample_size && !sc->sample_count))) {
2534 2535
        av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
               st->index);
2536 2537
        return 0;
    }
2538

2539
    fix_timescale(c, sc);
2540

2541
    avpriv_set_pts_info(st, 64, 1, sc->time_scale);
2542 2543 2544 2545

    mov_build_index(c, st);

    if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
2546
        MOVDref *dref = &sc->drefs[sc->dref_id - 1];
2547 2548
        if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback,
            c->use_absolute_path, c->fc) < 0)
2549 2550 2551 2552 2553
            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);
2554
    } else {
2555
        sc->pb = c->fc->pb;
2556 2557
        sc->pb_is_copied = 1;
    }
2558

2559
    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
2560 2561 2562 2563
        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);
2564 2565
        }

A
Anton Khirnov 已提交
2566
#if FF_API_R_FRAME_RATE
2567 2568 2569
        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);
A
Anton Khirnov 已提交
2570
#endif
2571 2572
    }

R
Reimar Döffinger 已提交
2573 2574
    // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
    if (!st->codec->extradata_size && st->codec->codec_id == AV_CODEC_ID_H264 &&
2575 2576 2577 2578
        TAG_IS_AVCI(st->codec->codec_tag)) {
        ret = ff_generate_avci_extradata(st);
        if (ret < 0)
            return ret;
R
Reimar Döffinger 已提交
2579 2580
    }

2581
    switch (st->codec->codec_id) {
2582
#if CONFIG_H261_DECODER
2583
    case AV_CODEC_ID_H261:
2584
#endif
2585
#if CONFIG_H263_DECODER
2586
    case AV_CODEC_ID_H263:
2587
#endif
2588
#if CONFIG_MPEG4_DECODER
2589
    case AV_CODEC_ID_MPEG4:
2590
#endif
2591
        st->codec->width = 0; /* let decoder init width/height */
2592 2593 2594
        st->codec->height= 0;
        break;
    }
B
Baptiste Coudurier 已提交
2595 2596 2597

    /* Do not need those anymore. */
    av_freep(&sc->chunk_offsets);
2598
    av_freep(&sc->stsc_data);
B
Baptiste Coudurier 已提交
2599 2600 2601
    av_freep(&sc->sample_sizes);
    av_freep(&sc->keyframes);
    av_freep(&sc->stts_data);
2602
    av_freep(&sc->stps_data);
2603
    av_freep(&sc->rap_group);
B
Baptiste Coudurier 已提交
2604

2605
    return 0;
2606 2607
}

2608
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2609 2610 2611 2612 2613 2614 2615 2616
{
    int ret;
    c->itunes_metadata = 1;
    ret = mov_read_default(c, pb, atom);
    c->itunes_metadata = 0;
    return ret;
}

2617
static int mov_read_custom_2plus(MOVContext *c, AVIOContext *pb, int size)
2618 2619 2620 2621
{
    int64_t end = avio_tell(pb) + size;
    uint8_t *key = NULL, *val = NULL;
    int i;
2622 2623 2624 2625 2626 2627 2628
    AVStream *st;
    MOVStreamContext *sc;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;
2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661

    for (i = 0; i < 2; i++) {
        uint8_t **p;
        uint32_t len, tag;

        if (end - avio_tell(pb) <= 12)
            break;

        len = avio_rb32(pb);
        tag = avio_rl32(pb);
        avio_skip(pb, 4); // flags

        if (len < 12 || len - 12 > end - avio_tell(pb))
            break;
        len -= 12;

        if (tag == MKTAG('n', 'a', 'm', 'e'))
            p = &key;
        else if (tag == MKTAG('d', 'a', 't', 'a') && len > 4) {
            avio_skip(pb, 4);
            len -= 4;
            p = &val;
        } else
            break;

        *p = av_malloc(len + 1);
        if (!*p)
            break;
        avio_read(pb, *p, len);
        (*p)[len] = 0;
    }

    if (key && val) {
2662 2663 2664 2665 2666 2667
        if (strcmp(key, "iTunSMPB") == 0) {
            int priming, remainder, samples;
            if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
                if(priming>0 && priming<16384)
                    sc->start_pad = priming;
            }
2668 2669
        }
        if (strcmp(key, "cdec") != 0) {
2670 2671 2672 2673
            av_dict_set(&c->fc->metadata, key, val,
                        AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
            key = val = NULL;
        }
2674 2675 2676 2677 2678 2679 2680 2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 2698 2699 2700 2701 2702 2703 2704
    }

    avio_seek(pb, end, SEEK_SET);
    av_freep(&key);
    av_freep(&val);
    return 0;
}

static int mov_read_custom(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int64_t end = avio_tell(pb) + atom.size;
    uint32_t tag, len;

    if (atom.size < 8)
        goto fail;

    len = avio_rb32(pb);
    tag = avio_rl32(pb);

    if (len > atom.size)
        goto fail;

    if (tag == MKTAG('m', 'e', 'a', 'n') && len > 12) {
        uint8_t domain[128];
        int domain_len;

        avio_skip(pb, 4); // flags
        len -= 12;

        domain_len = avio_get_str(pb, len, domain, sizeof(domain));
        avio_skip(pb, len - domain_len);
2705
        return mov_read_custom_2plus(c, pb, end - avio_tell(pb));
2706 2707 2708 2709 2710 2711 2712 2713
    }

fail:
    av_log(c->fc, AV_LOG_VERBOSE,
           "Unhandled or malformed custom metadata of size %"PRId64"\n", atom.size);
    return 0;
}

2714
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2715
{
2716
    while (atom.size > 8) {
2717
        uint32_t tag = avio_rl32(pb);
2718 2719
        atom.size -= 4;
        if (tag == MKTAG('h','d','l','r')) {
A
Anton Khirnov 已提交
2720
            avio_seek(pb, -8, SEEK_CUR);
2721 2722 2723 2724 2725
            atom.size += 8;
            return mov_read_default(c, pb, atom);
        }
    }
    return 0;
2726 2727
}

2728
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2729
{
2730 2731 2732 2733
    int i;
    int width;
    int height;
    int64_t disp_transform[2];
2734
    int display_matrix[3][3];
2735 2736 2737
    AVStream *st;
    MOVStreamContext *sc;
    int version;
2738
    int flags;
2739 2740 2741 2742 2743

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

2745
    version = avio_r8(pb);
2746 2747
    flags = avio_rb24(pb);
    st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
2748

B
Baptiste Coudurier 已提交
2749
    if (version == 1) {
2750 2751
        avio_rb64(pb);
        avio_rb64(pb);
B
Baptiste Coudurier 已提交
2752
    } else {
2753 2754
        avio_rb32(pb); /* creation time */
        avio_rb32(pb); /* modification time */
B
Baptiste Coudurier 已提交
2755
    }
2756 2757
    st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
    avio_rb32(pb); /* reserved */
2758

2759
    /* highlevel (considering edits) duration in movie timebase */
2760 2761 2762
    (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
    avio_rb32(pb); /* reserved */
    avio_rb32(pb); /* reserved */
2763

2764 2765 2766 2767
    avio_rb16(pb); /* layer */
    avio_rb16(pb); /* alternate group */
    avio_rb16(pb); /* volume */
    avio_rb16(pb); /* reserved */
2768

2769 2770
    //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
    // they're kept in fixed point format through all calculations
2771 2772
    // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
    // side data, but the scale factor is not needed to calculate aspect ratio
2773
    for (i = 0; i < 3; i++) {
2774 2775
        display_matrix[i][0] = avio_rb32(pb);   // 16.16 fixed point
        display_matrix[i][1] = avio_rb32(pb);   // 16.16 fixed point
2776
        display_matrix[i][2] = avio_rb32(pb);   //  2.30 fixed point
2777
    }
2778

2779 2780
    width = avio_rb32(pb);       // 16.16 fixed point track width
    height = avio_rb32(pb);      // 16.16 fixed point track height
2781 2782
    sc->width = width >> 16;
    sc->height = height >> 16;
2783

2784 2785
    // save the matrix and add rotate metadata when it is not the default
    // identity
2786 2787 2788 2789 2790 2791 2792
    if (display_matrix[0][0] != (1 << 16) ||
        display_matrix[1][1] != (1 << 16) ||
        display_matrix[2][2] != (1 << 30) ||
        display_matrix[0][1] || display_matrix[0][2] ||
        display_matrix[1][0] || display_matrix[1][2] ||
        display_matrix[2][0] || display_matrix[2][1]) {
        int i, j;
2793
        double rotate;
2794 2795 2796 2797 2798 2799 2800 2801 2802

        av_freep(&sc->display_matrix);
        sc->display_matrix = av_malloc(sizeof(int32_t) * 9);
        if (!sc->display_matrix)
            return AVERROR(ENOMEM);

        for (i = 0; i < 3; i++)
            for (j = 0; j < 3; j++)
                sc->display_matrix[i * 3 + j] = display_matrix[j][i];
2803 2804 2805 2806 2807 2808 2809 2810 2811 2812

        rotate = av_display_rotation_get(sc->display_matrix);
        if (!isnan(rotate)) {
            char rotate_buf[64];
            rotate = -rotate;
            if (rotate < 0) // for backward compatibility
                rotate += 360;
            snprintf(rotate_buf, sizeof(rotate_buf), "%g", rotate);
            av_dict_set(&st->metadata, "rotate", rotate_buf, 0);
        }
2813 2814
    }

2815
    // transform the display width/height according to the matrix
2816
    // skip this if the display matrix is the default identity matrix
2817
    // or if it is rotating the picture, ex iPhone 3GS
2818 2819
    // to keep the same scale, use [width height 1<<16]
    if (width && height &&
2820 2821 2822 2823 2824
        ((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])) {
2825 2826 2827 2828 2829 2830 2831
        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
2832
        st->sample_aspect_ratio = av_d2q(
2833 2834 2835
            ((double) disp_transform[0] * height) /
            ((double) disp_transform[1] * width), INT_MAX);
    }
2836 2837 2838
    return 0;
}

2839
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
2840 2841 2842
{
    MOVFragment *frag = &c->fragment;
    MOVTrackExt *trex = NULL;
2843
    MOVFragmentIndex* index = NULL;
B
Baptiste Coudurier 已提交
2844 2845
    int flags, track_id, i;

2846 2847
    avio_r8(pb); /* version */
    flags = avio_rb24(pb);
B
Baptiste Coudurier 已提交
2848

2849
    track_id = avio_rb32(pb);
2850
    if (!track_id)
2851
        return AVERROR_INVALIDDATA;
B
Baptiste Coudurier 已提交
2852 2853 2854 2855 2856 2857 2858 2859
    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");
2860
        return AVERROR_INVALIDDATA;
B
Baptiste Coudurier 已提交
2861
    }
2862 2863 2864 2865 2866 2867 2868 2869 2870
    for (i = 0; i < c->fragment_index_count; i++) {
        MOVFragmentIndex* candidate = c->fragment_index_data[i];
        if (candidate->track_id == frag->track_id) {
            av_log(c->fc, AV_LOG_DEBUG,
                   "found fragment index for track %u\n", frag->track_id);
            index = candidate;
            break;
        }
    }
B
Baptiste Coudurier 已提交
2871

2872
    frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
2873 2874
                             avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
                             frag->moof_offset : frag->implicit_offset;
2875 2876 2877 2878 2879 2880 2881 2882
    frag->stsd_id  = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;

    frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
                     avio_rb32(pb) : trex->duration;
    frag->size     = flags & MOV_TFHD_DEFAULT_SIZE ?
                     avio_rb32(pb) : trex->size;
    frag->flags    = flags & MOV_TFHD_DEFAULT_FLAGS ?
                     avio_rb32(pb) : trex->flags;
2883 2884 2885 2886 2887 2888 2889 2890 2891 2892 2893 2894 2895 2896 2897 2898 2899 2900 2901
    frag->time     = AV_NOPTS_VALUE;
    if (index) {
        int i, found = 0;
        for (i = index->current_item; i < index->item_count; i++) {
            if (frag->implicit_offset == index->items[i].moof_offset) {
                av_log(c->fc, AV_LOG_DEBUG, "found fragment index entry "
                        "for track %u and moof_offset %"PRId64"\n",
                        frag->track_id, index->items[i].moof_offset);
                frag->time = index->items[i].time;
                index->current_item = i + 1;
                found = 1;
            }
        }
        if (!found) {
            av_log(c->fc, AV_LOG_WARNING, "track %u has a fragment index "
                   "but it doesn't have an (in-order) entry for moof_offset "
                   "%"PRId64"\n", frag->track_id, frag->implicit_offset);
        }
    }
L
Luca Barbato 已提交
2902
    av_dlog(c->fc, "frag flags 0x%x\n", frag->flags);
B
Baptiste Coudurier 已提交
2903 2904 2905
    return 0;
}

2906
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
D
David Conrad 已提交
2907
{
2908
    c->chapter_track = avio_rb32(pb);
D
David Conrad 已提交
2909 2910 2911
    return 0;
}

2912
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
2913 2914
{
    MOVTrackExt *trex;
2915
    int err;
B
Baptiste Coudurier 已提交
2916 2917

    if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
2918
        return AVERROR_INVALIDDATA;
2919 2920 2921 2922 2923
    if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
                                 sizeof(*c->trex_data))) < 0) {
        c->trex_count = 0;
        return err;
    }
2924 2925 2926

    c->fc->duration = AV_NOPTS_VALUE; // the duration from mvhd is not representing the whole file when fragments are used.

B
Baptiste Coudurier 已提交
2927
    trex = &c->trex_data[c->trex_count++];
2928 2929 2930 2931 2932 2933 2934
    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 已提交
2935 2936 2937
    return 0;
}

M
Martin Storsjö 已提交
2938 2939 2940 2941 2942 2943 2944 2945 2946 2947 2948 2949 2950 2951 2952 2953 2954 2955 2956 2957 2958 2959 2960 2961 2962 2963 2964 2965 2966 2967
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    MOVFragment *frag = &c->fragment;
    AVStream *st = NULL;
    MOVStreamContext *sc;
    int version, i;

    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);
        return AVERROR_INVALIDDATA;
    }
    sc = st->priv_data;
    if (sc->pseudo_stream_id + 1 != frag->stsd_id)
        return 0;
    version = avio_r8(pb);
    avio_rb24(pb); /* flags */
    if (version) {
        sc->track_end = avio_rb64(pb);
    } else {
        sc->track_end = avio_rb32(pb);
    }
    return 0;
}

2968
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
2969 2970
{
    MOVFragment *frag = &c->fragment;
2971
    AVStream *st = NULL;
2972
    MOVStreamContext *sc;
2973
    MOVStts *ctts_data;
B
Baptiste Coudurier 已提交
2974 2975 2976 2977
    uint64_t offset;
    int64_t dts;
    int data_offset = 0;
    unsigned entries, first_sample_flags = frag->flags;
2978
    int flags, distance, i, found_keyframe = 0, err;
B
Baptiste Coudurier 已提交
2979

2980 2981 2982 2983 2984 2985 2986 2987
    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);
2988
        return AVERROR_INVALIDDATA;
2989
    }
2990
    sc = st->priv_data;
2991
    if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
B
Baptiste Coudurier 已提交
2992
        return 0;
2993 2994 2995
    avio_r8(pb); /* version */
    flags = avio_rb24(pb);
    entries = avio_rb32(pb);
L
Luca Barbato 已提交
2996
    av_dlog(c->fc, "flags 0x%x entries %d\n", flags, entries);
2997 2998 2999 3000 3001 3002 3003 3004 3005

    /* 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. */
3006
        ctts_data = av_realloc(NULL, sizeof(*sc->ctts_data));
3007
        if (!ctts_data)
B
Baptiste Coudurier 已提交
3008
            return AVERROR(ENOMEM);
3009
        sc->ctts_data = ctts_data;
3010 3011 3012
        sc->ctts_data[sc->ctts_count].count = sc->sample_count;
        sc->ctts_data[sc->ctts_count].duration = 0;
        sc->ctts_count++;
B
Baptiste Coudurier 已提交
3013
    }
3014
    if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
3015
        return AVERROR_INVALIDDATA;
3016 3017 3018 3019 3020
    if ((err = av_reallocp_array(&sc->ctts_data, entries + sc->ctts_count,
                                 sizeof(*sc->ctts_data))) < 0) {
        sc->ctts_count = 0;
        return err;
    }
3021 3022
    if (flags & MOV_TRUN_DATA_OFFSET)        data_offset        = avio_rb32(pb);
    if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
3023
    dts    = sc->track_end - sc->time_offset;
B
Baptiste Coudurier 已提交
3024 3025
    offset = frag->base_data_offset + data_offset;
    distance = 0;
L
Luca Barbato 已提交
3026
    av_dlog(c->fc, "first sample flags 0x%x\n", first_sample_flags);
3027
    for (i = 0; i < entries && !pb->eof_reached; i++) {
B
Baptiste Coudurier 已提交
3028 3029 3030
        unsigned sample_size = frag->size;
        int sample_flags = i ? frag->flags : first_sample_flags;
        unsigned sample_duration = frag->duration;
3031
        int keyframe = 0;
B
Baptiste Coudurier 已提交
3032

3033 3034 3035
        if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
        if (flags & MOV_TRUN_SAMPLE_SIZE)     sample_size     = avio_rb32(pb);
        if (flags & MOV_TRUN_SAMPLE_FLAGS)    sample_flags    = avio_rb32(pb);
3036
        sc->ctts_data[sc->ctts_count].count = 1;
3037 3038
        sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
                                                  avio_rb32(pb) : 0;
3039
        mov_update_dts_shift(sc, sc->ctts_data[sc->ctts_count].duration);
3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061
        if (frag->time != AV_NOPTS_VALUE) {
            if (c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
                int64_t pts = frag->time;
                av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64
                        " sc->dts_shift %d ctts.duration %d"
                        " sc->time_offset %"PRId64" flags & MOV_TRUN_SAMPLE_CTS %d\n", pts,
                        sc->dts_shift, sc->ctts_data[sc->ctts_count].duration,
                        sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
                dts = pts - sc->dts_shift;
                if (flags & MOV_TRUN_SAMPLE_CTS) {
                    dts -= sc->ctts_data[sc->ctts_count].duration;
                } else {
                    dts -= sc->time_offset;
                }
                av_log(c->fc, AV_LOG_DEBUG, "calculated into dts %"PRId64"\n", dts);
            } else {
                dts = frag->time;
                av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64
                        ", using it for dts\n", dts);
            }
            frag->time = AV_NOPTS_VALUE;
        }
3062
        sc->ctts_count++;
3063 3064 3065 3066 3067 3068 3069
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
            keyframe = 1;
        else if (!found_keyframe)
            keyframe = found_keyframe =
                !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
                                  MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
        if (keyframe)
B
Baptiste Coudurier 已提交
3070 3071 3072
            distance = 0;
        av_add_index_entry(st, offset, dts, sample_size, distance,
                           keyframe ? AVINDEX_KEYFRAME : 0);
L
Luca Barbato 已提交
3073
        av_dlog(c->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
B
Baptiste Coudurier 已提交
3074 3075 3076
                "size %d, distance %d, keyframe %d\n", st->index, sc->sample_count+i,
                offset, dts, sample_size, distance, keyframe);
        distance++;
3077
        dts += sample_duration;
B
Baptiste Coudurier 已提交
3078
        offset += sample_size;
3079
        sc->data_size += sample_size;
3080 3081
        sc->duration_for_fps += sample_duration;
        sc->nb_frames_for_fps ++;
B
Baptiste Coudurier 已提交
3082
    }
3083 3084 3085 3086

    if (pb->eof_reached)
        return AVERROR_EOF;

3087
    frag->implicit_offset = offset;
3088
    st->duration = sc->track_end = dts + sc->time_offset;
B
Baptiste Coudurier 已提交
3089 3090 3091
    return 0;
}

3092 3093 3094
/* 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/ */
3095
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3096 3097 3098 3099 3100
{
    int err;

    if (atom.size < 8)
        return 0; /* continue */
3101
    if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
3102
        avio_skip(pb, atom.size - 4);
3103 3104
        return 0;
    }
3105
    atom.type = avio_rl32(pb);
3106
    atom.size -= 8;
3107
    if (atom.type != MKTAG('m','d','a','t')) {
3108
        avio_skip(pb, atom.size);
3109 3110 3111 3112 3113 3114
        return 0;
    }
    err = mov_read_mdat(c, pb, atom);
    return err;
}

3115
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3116
{
3117
#if CONFIG_ZLIB
3118
    AVIOContext ctx;
3119 3120
    uint8_t *cmov_data;
    uint8_t *moov_data; /* uncompressed data */
3121
    long cmov_len, moov_len;
3122
    int ret = -1;
3123

3124 3125
    avio_rb32(pb); /* dcom atom */
    if (avio_rl32(pb) != MKTAG('d','c','o','m'))
3126
        return AVERROR_INVALIDDATA;
3127
    if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
3128
        av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
3129
        return AVERROR_INVALIDDATA;
3130
    }
3131 3132
    avio_rb32(pb); /* cmvd atom */
    if (avio_rl32(pb) != MKTAG('c','m','v','d'))
3133
        return AVERROR_INVALIDDATA;
3134
    moov_len = avio_rb32(pb); /* uncompressed size */
3135
    cmov_len = atom.size - 6 * 4;
3136

B
Baptiste Coudurier 已提交
3137
    cmov_data = av_malloc(cmov_len);
3138
    if (!cmov_data)
3139
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
3140
    moov_data = av_malloc(moov_len);
3141 3142
    if (!moov_data) {
        av_free(cmov_data);
3143
        return AVERROR(ENOMEM);
3144
    }
3145
    avio_read(pb, cmov_data, cmov_len);
3146
    if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
3147
        goto free_and_return;
3148
    if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
3149
        goto free_and_return;
3150
    atom.type = MKTAG('m','o','o','v');
3151 3152
    atom.size = moov_len;
    ret = mov_read_default(c, &ctx, atom);
3153
free_and_return:
3154 3155 3156
    av_free(moov_data);
    av_free(cmov_data);
    return ret;
3157 3158
#else
    av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
3159
    return AVERROR(ENOSYS);
3160
#endif
3161
}
3162

G
Gael Chardon 已提交
3163
/* edit list atom */
3164
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
G
Gael Chardon 已提交
3165
{
3166
    MOVStreamContext *sc;
3167
    int i, edit_count, version, edit_start_index = 0;
3168
    int unsupported = 0;
B
Baptiste Coudurier 已提交
3169

3170
    if (c->fc->nb_streams < 1 || c->ignore_editlist)
3171 3172 3173
        return 0;
    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;

3174
    version = avio_r8(pb); /* version */
3175 3176
    avio_rb24(pb); /* flags */
    edit_count = avio_rb32(pb); /* entries */
B
Baptiste Coudurier 已提交
3177

3178
    if ((uint64_t)edit_count*12+8 > atom.size)
3179
        return AVERROR_INVALIDDATA;
3180

3181
    av_dlog(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count);
3182
    for (i=0; i<edit_count; i++){
3183 3184
        int64_t time;
        int64_t duration;
3185
        int rate;
3186 3187 3188 3189 3190
        if (version == 1) {
            duration = avio_rb64(pb);
            time     = avio_rb64(pb);
        } else {
            duration = avio_rb32(pb); /* segment duration */
Y
Yusuke Nakamura 已提交
3191
            time     = (int32_t)avio_rb32(pb); /* media time */
3192
        }
3193
        rate = avio_rb32(pb);
3194 3195 3196 3197 3198
        if (i == 0 && time == -1) {
            sc->empty_duration = duration;
            edit_start_index = 1;
        } else if (i == edit_start_index && time >= 0)
            sc->start_time = time;
3199 3200
        else
            unsupported = 1;
3201 3202 3203

        av_dlog(c->fc, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
                duration, time, rate / 65536.0);
B
Baptiste Coudurier 已提交
3204
    }
3205

3206
    if (unsupported)
3207 3208 3209
        av_log(c->fc, AV_LOG_WARNING, "multiple edit list entries, "
               "a/v desync might occur, patch welcome\n");

B
Baptiste Coudurier 已提交
3210
    return 0;
G
Gael Chardon 已提交
3211 3212
}

3213
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
C
Clément Bœsch 已提交
3214 3215 3216 3217 3218 3219
{
    MOVStreamContext *sc;

    if (c->fc->nb_streams < 1)
        return AVERROR_INVALIDDATA;
    sc = c->fc->streams[c->fc->nb_streams - 1]->priv_data;
3220
    sc->timecode_track = avio_rb32(pb);
C
Clément Bœsch 已提交
3221 3222 3223
    return 0;
}

3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int ret;
    uint8_t uuid[16];
    static const uint8_t uuid_isml_manifest[] = {
        0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
        0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
    };

    if (atom.size < sizeof(uuid) || atom.size == INT64_MAX)
        return AVERROR_INVALIDDATA;

    ret = avio_read(pb, uuid, sizeof(uuid));
    if (ret < 0) {
        return ret;
    } else if (ret != sizeof(uuid)) {
        return AVERROR_INVALIDDATA;
    }
    if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
        uint8_t *buffer, *ptr;
        char *endptr;
        size_t len = atom.size - sizeof(uuid);

        if (len < 4) {
            return AVERROR_INVALIDDATA;
        }
        ret = avio_skip(pb, 4); // zeroes
        len -= 4;

        buffer = av_mallocz(len + 1);
        if (!buffer) {
            return AVERROR(ENOMEM);
        }
        ret = avio_read(pb, buffer, len);
        if (ret < 0) {
            av_free(buffer);
            return ret;
        } else if (ret != len) {
            av_free(buffer);
            return AVERROR_INVALIDDATA;
        }

        ptr = buffer;
3267
        while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289
            ptr += sizeof("systemBitrate=\"") - 1;
            c->bitrates_count++;
            c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
            if (!c->bitrates) {
                c->bitrates_count = 0;
                av_free(buffer);
                return AVERROR(ENOMEM);
            }
            errno = 0;
            ret = strtol(ptr, &endptr, 10);
            if (ret < 0 || errno || *endptr != '"') {
                c->bitrates[c->bitrates_count - 1] = 0;
            } else {
                c->bitrates[c->bitrates_count - 1] = ret;
            }
        }

        av_free(buffer);
    }
    return 0;
}

3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int ret;
    uint8_t content[16];

    if (atom.size < 8)
        return 0;

    ret = avio_read(pb, content, FFMIN(sizeof(content), atom.size));
    if (ret < 0)
        return ret;

    if (   !c->found_moov
        && !c->found_mdat
        && !memcmp(content, "Anevia\x1A\x1A", 8)
        && c->use_mfra_for == FF_MOV_FLAG_MFRA_AUTO) {
        c->use_mfra_for = FF_MOV_FLAG_MFRA_PTS;
    }

    return 0;
}

3312
static const MOVParseTableEntry mov_default_parse_table[] = {
C
Carl Eugen Hoyos 已提交
3313 3314
{ MKTAG('A','C','L','R'), mov_read_avid },
{ MKTAG('A','P','R','G'), mov_read_avid },
P
Piotr Bandurski 已提交
3315
{ MKTAG('A','A','L','P'), mov_read_avid },
3316
{ MKTAG('A','R','E','S'), mov_read_ares },
3317
{ MKTAG('a','v','s','s'), mov_read_avss },
D
David Conrad 已提交
3318
{ MKTAG('c','h','p','l'), mov_read_chpl },
3319
{ MKTAG('c','o','6','4'), mov_read_stco },
3320
{ MKTAG('c','o','l','r'), mov_read_colr },
3321 3322 3323 3324 3325 3326
{ 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 },
3327
{ MKTAG('f','i','e','l'), mov_read_fiel },
3328 3329 3330
{ MKTAG('f','t','y','p'), mov_read_ftyp },
{ MKTAG('g','l','b','l'), mov_read_glbl },
{ MKTAG('h','d','l','r'), mov_read_hdlr },
3331
{ MKTAG('i','l','s','t'), mov_read_ilst },
3332
{ MKTAG('j','p','2','h'), mov_read_jp2h },
3333 3334 3335
{ MKTAG('m','d','a','t'), mov_read_mdat },
{ MKTAG('m','d','h','d'), mov_read_mdhd },
{ MKTAG('m','d','i','a'), mov_read_default },
3336
{ MKTAG('m','e','t','a'), mov_read_meta },
3337 3338 3339 3340 3341
{ 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 },
P
Piotr Bandurski 已提交
3342
{ MKTAG('S','M','I',' '), mov_read_svq3 },
3343
{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
3344
{ MKTAG('a','v','c','C'), mov_read_glbl },
3345
{ MKTAG('p','a','s','p'), mov_read_pasp },
3346 3347
{ MKTAG('s','t','b','l'), mov_read_default },
{ MKTAG('s','t','c','o'), mov_read_stco },
3348
{ MKTAG('s','t','p','s'), mov_read_stps },
M
Martin Storsjö 已提交
3349
{ MKTAG('s','t','r','f'), mov_read_strf },
3350 3351 3352 3353 3354
{ 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 },
3355
{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
3356
{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
M
Martin Storsjö 已提交
3357
{ MKTAG('t','f','d','t'), mov_read_tfdt },
3358 3359 3360
{ 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 },
3361 3362
{ MKTAG('t','r','e','f'), mov_read_default },
{ MKTAG('t','m','c','d'), mov_read_tmcd },
D
David Conrad 已提交
3363
{ MKTAG('c','h','a','p'), mov_read_chap },
3364 3365
{ MKTAG('t','r','e','x'), mov_read_trex },
{ MKTAG('t','r','u','n'), mov_read_trun },
B
Baptiste Coudurier 已提交
3366
{ MKTAG('u','d','t','a'), mov_read_default },
3367 3368
{ MKTAG('w','a','v','e'), mov_read_wave },
{ MKTAG('e','s','d','s'), mov_read_esds },
3369
{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
3370
{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
3371
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
3372
{ MKTAG('w','f','e','x'), mov_read_wfex },
3373
{ MKTAG('c','m','o','v'), mov_read_cmov },
3374
{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
M
Martin Storsjö 已提交
3375
{ MKTAG('d','v','c','1'), mov_read_dvc1 },
3376
{ MKTAG('s','b','g','p'), mov_read_sbgp },
Y
Yusuke Nakamura 已提交
3377
{ MKTAG('h','v','c','C'), mov_read_glbl },
3378
{ MKTAG('u','u','i','d'), mov_read_uuid },
3379
{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
3380
{ MKTAG('f','r','e','e'), mov_read_free },
3381
{ MKTAG('-','-','-','-'), mov_read_custom },
B
Baptiste Coudurier 已提交
3382
{ 0, NULL }
3383 3384
};

3385 3386 3387 3388 3389 3390 3391 3392
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int64_t total_size = 0;
    MOVAtom a;
    int i;

    if (atom.size < 0)
        atom.size = INT64_MAX;
3393
    while (total_size + 8 <= atom.size && !avio_feof(pb)) {
3394 3395 3396 3397 3398 3399
        int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
        a.size = atom.size;
        a.type=0;
        if (atom.size >= 8) {
            a.size = avio_rb32(pb);
            a.type = avio_rl32(pb);
3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412
            if (a.type == MKTAG('f','r','e','e') &&
                a.size >= 8 &&
                c->moov_retry) {
                uint8_t buf[8];
                uint32_t *type = (uint32_t *)buf + 1;
                avio_read(pb, buf, 8);
                avio_seek(pb, -8, SEEK_CUR);
                if (*type == MKTAG('m','v','h','d') ||
                    *type == MKTAG('c','m','o','v')) {
                    av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
                    a.type = MKTAG('m','o','o','v');
                }
            }
3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427
            if (atom.type != MKTAG('r','o','o','t') &&
                atom.type != MKTAG('m','o','o','v'))
            {
                if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
                {
                    av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
                    avio_skip(pb, -8);
                    return 0;
                }
            }
            total_size += 8;
            if (a.size == 1) { /* 64 bit extended size */
                a.size = avio_rb64(pb) - 8;
                total_size += 8;
            }
3428 3429 3430 3431
        }
        av_dlog(c->fc, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
                a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size);
        if (a.size == 0) {
3432
            a.size = atom.size - total_size + 8;
3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467
        }
        a.size -= 8;
        if (a.size < 0)
            break;
        a.size = FFMIN(a.size, atom.size - total_size);

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

        // 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 */
            avio_skip(pb, a.size);
        } else {
            int64_t start_pos = avio_tell(pb);
            int64_t left;
            int err = parse(c, pb, a);
            if (err < 0)
                return err;
            if (c->found_moov && c->found_mdat &&
                ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) ||
                 start_pos + a.size == avio_size(pb))) {
                if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX)
                    c->next_root_atom = start_pos + a.size;
                return 0;
            }
            left = a.size - avio_tell(pb) + start_pos;
            if (left > 0) /* skip garbage at atom end */
                avio_skip(pb, left);
3468 3469 3470 3471
            else if (left < 0) {
                av_log(c->fc, AV_LOG_WARNING,
                       "overread end of atom '%.4s' by %"PRId64" bytes\n",
                       (char*)&a.type, -left);
3472 3473
                avio_seek(pb, left, SEEK_CUR);
            }
3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484
        }

        total_size += a.size;
    }

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

    return 0;
}

F
Fabrice Bellard 已提交
3485 3486
static int mov_probe(AVProbeData *p)
{
3487
    int64_t offset;
3488
    uint32_t tag;
3489
    int score = 0;
3490
    int moov_offset = -1;
3491

F
Fabrice Bellard 已提交
3492
    /* check file header */
3493
    offset = 0;
3494
    for (;;) {
3495 3496
        /* ignore invalid offset */
        if ((offset + 8) > (unsigned int)p->buf_size)
3497
            break;
3498
        tag = AV_RL32(p->buf + offset + 4);
3499
        switch(tag) {
3500
        /* check for obvious tags */
3501
        case MKTAG('m','o','o','v'):
3502
            moov_offset = offset + 4;
3503 3504 3505
        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 */
3506
        case MKTAG('f','t','y','p'):
3507 3508 3509 3510
            if (AV_RB32(p->buf+offset) < 8 &&
                (AV_RB32(p->buf+offset) != 1 ||
                 offset + 12 > (unsigned int)p->buf_size ||
                 AV_RB64(p->buf+offset + 8) == 0)) {
3511
                score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
3512 3513 3514
            } else if (tag == MKTAG('f','t','y','p') &&
                       AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')) {
                score = FFMAX(score, 5);
3515 3516 3517
            } else {
                score = AVPROBE_SCORE_MAX;
            }
3518 3519
            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
            break;
3520
        /* those are more common words, so rate then a bit less */
3521 3522 3523 3524 3525
        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'):
3526 3527 3528
            score  = FFMAX(score, AVPROBE_SCORE_MAX - 5);
            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
            break;
B
Baptiste Coudurier 已提交
3529
        case MKTAG(0x82,0x82,0x7f,0x7d):
3530 3531 3532
        case MKTAG('s','k','i','p'):
        case MKTAG('u','u','i','d'):
        case MKTAG('p','r','f','l'):
3533
            /* if we only find those cause probedata is too small at least rate them */
3534
            score  = FFMAX(score, AVPROBE_SCORE_EXTENSION);
3535
            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
3536 3537
            break;
        default:
3538 3539 3540
            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
        }
    }
3541
    if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
3542 3543 3544 3545
        /* moov atom in the header - we should make sure that this is not a
         * MOV-packed MPEG-PS */
        offset = moov_offset;

3546 3547 3548 3549 3550 3551 3552 3553
        while(offset < (p->buf_size - 16)){ /* Sufficient space */
               /* We found an actual hdlr atom */
            if(AV_RL32(p->buf + offset     ) == MKTAG('h','d','l','r') &&
               AV_RL32(p->buf + offset +  8) == MKTAG('m','h','l','r') &&
               AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
                av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
                /* We found a media handler reference atom describing an
                 * MPEG-PS-in-MOV, return a
3554 3555 3556 3557 3558 3559
                 * low score to force expanding the probe window until
                 * mpegps_probe finds what it needs */
                return 5;
            }else
                /* Keep looking */
                offset+=2;
3560
        }
3561
    }
3562 3563

    return score;
F
Fabrice Bellard 已提交
3564 3565
}

D
David Conrad 已提交
3566 3567 3568 3569 3570 3571 3572
// 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;
3573
    int i;
D
David Conrad 已提交
3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586

    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;
3587
    cur_pos = avio_tell(sc->pb);
D
David Conrad 已提交
3588 3589 3590 3591

    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;
3592 3593 3594
        uint8_t *title;
        uint16_t ch;
        int len, title_len;
D
David Conrad 已提交
3595

3596 3597 3598 3599 3600
        if (end < sample->timestamp) {
            av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
            end = AV_NOPTS_VALUE;
        }

A
Anton Khirnov 已提交
3601
        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
D
David Conrad 已提交
3602 3603 3604 3605 3606
            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
3607
        len = avio_rb16(sc->pb);
D
David Conrad 已提交
3608 3609
        if (len > sample->size-2)
            continue;
3610 3611 3612
        title_len = 2*len + 1;
        if (!(title = av_mallocz(title_len)))
            goto finish;
D
David Conrad 已提交
3613 3614 3615 3616

        // 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
3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627
        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)
3628
                    title[len] = 0;
3629
                else
3630
                    avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
3631
            }
D
David Conrad 已提交
3632 3633
        }

3634
        avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
3635
        av_freep(&title);
D
David Conrad 已提交
3636 3637
    }
finish:
A
Anton Khirnov 已提交
3638
    avio_seek(sc->pb, cur_pos, SEEK_SET);
D
David Conrad 已提交
3639 3640
}

3641
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
3642
                                             uint32_t value, int flags)
3643
{
3644 3645 3646 3647 3648 3649 3650
    AVTimecode tc;
    char buf[AV_TIMECODE_STR_SIZE];
    AVRational rate = {st->codec->time_base.den,
                       st->codec->time_base.num};
    int ret = av_timecode_init(&tc, rate, flags, 0, s);
    if (ret < 0)
        return ret;
3651
    av_dict_set(&st->metadata, "timecode",
3652
                av_timecode_make_string(&tc, buf, value), 0);
3653 3654 3655 3656 3657 3658
    return 0;
}

static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
{
    MOVStreamContext *sc = st->priv_data;
3659
    int flags = 0;
3660 3661 3662 3663 3664 3665 3666 3667 3668
    int64_t cur_pos = avio_tell(sc->pb);
    uint32_t value;

    if (!st->nb_index_entries)
        return -1;

    avio_seek(sc->pb, st->index_entries->pos, SEEK_SET);
    value = avio_rb32(s->pb);

3669 3670 3671 3672
    if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
    if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
    if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;

3673 3674 3675 3676 3677
    /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
     * not the case) and thus assume "frame number format" instead of QT one.
     * No sample with tmcd track can be found with a QT timecode at the moment,
     * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
     * format). */
3678
    parse_timecode_in_framenum_format(s, st, value, flags);
3679 3680 3681 3682 3683

    avio_seek(sc->pb, cur_pos, SEEK_SET);
    return 0;
}

3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698
static int mov_read_close(AVFormatContext *s)
{
    MOVContext *mov = s->priv_data;
    int i, j;

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

        av_freep(&sc->ctts_data);
        for (j = 0; j < sc->drefs_count; j++) {
            av_freep(&sc->drefs[j].path);
            av_freep(&sc->drefs[j].dir);
        }
        av_freep(&sc->drefs);
3699 3700 3701

        sc->drefs_count = 0;

3702
        if (!sc->pb_is_copied)
3703
            avio_close(sc->pb);
3704

3705
        sc->pb = NULL;
3706 3707
        av_freep(&sc->chunk_offsets);
        av_freep(&sc->stsc_data);
3708 3709
        av_freep(&sc->sample_sizes);
        av_freep(&sc->keyframes);
3710
        av_freep(&sc->stts_data);
3711 3712
        av_freep(&sc->stps_data);
        av_freep(&sc->rap_group);
3713
        av_freep(&sc->display_matrix);
3714 3715 3716
    }

    if (mov->dv_demux) {
3717 3718
        avformat_free_context(mov->dv_fctx);
        mov->dv_fctx = NULL;
3719 3720 3721
    }

    av_freep(&mov->trex_data);
3722
    av_freep(&mov->bitrates);
3723

3724 3725 3726 3727 3728 3729 3730
    for (i = 0; i < mov->fragment_index_count; i++) {
        MOVFragmentIndex* index = mov->fragment_index_data[i];
        av_freep(&index->items);
        av_freep(&mov->fragment_index_data[i]);
    }
    av_freep(&mov->fragment_index_data);

3731 3732 3733
    return 0;
}

3734 3735
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
{
3736
    int i;
3737 3738 3739 3740 3741

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

3742 3743 3744
        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
            sc->timecode_track == tmcd_id)
            return 1;
3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767
    }
    return 0;
}

/* look for a tmcd track not referenced by any video track, and export it globally */
static void export_orphan_timecode(AVFormatContext *s)
{
    int i;

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

        if (st->codec->codec_tag  == MKTAG('t','m','c','d') &&
            !tmcd_is_referenced(s, i + 1)) {
            AVDictionaryEntry *tcr = av_dict_get(st->metadata, "timecode", NULL, 0);
            if (tcr) {
                av_dict_set(&s->metadata, "timecode", tcr->value, 0);
                break;
            }
        }
    }
}

3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828
static int read_tfra(MOVContext *mov, AVIOContext *f)
{
    MOVFragmentIndex* index = NULL;
    int version, fieldlength, i, j, err;
    int64_t pos = avio_tell(f);
    uint32_t size = avio_rb32(f);
    if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
        return -1;
    }
    av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
    index = av_mallocz(sizeof(MOVFragmentIndex));
    if (!index) {
        return AVERROR(ENOMEM);
    }
    mov->fragment_index_count++;
    if ((err = av_reallocp(&mov->fragment_index_data,
                           mov->fragment_index_count *
                           sizeof(MOVFragmentIndex*))) < 0) {
        av_freep(&index);
        return err;
    }
    mov->fragment_index_data[mov->fragment_index_count - 1] =
        index;

    version = avio_r8(f);
    avio_rb24(f);
    index->track_id = avio_rb32(f);
    fieldlength = avio_rb32(f);
    index->item_count = avio_rb32(f);
    index->items = av_mallocz(
            index->item_count * sizeof(MOVFragmentIndexItem));
    if (!index->items) {
        return AVERROR(ENOMEM);
    }
    for (i = 0; i < index->item_count; i++) {
        int64_t time, offset;
        if (version == 1) {
            time   = avio_rb64(f);
            offset = avio_rb64(f);
        } else {
            time   = avio_rb32(f);
            offset = avio_rb32(f);
        }
        index->items[i].time = time;
        index->items[i].moof_offset = offset;
        for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
            avio_r8(f);
        for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
            avio_r8(f);
        for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
            avio_r8(f);
    }

    avio_seek(f, pos + size, SEEK_SET);
    return 0;
}

static int mov_read_mfra(MOVContext *c, AVIOContext *f)
{
    int64_t stream_size = avio_size(f);
    int64_t original_pos = avio_tell(f);
3829
    int64_t seek_ret;
3830 3831
    int32_t mfra_size;
    int ret = -1;
3832 3833 3834 3835
    if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
        ret = seek_ret;
        goto fail;
    }
3836 3837 3838 3839 3840
    mfra_size = avio_rb32(f);
    if (mfra_size < 0 || mfra_size > stream_size) {
        av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
        goto fail;
    }
3841 3842 3843 3844
    if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
        ret = seek_ret;
        goto fail;
    }
3845 3846 3847 3848 3849 3850 3851 3852
    if (avio_rb32(f) != mfra_size) {
        av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
        goto fail;
    }
    if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
        av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
        goto fail;
    }
3853
    ret = 0;
3854 3855 3856 3857 3858
    av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
    while (!read_tfra(c, f)) {
        /* Empty */
    }
fail:
3859 3860
    seek_ret = avio_seek(f, original_pos, SEEK_SET);
    if (seek_ret < 0) {
3861 3862
        av_log(c->fc, AV_LOG_ERROR,
               "failed to seek back after looking for mfra\n");
3863 3864
        ret = seek_ret;
    }
3865 3866 3867
    return ret;
}

3868
static int mov_read_header(AVFormatContext *s)
3869
{
3870
    MOVContext *mov = s->priv_data;
3871
    AVIOContext *pb = s->pb;
3872
    int j, err;
3873
    MOVAtom atom = { AV_RL32("root") };
3874
    int i;
3875 3876

    mov->fc = s;
3877
    /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
3878
    if (pb->seekable)
A
Anton Khirnov 已提交
3879
        atom.size = avio_size(pb);
3880
    else
B
Baptiste Coudurier 已提交
3881
        atom.size = INT64_MAX;
3882 3883

    /* check MOV header */
3884 3885 3886
    do {
    if (mov->moov_retry)
        avio_seek(pb, 0, SEEK_SET);
B
Baptiste Coudurier 已提交
3887
    if ((err = mov_read_default(mov, pb, atom)) < 0) {
3888
        av_log(s, AV_LOG_ERROR, "error reading header\n");
3889
        mov_read_close(s);
B
Baptiste Coudurier 已提交
3890 3891
        return err;
    }
3892
    } while (pb->seekable && !mov->found_moov && !mov->moov_retry++);
B
Baptiste Coudurier 已提交
3893 3894
    if (!mov->found_moov) {
        av_log(s, AV_LOG_ERROR, "moov atom not found\n");
3895
        mov_read_close(s);
3896
        return AVERROR_INVALIDDATA;
3897
    }
3898
    av_dlog(mov->fc, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
3899

3900 3901 3902 3903 3904 3905 3906
    if (pb->seekable) {
        if (mov->chapter_track > 0)
            mov_read_chapters(s);
        for (i = 0; i < s->nb_streams; i++)
            if (s->streams[i]->codec->codec_tag == AV_RL32("tmcd"))
                mov_read_timecode_track(s, s->streams[i]);
    }
D
David Conrad 已提交
3907

3908 3909 3910 3911
    /* copy timecode metadata from tmcd tracks to the related video streams */
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
        MOVStreamContext *sc = st->priv_data;
3912
        if (sc->timecode_track > 0) {
3913
            AVDictionaryEntry *tcr;
3914
            int tmcd_st_id = -1;
3915

3916 3917 3918 3919
            for (j = 0; j < s->nb_streams; j++)
                if (s->streams[j]->id == sc->timecode_track)
                    tmcd_st_id = j;

3920
            if (tmcd_st_id < 0 || tmcd_st_id == i)
3921 3922 3923 3924 3925 3926
                continue;
            tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
            if (tcr)
                av_dict_set(&st->metadata, "timecode", tcr->value, 0);
        }
    }
3927
    export_orphan_timecode(s);
3928

3929 3930 3931
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
        MOVStreamContext *sc = st->priv_data;
3932
        fix_timescale(mov, sc);
3933
        if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) {
3934 3935
            st->skip_samples = sc->start_pad;
        }
3936 3937
        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
            av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
3938
                      sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
3939
        if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
V
Vittorio Giovara 已提交
3940
            if (st->codec->width <= 0 || st->codec->height <= 0) {
3941 3942 3943
                st->codec->width  = sc->width;
                st->codec->height = sc->height;
            }
3944 3945 3946 3947
            if (st->codec->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
                if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
                    return err;
            }
3948
        }
3949 3950
    }

3951 3952 3953 3954
    if (mov->trex_data) {
        for (i = 0; i < s->nb_streams; i++) {
            AVStream *st = s->streams[i];
            MOVStreamContext *sc = st->priv_data;
3955
            if (st->duration > 0)
3956 3957 3958 3959
                st->codec->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
        }
    }

3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970
    if (mov->use_mfra_for > 0) {
        for (i = 0; i < s->nb_streams; i++) {
            AVStream *st = s->streams[i];
            MOVStreamContext *sc = st->priv_data;
            if (sc->duration_for_fps > 0) {
                st->codec->bit_rate = sc->data_size * 8 * sc->time_scale /
                    sc->duration_for_fps;
            }
        }
    }

3971 3972 3973 3974 3975 3976
    for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
        if (mov->bitrates[i]) {
            s->streams[i]->codec->bit_rate = mov->bitrates[i];
        }
    }

3977 3978
    ff_rfps_calculate(s);

3979 3980
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
3981
        MOVStreamContext *sc = st->priv_data;
3982

3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009
        switch (st->codec->codec_type) {
        case AVMEDIA_TYPE_AUDIO:
            err = ff_replaygain_export(st, s->metadata);
            if (err < 0) {
                mov_read_close(s);
                return err;
            }
            break;
        case AVMEDIA_TYPE_VIDEO:
            if (sc->display_matrix) {
                AVPacketSideData *sd, *tmp;

                tmp = av_realloc_array(st->side_data,
                                       st->nb_side_data + 1, sizeof(*tmp));
                if (!tmp)
                    return AVERROR(ENOMEM);

                st->side_data = tmp;
                st->nb_side_data++;

                sd = &st->side_data[st->nb_side_data - 1];
                sd->type = AV_PKT_DATA_DISPLAYMATRIX;
                sd->size = sizeof(int32_t) * 9;
                sd->data = (uint8_t*)sc->display_matrix;
                sc->display_matrix = NULL;
            }
            break;
4010 4011 4012
        }
    }

4013 4014 4015
    return 0;
}

4016
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
4017
{
4018
    AVIndexEntry *sample = NULL;
4019
    int64_t best_dts = INT64_MAX;
4020
    int i;
B
Baptiste Coudurier 已提交
4021
    for (i = 0; i < s->nb_streams; i++) {
4022 4023
        AVStream *avst = s->streams[i];
        MOVStreamContext *msc = avst->priv_data;
4024
        if (msc->pb && msc->current_sample < avst->nb_index_entries) {
4025
            AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
4026
            int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
L
Luca Barbato 已提交
4027
            av_dlog(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
4028 4029
            if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) ||
                (s->pb->seekable &&
4030
                 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
B
Baptiste Coudurier 已提交
4031
                 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
4032
                  (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
4033 4034
                sample = current_sample;
                best_dts = dts;
4035
                *st = avst;
4036
            }
4037 4038
        }
    }
4039 4040 4041 4042 4043 4044 4045 4046 4047 4048
    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;
4049
    mov->fc = s;
4050 4051
 retry:
    sample = mov_find_next_sample(s, &st);
4052 4053
    if (!sample) {
        mov->found_mdat = 0;
4054 4055 4056 4057 4058
        if (!mov->next_root_atom)
            return AVERROR_EOF;
        avio_seek(s->pb, mov->next_root_atom, SEEK_SET);
        mov->next_root_atom = 0;
        if (mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
4059
            avio_feof(s->pb))
B
Baptiste Coudurier 已提交
4060
            return AVERROR_EOF;
4061
        av_dlog(s, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
4062 4063
        goto retry;
    }
4064
    sc = st->priv_data;
4065 4066
    /* must be done just before reading, to avoid infinite loop on sample */
    sc->current_sample++;
4067

4068 4069 4070 4071 4072
    if (mov->next_root_atom) {
        sample->pos = FFMIN(sample->pos, mov->next_root_atom);
        sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
    }

4073
    if (st->discard != AVDISCARD_ALL) {
A
Anton Khirnov 已提交
4074
        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
R
Reimar Döffinger 已提交
4075 4076
            av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
                   sc->ffindex, sample->pos);
4077
            return AVERROR_INVALIDDATA;
R
Reimar Döffinger 已提交
4078 4079
        }
        ret = av_get_packet(sc->pb, pkt, sample->size);
4080 4081
        if (ret < 0)
            return ret;
4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092
        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 已提交
4093 4094
#if CONFIG_DV_DEMUXER
        if (mov->dv_demux && sc->dv_audio_container) {
4095
            avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
R
Reimar Döffinger 已提交
4096 4097
            av_free(pkt->data);
            pkt->size = 0;
4098
            ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
R
Reimar Döffinger 已提交
4099 4100 4101
            if (ret < 0)
                return ret;
        }
4102
#endif
4103 4104
    }

4105 4106
    pkt->stream_index = sc->ffindex;
    pkt->dts = sample->timestamp;
4107
    if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
4108
        pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
4109
        /* update ctts context */
4110 4111 4112 4113 4114
        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;
4115
        }
4116 4117
        if (sc->wrong_dts)
            pkt->dts = AV_NOPTS_VALUE;
4118
    } else {
4119
        int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
4120 4121
            st->index_entries[sc->current_sample].timestamp : st->duration;
        pkt->duration = next_dts - pkt->dts;
4122
        pkt->pts = pkt->dts;
4123
    }
4124 4125
    if (st->discard == AVDISCARD_ALL)
        goto retry;
4126
    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
4127
    pkt->pos = sample->pos;
L
Luca Barbato 已提交
4128
    av_dlog(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64", duration %d\n",
4129
            pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration);
4130 4131
    return 0;
}
4132

4133
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
4134 4135 4136 4137
{
    MOVStreamContext *sc = st->priv_data;
    int sample, time_sample;
    int i;
4138

4139
    sample = av_index_search_timestamp(st, timestamp, flags);
L
Luca Barbato 已提交
4140
    av_dlog(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
4141 4142
    if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
        sample = 0;
4143
    if (sample < 0) /* not sure what to do */
4144
        return AVERROR_INVALIDDATA;
4145
    sc->current_sample = sample;
L
Luca Barbato 已提交
4146
    av_dlog(s, "stream %d, found sample %d\n", st->index, sc->current_sample);
4147 4148 4149 4150
    /* adjust ctts index */
    if (sc->ctts_data) {
        time_sample = 0;
        for (i = 0; i < sc->ctts_count; i++) {
4151 4152
            int next = time_sample + sc->ctts_data[i].count;
            if (next > sc->current_sample) {
4153 4154
                sc->ctts_index = i;
                sc->ctts_sample = sc->current_sample - time_sample;
4155
                break;
4156
            }
4157
            time_sample = next;
4158 4159
        }
    }
4160
    return sample;
4161 4162
}

4163
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
G
Gael Chardon 已提交
4164
{
4165 4166 4167 4168
    AVStream *st;
    int64_t seek_timestamp, timestamp;
    int sample;
    int i;
G
Gael Chardon 已提交
4169

4170
    if (stream_index >= s->nb_streams)
4171
        return AVERROR_INVALIDDATA;
G
Gael Chardon 已提交
4172

4173
    st = s->streams[stream_index];
4174
    sample = mov_seek_stream(s, st, sample_time, flags);
4175
    if (sample < 0)
4176
        return sample;
G
Gael Chardon 已提交
4177

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

4181
    for (i = 0; i < s->nb_streams; i++) {
4182
        MOVStreamContext *sc = s->streams[i]->priv_data;
4183
        st = s->streams[i];
4184 4185
        st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;

4186
        if (stream_index == i)
4187
            continue;
G
Gael Chardon 已提交
4188

4189
        timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
4190
        mov_seek_stream(s, st, timestamp, flags);
4191
    }
G
Gael Chardon 已提交
4192 4193 4194
    return 0;
}

4195 4196 4197
#define OFFSET(x) offsetof(MOVContext, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption mov_options[] = {
4198 4199
    {"use_absolute_path",
        "allow using absolute path when opening alias, this is a possible security issue",
4200
        offsetof(MOVContext, use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0},
4201
        0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM},
4202
    {"ignore_editlist", "", offsetof(MOVContext, ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0},
4203
        0, 1, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM},
4204 4205
    {"use_mfra_for",
        "use mfra for fragment timestamps",
4206 4207
        offsetof(MOVContext, use_mfra_for), FF_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
        -1, FF_MOV_FLAG_MFRA_PTS, AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM,
4208
        "use_mfra_for"},
4209 4210
    {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
        AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM, "use_mfra_for" },
4211 4212 4213 4214
    {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
        AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM, "use_mfra_for" },
    {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
        AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM, "use_mfra_for" },
4215 4216 4217
    { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
        AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS },
    { NULL },
4218 4219
};

4220
static const AVClass mov_class = {
4221 4222
    .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
    .item_name  = av_default_item_name,
4223
    .option     = mov_options,
4224 4225
    .version    = LIBAVUTIL_VERSION_INT,
};
4226

4227
AVInputFormat ff_mov_demuxer = {
4228
    .name           = "mov,mp4,m4a,3gp,3g2,mj2",
4229
    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
4230
    .priv_class     = &mov_class,
4231
    .priv_data_size = sizeof(MOVContext),
4232
    .extensions     = "mov,mp4,m4a,3gp,3g2,mj2",
4233 4234 4235 4236 4237
    .read_probe     = mov_probe,
    .read_header    = mov_read_header,
    .read_packet    = mov_read_packet,
    .read_close     = mov_read_close,
    .read_seek      = mov_read_seek,
4238
    .flags          = AVFMT_NO_BYTE_SEEK,
4239
};