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

#include <limits.h>
24

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

29
#include "libavutil/intreadwrite.h"
30
#include "libavutil/avstring.h"
31
#include "avformat.h"
32
#include "riff.h"
33
#include "isom.h"
34 35
#include "libavcodec/mpeg4audio.h"
#include "libavcodec/mpegaudiodata.h"
36
#include "libavcodec/get_bits.h"
37

38
#if CONFIG_ZLIB
39 40 41
#include <zlib.h>
#endif

42 43
/*
 * First version by Francois Revol revol@free.fr
44
 * Seek function by Gael Chardon gael.dev@4now.net
45
 *
46
 * Features and limitations:
47
 * - reads most of the QT files I have (at least the structure),
48 49
 *   Sample QuickTime files with mp3 audio can be found at: http://www.3ivx.com/showcase.html
 * - the code is quite ugly... maybe I won't do it recursive next time :-)
50
 *
51 52
 * Funny I didn't know about http://sourceforge.net/projects/qt-ffmpeg/
 * when coding this :) (it's a writer anyway)
53
 *
54 55 56
 * Reference documents:
 * http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
 * Apple:
G
Gael Chardon 已提交
57
 *  http://developer.apple.com/documentation/QuickTime/QTFF/
58
 *  http://developer.apple.com/documentation/QuickTime/QTFF/qtff.pdf
59 60 61
 * QuickTime is a trademark of Apple (AFAIK :))
 */

62 63
#include "qtpalette.h"

G
Gael Chardon 已提交
64

65 66 67
#undef NDEBUG
#include <assert.h>

68 69 70 71
/* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */

/* those functions parse an atom */
/* return code:
B
Baptiste Coudurier 已提交
72
  0: continue to parse next atom
D
Diego Biurrun 已提交
73
 <0: error occurred, exit
B
Baptiste Coudurier 已提交
74
*/
75 76
/* links atom IDs to parse functions */
typedef struct MOVParseTableEntry {
77
    uint32_t type;
78
    int (*parse)(MOVContext *ctx, ByteIOContext *pb, MOVAtom atom);
79 80
} MOVParseTableEntry;

81 82
static const MOVParseTableEntry mov_default_parse_table[];

B
Baptiste Coudurier 已提交
83 84 85 86 87 88 89 90 91 92 93 94 95
static int mov_metadata_trkn(MOVContext *c, ByteIOContext *pb, unsigned len)
{
    char buf[16];

    get_be16(pb); // unknown
    snprintf(buf, sizeof(buf), "%d", get_be16(pb));
    av_metadata_set(&c->fc->metadata, "track", buf);

    get_be16(pb); // total tracks

    return 0;
}

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
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,
};

static int mov_read_mac_string(MOVContext *c, ByteIOContext *pb, int len,
                               char *dst, int dstlen)
{
    char *p = dst;
    char *end = dst+dstlen-1;
    int i;

    for (i = 0; i < len; i++) {
        uint8_t t, c = get_byte(pb);
        if (c < 0x80 && p < end)
            *p++ = c;
        else
            PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;);
    }
    *p = 0;
    return p - dst;
}

133 134 135 136 137 138 139
static int mov_read_udta_string(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
#ifdef MOV_EXPORT_ALL_METADATA
    char tmp_key[5];
#endif
    char str[1024], key2[16], language[4] = {0};
    const char *key = NULL;
140 141
    uint16_t str_size, langcode = 0;
    uint32_t data_type = 0;
B
Baptiste Coudurier 已提交
142
    int (*parse)(MOVContext*, ByteIOContext*, unsigned) = NULL;
143 144 145 146

    switch (atom.type) {
    case MKTAG(0xa9,'n','a','m'): key = "title";     break;
    case MKTAG(0xa9,'a','u','t'):
147 148
    case MKTAG(0xa9,'A','R','T'): key = "author";    break;
    case MKTAG(0xa9,'w','r','t'): key = "composer";  break;
149
    case MKTAG( 'c','p','r','t'):
150 151 152 153
    case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
    case MKTAG(0xa9,'c','m','t'):
    case MKTAG(0xa9,'i','n','f'): key = "comment";   break;
    case MKTAG(0xa9,'a','l','b'): key = "album";     break;
154
    case MKTAG(0xa9,'d','a','y'): key = "date";      break;
155 156
    case MKTAG(0xa9,'g','e','n'): key = "genre";     break;
    case MKTAG(0xa9,'t','o','o'):
157
    case MKTAG(0xa9,'e','n','c'): key = "encoder";   break;
158 159 160 161 162
    case MKTAG( 'd','e','s','c'): key = "description";break;
    case MKTAG( 'l','d','e','s'): key = "synopsis";  break;
    case MKTAG( 't','v','s','h'): key = "show";      break;
    case MKTAG( 't','v','e','n'): key = "episode_id";break;
    case MKTAG( 't','v','n','n'): key = "network";   break;
B
Baptiste Coudurier 已提交
163 164
    case MKTAG( 't','r','k','n'): key = "track";
        parse = mov_metadata_trkn; break;
165 166 167 168 169 170
    }

    if (c->itunes_metadata && atom.size > 8) {
        int data_size = get_be32(pb);
        int tag = get_le32(pb);
        if (tag == MKTAG('d','a','t','a')) {
171
            data_type = get_be32(pb); // type
172 173 174 175 176 177
            get_be32(pb); // unknown
            str_size = data_size - 16;
            atom.size -= 16;
        } else return 0;
    } else if (atom.size > 4 && key && !c->itunes_metadata) {
        str_size = get_be16(pb); // string length
178 179
        langcode = get_be16(pb);
        ff_mov_lang_to_iso639(langcode, language);
180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196
        atom.size -= 4;
    } else
        str_size = atom.size;

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

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

    str_size = FFMIN3(sizeof(str)-1, str_size, atom.size);
B
Baptiste Coudurier 已提交
197 198 199 200

    if (parse)
        parse(c, pb, str_size);
    else {
201 202 203 204 205 206
        if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded
            mov_read_mac_string(c, pb, str_size, str, sizeof(str));
        } else {
            get_buffer(pb, str, str_size);
            str[str_size] = 0;
        }
B
Baptiste Coudurier 已提交
207 208 209 210 211
        av_metadata_set(&c->fc->metadata, key, str);
        if (*language && strcmp(language, "und")) {
            snprintf(key2, sizeof(key2), "%s-%s", key, language);
            av_metadata_set(&c->fc->metadata, key2, str);
        }
B
Baptiste Coudurier 已提交
212
    }
213 214 215 216 217 218 219 220
#ifdef DEBUG_METADATA
    av_log(c->fc, AV_LOG_DEBUG, "lang \"%3s\" ", language);
    av_log(c->fc, AV_LOG_DEBUG, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %lld\n",
           key, str, (char*)&atom.type, str_size, atom.size);
#endif

    return 0;
}
221

222
static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
223
{
224
    int64_t total_size = 0;
225
    MOVAtom a;
226
    int i;
227

228
    if (atom.size < 0)
B
Baptiste Coudurier 已提交
229
        atom.size = INT64_MAX;
230
    while (total_size + 8 < atom.size && !url_feof(pb)) {
231
        int (*parse)(MOVContext*, ByteIOContext*, MOVAtom) = NULL;
232
        a.size = atom.size;
B
Baptiste Coudurier 已提交
233
        a.type=0;
234
        if(atom.size >= 8) {
235
            a.size = get_be32(pb);
236
            a.type = get_le32(pb);
237
        }
238
        total_size += 8;
239 240
        dprintf(c->fc, "type: %08x  %.4s  sz: %"PRIx64"  %"PRIx64"   %"PRIx64"\n",
                a.type, (char*)&a.type, a.size, atom.size, total_size);
241
        if (a.size == 1) { /* 64 bit extended size */
242
            a.size = get_be64(pb) - 8;
243
            total_size += 8;
244
        }
245 246 247
        if (a.size == 0) {
            a.size = atom.size - total_size;
            if (a.size <= 8)
248
                break;
249 250
        }
        a.size -= 8;
251
        if(a.size < 0)
252
            break;
B
Baptiste Coudurier 已提交
253
        a.size = FFMIN(a.size, atom.size - total_size);
254

255 256 257 258 259
        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;
            }
260

261 262 263 264 265 266
        // 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 */
267
            url_fskip(pb, a.size);
268
        } else {
269
            int64_t start_pos = url_ftell(pb);
270
            int64_t left;
271 272 273
            int err = parse(c, pb, a);
            if (err < 0)
                return err;
274 275 276
            if (c->found_moov && c->found_mdat &&
                (url_is_streamed(pb) || start_pos + a.size == url_fsize(pb)))
                return 0;
277 278 279
            left = a.size - url_ftell(pb) + start_pos;
            if (left > 0) /* skip garbage at atom end */
                url_fskip(pb, left);
280
        }
281

282
        total_size += a.size;
283 284
    }

285
    if (total_size < atom.size && atom.size < 0x7ffff)
286
        url_fskip(pb, atom.size - total_size);
287

288
    return 0;
289 290
}

291
static int mov_read_dref(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
292
{
293 294
    AVStream *st;
    MOVStreamContext *sc;
295 296
    int entries, i, j;

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

302 303 304 305 306
    get_be32(pb); // version + flags
    entries = get_be32(pb);
    if (entries >= UINT_MAX / sizeof(*sc->drefs))
        return -1;
    sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
307 308 309
    if (!sc->drefs)
        return AVERROR(ENOMEM);
    sc->drefs_count = entries;
310 311

    for (i = 0; i < sc->drefs_count; i++) {
312
        MOVDref *dref = &sc->drefs[i];
313
        uint32_t size = get_be32(pb);
314
        int64_t next = url_ftell(pb) + size - 4;
315 316 317 318 319 320 321 322 323 324 325 326 327 328

        dref->type = get_le32(pb);
        get_be32(pb); // version + flags
        dprintf(c->fc, "type %.4s size %d\n", (char*)&dref->type, size);

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

            url_fskip(pb, 10);

            volume_len = get_byte(pb);
            volume_len = FFMIN(volume_len, 27);
329 330 331
            get_buffer(pb, dref->volume, 27);
            dref->volume[volume_len] = 0;
            av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
332

333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349
            url_fskip(pb, 12);

            len = get_byte(pb);
            len = FFMIN(len, 63);
            get_buffer(pb, dref->filename, 63);
            dref->filename[len] = 0;
            av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);

            url_fskip(pb, 16);

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

            url_fskip(pb, 16);
350 351 352 353 354 355 356 357

            for (type = 0; type != -1 && url_ftell(pb) < next; ) {
                type = get_be16(pb);
                len = get_be16(pb);
                av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
                if (len&1)
                    len += 1;
                if (type == 2) { // absolute path
358
                    av_free(dref->path);
359
                    dref->path = av_mallocz(len+1);
360 361
                    if (!dref->path)
                        return AVERROR(ENOMEM);
362
                    get_buffer(pb, dref->path, len);
363
                    if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
364 365 366 367 368 369 370 371
                        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);
372 373 374 375 376 377 378 379 380 381 382
                } else if (type == 0) { // directory name
                    av_free(dref->dir);
                    dref->dir = av_malloc(len+1);
                    if (!dref->dir)
                        return AVERROR(ENOMEM);
                    get_buffer(pb, dref->dir, len);
                    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);
383 384 385 386 387 388 389 390 391
                } else
                    url_fskip(pb, len);
            }
        }
        url_fseek(pb, next, SEEK_SET);
    }
    return 0;
}

392
static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
393
{
394
    AVStream *st;
395 396
    uint32_t type;
    uint32_t ctype;
397

398 399 400 401 402
    if (c->fc->nb_streams < 1) // meta before first trak
        return 0;

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

403
    get_byte(pb); /* version */
404
    get_be24(pb); /* flags */
405 406 407 408 409

    /* component type */
    ctype = get_le32(pb);
    type = get_le32(pb); /* component subtype */

B
Baptiste Coudurier 已提交
410 411
    dprintf(c->fc, "ctype= %.4s (0x%08x)\n", (char*)&ctype, ctype);
    dprintf(c->fc, "stype= %.4s\n", (char*)&type);
412

413
    if     (type == MKTAG('v','i','d','e'))
414
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
415
    else if(type == MKTAG('s','o','u','n'))
416
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
417
    else if(type == MKTAG('m','1','a',' '))
418
        st->codec->codec_id = CODEC_ID_MP2;
419
    else if(type == MKTAG('s','u','b','p'))
420
        st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
421

422 423 424 425 426 427 428
    get_be32(pb); /* component  manufacture */
    get_be32(pb); /* component flags */
    get_be32(pb); /* component flags mask */

    return 0;
}

429
int ff_mp4_read_descr_len(ByteIOContext *pb)
430
{
431
    int len = 0;
432 433
    int count = 4;
    while (count--) {
434
        int c = get_byte(pb);
435 436 437
        len = (len << 7) | (c & 0x7f);
        if (!(c & 0x80))
            break;
438 439 440 441
    }
    return len;
}

442
static int mp4_read_descr(AVFormatContext *fc, ByteIOContext *pb, int *tag)
443 444 445
{
    int len;
    *tag = get_byte(pb);
446 447
    len = ff_mp4_read_descr_len(pb);
    dprintf(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
448 449 450
    return len;
}

451 452 453 454
#define MP4ESDescrTag                   0x03
#define MP4DecConfigDescrTag            0x04
#define MP4DecSpecificDescrTag          0x05

455
static const AVCodecTag mp4_audio_types[] = {
456 457 458 459
    { CODEC_ID_MP3ON4, AOT_PS   }, /* old mp3on4 draft */
    { CODEC_ID_MP3ON4, AOT_L1   }, /* layer 1 */
    { CODEC_ID_MP3ON4, AOT_L2   }, /* layer 2 */
    { CODEC_ID_MP3ON4, AOT_L3   }, /* layer 3 */
460
    { CODEC_ID_MP4ALS, AOT_ALS  }, /* MPEG-4 ALS */
461
    { CODEC_ID_NONE,   AOT_NULL },
462 463
};

464
int ff_mov_read_esds(AVFormatContext *fc, ByteIOContext *pb, MOVAtom atom)
465
{
466
    AVStream *st;
467
    int tag, len;
468

469
    if (fc->nb_streams < 1)
470
        return 0;
471
    st = fc->streams[fc->nb_streams-1];
472

473
    get_be32(pb); /* version + flags */
474
    len = mp4_read_descr(fc, pb, &tag);
475
    if (tag == MP4ESDescrTag) {
476 477
        get_be16(pb); /* ID */
        get_byte(pb); /* priority */
478
    } else
479
        get_be16(pb); /* ID */
480

481
    len = mp4_read_descr(fc, pb, &tag);
482
    if (tag == MP4DecConfigDescrTag) {
483 484 485 486 487 488
        int object_type_id = get_byte(pb);
        get_byte(pb); /* stream type */
        get_be24(pb); /* buffer size db */
        get_be32(pb); /* max bitrate */
        get_be32(pb); /* avg bitrate */

489
        st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
490
        dprintf(fc, "esds object type id 0x%02x\n", object_type_id);
491
        len = mp4_read_descr(fc, pb, &tag);
492
        if (tag == MP4DecSpecificDescrTag) {
493
            dprintf(fc, "Specific MPEG4 header len=%d\n", len);
B
Baptiste Coudurier 已提交
494 495
            if((uint64_t)len > (1<<30))
                return -1;
B
Baptiste Coudurier 已提交
496
            st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
497 498
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
499 500
            get_buffer(pb, st->codec->extradata, len);
            st->codec->extradata_size = len;
501 502 503 504
            if (st->codec->codec_id == CODEC_ID_AAC) {
                MPEG4AudioConfig cfg;
                ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
                                         st->codec->extradata_size);
505
                st->codec->channels = cfg.channels;
506 507 508 509
                if (cfg.object_type == 29 && cfg.sampling_index < 3) // old mp3on4
                    st->codec->sample_rate = ff_mpa_freq_tab[cfg.sampling_index];
                else
                    st->codec->sample_rate = cfg.sample_rate; // ext sample rate ?
510
                dprintf(fc, "mp4a config channels %d obj %d ext obj %d "
511 512 513
                        "sample rate %d ext sample rate %d\n", st->codec->channels,
                        cfg.object_type, cfg.ext_object_type,
                        cfg.sample_rate, cfg.ext_sample_rate);
514 515
                if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,
                                                            cfg.object_type)))
516
                    st->codec->codec_id = CODEC_ID_AAC;
B
Baptiste Coudurier 已提交
517
            }
518
        }
519 520 521 522
    }
    return 0;
}

523 524 525 526 527
static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
    return ff_mov_read_esds(c->fc, pb, atom);
}

528 529 530 531
static int mov_read_pasp(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
    const int num = get_be32(pb);
    const int den = get_be32(pb);
532 533 534 535 536 537
    AVStream *st;

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

538
    if (den != 0) {
539 540
        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))
541
            av_log(c->fc, AV_LOG_WARNING,
542 543
                   "sample aspect ratio already set to %d:%d, overriding by 'pasp' atom\n",
                   st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
544 545 546 547 548 549
        st->sample_aspect_ratio.num = num;
        st->sample_aspect_ratio.den = den;
    }
    return 0;
}

550
/* this atom contains actual media data */
551
static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
552
{
553 554 555 556 557 558
    if(atom.size == 0) /* wrong one (MP4) */
        return 0;
    c->found_mdat=1;
    return 0; /* now go for moov */
}

559
/* read major brand, minor version and compatible brands and store them as metadata */
560
static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
561
{
562 563 564 565 566 567 568
    uint32_t minor_ver;
    int comp_brand_size;
    char minor_ver_str[11]; /* 32 bit integer -> 10 digits + null */
    char* comp_brands_str;
    uint8_t type[5] = {0};

    get_buffer(pb, type, 4);
B
Baptiste Coudurier 已提交
569
    if (strcmp(type, "qt  "))
570
        c->isom = 1;
571
    av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587
    av_metadata_set(&c->fc->metadata, "major_brand", type);
    minor_ver = get_be32(pb); /* minor version */
    snprintf(minor_ver_str, sizeof(minor_ver_str), "%d", minor_ver);
    av_metadata_set(&c->fc->metadata, "minor_version", minor_ver_str);

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

588 589 590
    return 0;
}

591
/* this atom should contain all header atoms */
592
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
593
{
594 595
    if (mov_read_default(c, pb, atom) < 0)
        return -1;
596 597 598 599 600 601
    /* 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 */
}

602
static int mov_read_moof(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
603 604 605 606 607
{
    c->fragment.moof_offset = url_ftell(pb) - 8;
    dprintf(c->fc, "moof offset %llx\n", c->fragment.moof_offset);
    return mov_read_default(c, pb, atom);
}
608

609
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
610
{
611 612 613
    AVStream *st;
    MOVStreamContext *sc;
    int version;
614
    char language[4] = {0};
615
    unsigned lang;
616

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

    version = get_byte(pb);
623
    if (version > 1)
B
Baptiste Coudurier 已提交
624
        return -1; /* unsupported */
625

626
    get_be24(pb); /* flags */
B
clean  
Baptiste Coudurier 已提交
627 628 629 630 631 632 633
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
634

B
clean  
Baptiste Coudurier 已提交
635 636
    sc->time_scale = get_be32(pb);
    st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
637

638
    lang = get_be16(pb); /* language */
639 640
    if (ff_mov_lang_to_iso639(lang, language))
        av_metadata_set(&st->metadata, "language", language);
641 642 643 644 645
    get_be16(pb); /* quality */

    return 0;
}

646
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
647
{
B
Baptiste Coudurier 已提交
648
    int version = get_byte(pb); /* version */
649
    get_be24(pb); /* flags */
650

B
Baptiste Coudurier 已提交
651 652 653 654 655 656 657
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
658
    c->time_scale = get_be32(pb); /* time scale */
659 660 661

    dprintf(c->fc, "time scale = %i\n", c->time_scale);

B
Baptiste Coudurier 已提交
662
    c->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681
    get_be32(pb); /* preferred scale */

    get_be16(pb); /* preferred volume */

    url_fskip(pb, 10); /* reserved */

    url_fskip(pb, 36); /* display matrix */

    get_be32(pb); /* preview time */
    get_be32(pb); /* preview duration */
    get_be32(pb); /* poster time */
    get_be32(pb); /* selection time */
    get_be32(pb); /* selection duration */
    get_be32(pb); /* current time */
    get_be32(pb); /* next track ID */

    return 0;
}

682
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
683
{
684 685 686 687 688
    AVStream *st;

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

690 691
    if((uint64_t)atom.size > (1<<30))
        return -1;
692

693 694
    // currently SVQ3 decoder expect full STSD header - so let's fake it
    // this should be fixed and just SMI header should be passed
695
    av_free(st->codec->extradata);
696 697 698
    st->codec->extradata = av_mallocz(atom.size + 0x5a + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
699 700 701 702
    st->codec->extradata_size = 0x5a + atom.size;
    memcpy(st->codec->extradata, "SVQ3", 4); // fake
    get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
    dprintf(c->fc, "Reading SMI %"PRId64"  %s\n", atom.size, st->codec->extradata + 0x5a);
703 704
    return 0;
}
705

706
static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
707
{
708 709 710 711 712 713
    AVStream *st;
    int little_endian;

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

715
    little_endian = get_be16(pb);
716 717
    dprintf(c->fc, "enda %d\n", little_endian);
    if (little_endian == 1) {
718 719 720 721 722 723 724
        switch (st->codec->codec_id) {
        case CODEC_ID_PCM_S24BE:
            st->codec->codec_id = CODEC_ID_PCM_S24LE;
            break;
        case CODEC_ID_PCM_S32BE:
            st->codec->codec_id = CODEC_ID_PCM_S32LE;
            break;
725 726 727 728 729 730
        case CODEC_ID_PCM_F32BE:
            st->codec->codec_id = CODEC_ID_PCM_F32LE;
            break;
        case CODEC_ID_PCM_F64BE:
            st->codec->codec_id = CODEC_ID_PCM_F64LE;
            break;
731 732 733 734 735 736 737
        default:
            break;
        }
    }
    return 0;
}

738
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
739
static int mov_read_extradata(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
740
{
741 742
    AVStream *st;
    uint64_t size;
743
    uint8_t *buf;
744 745 746 747 748

    if (c->fc->nb_streams < 1) // will happen with jp2 files
        return 0;
    st= c->fc->streams[c->fc->nb_streams-1];
    size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
749
    if(size > INT_MAX || (uint64_t)atom.size > INT_MAX)
750
        return -1;
751 752 753 754 755 756 757 758 759
    buf= av_realloc(st->codec->extradata, size);
    if(!buf)
        return -1;
    st->codec->extradata= buf;
    buf+= st->codec->extradata_size;
    st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE;
    AV_WB32(       buf    , atom.size + 8);
    AV_WL32(       buf + 4, atom.type);
    get_buffer(pb, buf + 8, atom.size);
760 761 762
    return 0;
}

763
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
R
Roberto Togni 已提交
764
{
765 766 767 768 769
    AVStream *st;

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

    if((uint64_t)atom.size > (1<<30))
        return -1;
773

774 775 776
    if (st->codec->codec_id == CODEC_ID_QDM2) {
        // pass all frma atom to codec, needed at least for QDM2
        av_free(st->codec->extradata);
777 778 779
        st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
        if (!st->codec->extradata)
            return AVERROR(ENOMEM);
780
        st->codec->extradata_size = atom.size;
781
        get_buffer(pb, st->codec->extradata, atom.size);
782
    } else if (atom.size > 8) { /* to read frma, esds atoms */
783 784
        if (mov_read_default(c, pb, atom) < 0)
            return -1;
785
    } else
786
        url_fskip(pb, atom.size);
R
Roberto Togni 已提交
787 788 789
    return 0;
}

790 791 792 793
/**
 * This function reads atom content and puts data in extradata without tag
 * nor size unlike mov_read_extradata.
 */
794
static int mov_read_glbl(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
795
{
796 797 798 799 800
    AVStream *st;

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

802 803 804
    if((uint64_t)atom.size > (1<<30))
        return -1;

805
    av_free(st->codec->extradata);
806 807 808
    st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
809
    st->codec->extradata_size = atom.size;
810
    get_buffer(pb, st->codec->extradata, atom.size);
811 812 813
    return 0;
}

814
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
815
{
816 817
    AVStream *st;
    MOVStreamContext *sc;
818
    unsigned int i, entries;
819

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

825
    get_byte(pb); /* version */
826
    get_be24(pb); /* flags */
827 828

    entries = get_be32(pb);
829

830 831
    if(entries >= UINT_MAX/sizeof(int64_t))
        return -1;
832

B
Baptiste Coudurier 已提交
833
    sc->chunk_offsets = av_malloc(entries * sizeof(int64_t));
834
    if (!sc->chunk_offsets)
835 836 837
        return AVERROR(ENOMEM);
    sc->chunk_count = entries;

838 839
    if      (atom.type == MKTAG('s','t','c','o'))
        for(i=0; i<entries; i++)
840
            sc->chunk_offsets[i] = get_be32(pb);
841 842
    else if (atom.type == MKTAG('c','o','6','4'))
        for(i=0; i<entries; i++)
843
            sc->chunk_offsets[i] = get_be64(pb);
844
    else
845
        return -1;
846

847 848 849
    return 0;
}

850 851 852 853
/**
 * Compute codec id for 'lpcm' tag.
 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
 */
854
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
855 856 857 858
{
    if (flags & 1) { // floating point
        if (flags & 2) { // big endian
            if      (bps == 32) return CODEC_ID_PCM_F32BE;
859
            else if (bps == 64) return CODEC_ID_PCM_F64BE;
860
        } else {
861 862
            if      (bps == 32) return CODEC_ID_PCM_F32LE;
            else if (bps == 64) return CODEC_ID_PCM_F64LE;
863 864 865 866 867 868 869 870 871 872 873 874 875 876
        }
    } else {
        if (flags & 2) {
            if      (bps == 8)
                // signed integer
                if (flags & 4)  return CODEC_ID_PCM_S8;
                else            return CODEC_ID_PCM_U8;
            else if (bps == 16) return CODEC_ID_PCM_S16BE;
            else if (bps == 24) return CODEC_ID_PCM_S24BE;
            else if (bps == 32) return CODEC_ID_PCM_S32BE;
        } else {
            if      (bps == 8)
                if (flags & 4)  return CODEC_ID_PCM_S8;
                else            return CODEC_ID_PCM_U8;
B
Baptiste Coudurier 已提交
877
            else if (bps == 16) return CODEC_ID_PCM_S16LE;
878 879 880 881
            else if (bps == 24) return CODEC_ID_PCM_S24LE;
            else if (bps == 32) return CODEC_ID_PCM_S32LE;
        }
    }
D
Diego Pettenò 已提交
882
    return CODEC_ID_NONE;
883 884
}

885
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
886
{
887 888
    AVStream *st;
    MOVStreamContext *sc;
889
    int j, entries, pseudo_stream_id;
890

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

896
    get_byte(pb); /* version */
897
    get_be24(pb); /* flags */
898 899 900

    entries = get_be32(pb);

901 902
    for(pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
        //Parsing Sample description table
903
        enum CodecID id;
904
        int dref_id = 1;
905
        MOVAtom a = { 0 };
906
        int64_t start_pos = url_ftell(pb);
907
        int size = get_be32(pb); /* size */
908
        uint32_t format = get_le32(pb); /* data format */
909

910 911 912 913 914
        if (size >= 16) {
            get_be32(pb); /* reserved */
            get_be16(pb); /* reserved */
            dref_id = get_be16(pb);
        }
915

916
        if (st->codec->codec_tag &&
917
            st->codec->codec_tag != format &&
918
            (c->fc->video_codec_id ? ff_codec_get_id(codec_movvideo_tags, format) != c->fc->video_codec_id
919
                                   : st->codec->codec_tag != MKTAG('j','p','e','g'))
920
           ){
D
Diego Biurrun 已提交
921 922 923
            /* 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. */
B
Baptiste Coudurier 已提交
924
            av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
925 926 927
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
            continue;
        }
928
        sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
929
        sc->dref_id= dref_id;
930

931
        st->codec->codec_tag = format;
932
        id = ff_codec_get_id(codec_movaudio_tags, format);
933
        if (id<=0 && ((format&0xFFFF) == 'm'+('s'<<8) || (format&0xFFFF) == 'T'+('S'<<8)))
934
            id = ff_codec_get_id(ff_codec_wav_tags, bswap_32(format)&0xFFFF);
M
Michael Niedermayer 已提交
935

936 937 938
        if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
            st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        } else if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO && /* do not overwrite codec type */
939
                   format && format != MKTAG('m','p','4','s')) { /* skip old asf mpeg4 tag */
940
            id = ff_codec_get_id(codec_movvideo_tags, format);
941
            if (id <= 0)
942
                id = ff_codec_get_id(ff_codec_bmp_tags, format);
943
            if (id > 0)
944 945
                st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
            else if(st->codec->codec_type == AVMEDIA_TYPE_DATA){
946
                id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
947
                if(id > 0)
948
                    st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
949
            }
950 951
        }

952 953 954
        dprintf(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size,
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
                (format >> 24) & 0xff, st->codec->codec_type);
955

956
        if(st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
957
            unsigned int color_depth, len;
958 959
            int color_greyscale;

960
            st->codec->codec_id = id;
961 962 963 964
            get_be16(pb); /* version */
            get_be16(pb); /* revision level */
            get_be32(pb); /* vendor */
            get_be32(pb); /* temporal quality */
D
Diego Biurrun 已提交
965
            get_be32(pb); /* spatial quality */
966 967 968 969

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

970 971 972
            get_be32(pb); /* horiz resolution */
            get_be32(pb); /* vert resolution */
            get_be32(pb); /* data size, always 0 */
B
Baptiste Coudurier 已提交
973
            get_be16(pb); /* frames per samples */
974

975 976 977 978 979 980 981 982 983
            len = get_byte(pb); /* codec name, pascal string */
            if (len > 31)
                len = 31;
            mov_read_mac_string(c, pb, len, st->codec->codec_name, 32);
            if (len < 31)
                url_fskip(pb, 31 - len);
            /* codec_tag YV12 triggers an UV swap in rawdec.c */
            if (!memcmp(st->codec->codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25))
                st->codec->codec_tag=MKTAG('I', '4', '2', '0');
984

985
            st->codec->bits_per_coded_sample = get_be16(pb); /* depth */
986
            st->codec->color_table_id = get_be16(pb); /* colortable id */
987
            dprintf(c->fc, "depth %d, ctab id %d\n",
988
                   st->codec->bits_per_coded_sample, st->codec->color_table_id);
989
            /* figure out the palette situation */
990 991
            color_depth = st->codec->bits_per_coded_sample & 0x1F;
            color_greyscale = st->codec->bits_per_coded_sample & 0x20;
992 993

            /* if the depth is 2, 4, or 8 bpp, file is palettized */
994
            if ((color_depth == 2) || (color_depth == 4) ||
995
                (color_depth == 8)) {
996 997 998 999
                /* for palette traversal */
                unsigned int color_start, color_count, color_end;
                unsigned char r, g, b;

1000
                st->codec->palctrl = av_malloc(sizeof(*st->codec->palctrl));
1001
                if (color_greyscale) {
1002
                    int color_index, color_dec;
1003
                    /* compute the greyscale palette */
1004
                    st->codec->bits_per_coded_sample = color_depth;
1005 1006 1007 1008 1009
                    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;
1010
                        st->codec->palctrl->palette[j] =
1011 1012 1013 1014 1015
                            (r << 16) | (g << 8) | (b);
                        color_index -= color_dec;
                        if (color_index < 0)
                            color_index = 0;
                    }
1016
                } else if (st->codec->color_table_id) {
1017
                    const uint8_t *color_table;
1018 1019 1020
                    /* if flag bit 3 is set, use the default palette */
                    color_count = 1 << color_depth;
                    if (color_depth == 2)
M
Michael Niedermayer 已提交
1021
                        color_table = ff_qt_default_palette_4;
1022
                    else if (color_depth == 4)
M
Michael Niedermayer 已提交
1023
                        color_table = ff_qt_default_palette_16;
1024
                    else
M
Michael Niedermayer 已提交
1025
                        color_table = ff_qt_default_palette_256;
1026 1027

                    for (j = 0; j < color_count; j++) {
1028 1029 1030
                        r = color_table[j * 3 + 0];
                        g = color_table[j * 3 + 1];
                        b = color_table[j * 3 + 2];
1031
                        st->codec->palctrl->palette[j] =
1032 1033 1034 1035 1036 1037 1038
                            (r << 16) | (g << 8) | (b);
                    }
                } else {
                    /* load the palette from the file */
                    color_start = get_be32(pb);
                    color_count = get_be16(pb);
                    color_end = get_be16(pb);
1039 1040
                    if ((color_start <= 255) &&
                        (color_end <= 255)) {
M
Mike Melanson 已提交
1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052
                        for (j = color_start; j <= color_end; j++) {
                            /* each R, G, or B component is 16 bits;
                             * only use the top 8 bits; skip alpha bytes
                             * up front */
                            get_byte(pb);
                            get_byte(pb);
                            r = get_byte(pb);
                            get_byte(pb);
                            g = get_byte(pb);
                            get_byte(pb);
                            b = get_byte(pb);
                            get_byte(pb);
1053
                            st->codec->palctrl->palette[j] =
M
Mike Melanson 已提交
1054
                                (r << 16) | (g << 8) | (b);
1055
                        }
1056 1057
                    }
                }
1058
                st->codec->palctrl->palette_changed = 1;
1059
            }
1060
        } else if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
1061
            int bits_per_sample, flags;
1062
            uint16_t version = get_be16(pb);
1063

1064
            st->codec->codec_id = id;
1065 1066
            get_be16(pb); /* revision level */
            get_be32(pb); /* vendor */
1067

1068
            st->codec->channels = get_be16(pb);             /* channel count */
M
Michel Bardiaux 已提交
1069
            dprintf(c->fc, "audio channels %d\n", st->codec->channels);
1070
            st->codec->bits_per_coded_sample = get_be16(pb);      /* sample size */
1071

1072
            sc->audio_cid = get_be16(pb);
1073 1074 1075 1076
            get_be16(pb); /* packet size = 0 */

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

1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089
            //Read QT version 1 fields. In version 0 these do not exist.
            dprintf(c->fc, "version =%d, isom =%d\n",version,c->isom);
            if(!c->isom) {
                if(version==1) {
                    sc->samples_per_frame = get_be32(pb);
                    get_be32(pb); /* bytes per packet */
                    sc->bytes_per_frame = get_be32(pb);
                    get_be32(pb); /* bytes per sample */
                } else if(version==2) {
                    get_be32(pb); /* sizeof struct only */
                    st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */
                    st->codec->channels = get_be32(pb);
                    get_be32(pb); /* always 0x7F000000 */
1090
                    st->codec->bits_per_coded_sample = get_be32(pb); /* bits per channel if sound is uncompressed */
J
Jai Menon 已提交
1091
                    flags = get_be32(pb); /* lpcm format specific flag */
B
Baptiste Coudurier 已提交
1092 1093
                    sc->bytes_per_frame = get_be32(pb); /* bytes per audio packet if constant */
                    sc->samples_per_frame = get_be32(pb); /* lpcm frames per audio packet if constant */
1094
                    if (format == MKTAG('l','p','c','m'))
1095
                        st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, flags);
1096 1097 1098
                }
            }

1099
            switch (st->codec->codec_id) {
1100 1101
            case CODEC_ID_PCM_S8:
            case CODEC_ID_PCM_U8:
1102
                if (st->codec->bits_per_coded_sample == 16)
1103 1104
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
                break;
1105
            case CODEC_ID_PCM_S16LE:
1106
            case CODEC_ID_PCM_S16BE:
1107
                if (st->codec->bits_per_coded_sample == 8)
1108
                    st->codec->codec_id = CODEC_ID_PCM_S8;
1109
                else if (st->codec->bits_per_coded_sample == 24)
1110 1111 1112
                    st->codec->codec_id =
                        st->codec->codec_id == CODEC_ID_PCM_S16BE ?
                        CODEC_ID_PCM_S24BE : CODEC_ID_PCM_S24LE;
1113
                break;
1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
            /* set values for old format before stsd version 1 appeared */
            case CODEC_ID_MACE3:
                sc->samples_per_frame = 6;
                sc->bytes_per_frame = 2*st->codec->channels;
                break;
            case CODEC_ID_MACE6:
                sc->samples_per_frame = 6;
                sc->bytes_per_frame = 1*st->codec->channels;
                break;
            case CODEC_ID_ADPCM_IMA_QT:
                sc->samples_per_frame = 64;
                sc->bytes_per_frame = 34*st->codec->channels;
                break;
1127 1128 1129 1130
            case CODEC_ID_GSM:
                sc->samples_per_frame = 160;
                sc->bytes_per_frame = 33;
                break;
1131 1132
            default:
                break;
1133
            }
1134

1135 1136
            bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
            if (bits_per_sample) {
1137
                st->codec->bits_per_coded_sample = bits_per_sample;
1138 1139
                sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
            }
1140
        } else if(st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
1141 1142 1143
            // ttxt stsd contains display flags, justification, background
            // color, fonts, and default styles, so fake an atom to read it
            MOVAtom fake_atom = { .size = size - (url_ftell(pb) - start_pos) };
1144
            if (format != AV_RL32("mp4s")) // mp4s contains a regular esds atom
R
Reimar Döffinger 已提交
1145
                mov_read_glbl(c, pb, fake_atom);
1146
            st->codec->codec_id= id;
1147 1148
            st->codec->width = sc->width;
            st->codec->height = sc->height;
1149 1150 1151
        } else {
            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
1152
        }
1153 1154
        /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
        a.size = size - (url_ftell(pb) - start_pos);
1155 1156 1157 1158
        if (a.size > 8) {
            if (mov_read_default(c, pb, a) < 0)
                return -1;
        } else if (a.size > 0)
1159
            url_fskip(pb, a.size);
1160
    }
1161

1162
    if(st->codec->codec_type==AVMEDIA_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
1163
        st->codec->sample_rate= sc->time_scale;
1164

1165
    /* special codec parameters handling */
1166
    switch (st->codec->codec_id) {
1167
#if CONFIG_DV_DEMUXER
1168
    case CODEC_ID_DVAUDIO:
1169
        c->dv_fctx = avformat_alloc_context();
1170 1171 1172 1173 1174 1175 1176 1177
        c->dv_demux = dv_init_demux(c->dv_fctx);
        if (!c->dv_demux) {
            av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
            return -1;
        }
        sc->dv_audio_container = 1;
        st->codec->codec_id = CODEC_ID_PCM_S16LE;
        break;
1178
#endif
1179
    /* no ifdef since parameters are always those */
1180
    case CODEC_ID_QCELP:
1181 1182 1183
        // 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;
1184
        st->codec->frame_size= 160;
1185
        st->codec->channels= 1; /* really needed */
1186
        break;
1187
    case CODEC_ID_AMR_NB:
1188
    case CODEC_ID_AMR_WB:
B
Baptiste Coudurier 已提交
1189
        st->codec->frame_size= sc->samples_per_frame;
1190
        st->codec->channels= 1; /* really needed */
1191
        /* force sample rate for amr, stsd in 3gp does not store sample rate */
B
Baptiste Coudurier 已提交
1192
        if (st->codec->codec_id == CODEC_ID_AMR_NB)
1193
            st->codec->sample_rate = 8000;
B
Baptiste Coudurier 已提交
1194 1195
        else if (st->codec->codec_id == CODEC_ID_AMR_WB)
            st->codec->sample_rate = 16000;
1196
        break;
1197
    case CODEC_ID_MP2:
1198
    case CODEC_ID_MP3:
1199
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO; /* force type after stsd for m1a hdlr */
A
Aurelien Jacobs 已提交
1200
        st->need_parsing = AVSTREAM_PARSE_FULL;
1201
        break;
1202
    case CODEC_ID_GSM:
1203 1204 1205 1206
    case CODEC_ID_ADPCM_MS:
    case CODEC_ID_ADPCM_IMA_WAV:
        st->codec->block_align = sc->bytes_per_frame;
        break;
1207
    case CODEC_ID_ALAC:
1208
        if (st->codec->extradata_size == 36) {
1209 1210
            st->codec->frame_size = AV_RB32(st->codec->extradata+12);
            st->codec->channels   = AV_RB8 (st->codec->extradata+21);
1211
        }
1212
        break;
1213 1214 1215
    default:
        break;
    }
1216

1217 1218 1219
    return 0;
}

1220
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1221
{
1222 1223
    AVStream *st;
    MOVStreamContext *sc;
1224
    unsigned int i, entries;
1225

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

1231
    get_byte(pb); /* version */
1232
    get_be24(pb); /* flags */
1233 1234

    entries = get_be32(pb);
1235

1236 1237
    dprintf(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);

1238 1239
    if(entries >= UINT_MAX / sizeof(*sc->stsc_data))
        return -1;
1240 1241
    sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
    if (!sc->stsc_data)
1242 1243 1244
        return AVERROR(ENOMEM);
    sc->stsc_count = entries;

1245
    for(i=0; i<entries; i++) {
1246 1247 1248
        sc->stsc_data[i].first = get_be32(pb);
        sc->stsc_data[i].count = get_be32(pb);
        sc->stsc_data[i].id = get_be32(pb);
1249 1250 1251 1252
    }
    return 0;
}

1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267 1268 1269 1270 1271 1272 1273 1274 1275 1276 1277 1278 1279 1280 1281
static int mov_read_stps(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
    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;

    get_be32(pb); // version + flags

    entries = get_be32(pb);
    if (entries >= UINT_MAX / sizeof(*sc->stps_data))
        return -1;
    sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data));
    if (!sc->stps_data)
        return AVERROR(ENOMEM);
    sc->stps_count = entries;

    for (i = 0; i < entries; i++) {
        sc->stps_data[i] = get_be32(pb);
        //dprintf(c->fc, "stps %d\n", sc->stps_data[i]);
    }

    return 0;
}

1282
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1283
{
1284 1285
    AVStream *st;
    MOVStreamContext *sc;
1286
    unsigned int i, entries;
1287

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

1293
    get_byte(pb); /* version */
1294
    get_be24(pb); /* flags */
1295 1296

    entries = get_be32(pb);
1297

1298 1299
    dprintf(c->fc, "keyframe_count = %d\n", entries);

B
Baptiste Coudurier 已提交
1300
    if(entries >= UINT_MAX / sizeof(int))
1301
        return -1;
B
Baptiste Coudurier 已提交
1302
    sc->keyframes = av_malloc(entries * sizeof(int));
1303
    if (!sc->keyframes)
1304 1305 1306
        return AVERROR(ENOMEM);
    sc->keyframe_count = entries;

1307 1308
    for(i=0; i<entries; i++) {
        sc->keyframes[i] = get_be32(pb);
1309
        //dprintf(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
1310 1311 1312 1313
    }
    return 0;
}

1314
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1315
{
1316 1317
    AVStream *st;
    MOVStreamContext *sc;
1318 1319 1320
    unsigned int i, entries, sample_size, field_size, num_bytes;
    GetBitContext gb;
    unsigned char* buf;
1321

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

1327
    get_byte(pb); /* version */
1328
    get_be24(pb); /* flags */
1329

1330
    if (atom.type == MKTAG('s','t','s','z')) {
1331 1332 1333 1334
        sample_size = get_be32(pb);
        if (!sc->sample_size) /* do not overwrite value computed in stsd */
            sc->sample_size = sample_size;
        field_size = 32;
1335 1336 1337 1338 1339
    } else {
        sample_size = 0;
        get_be24(pb); /* reserved */
        field_size = get_byte(pb);
    }
1340
    entries = get_be32(pb);
1341 1342

    dprintf(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, entries);
1343

1344
    sc->sample_count = entries;
1345 1346 1347
    if (sample_size)
        return 0;

1348 1349 1350 1351 1352
    if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) {
        av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %d\n", field_size);
        return -1;
    }

1353
    if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size)
1354
        return -1;
B
Baptiste Coudurier 已提交
1355
    sc->sample_sizes = av_malloc(entries * sizeof(int));
1356
    if (!sc->sample_sizes)
1357 1358
        return AVERROR(ENOMEM);

1359 1360
    num_bytes = (entries*field_size+4)>>3;

1361
    buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE);
1362 1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374
    if (!buf) {
        av_freep(&sc->sample_sizes);
        return AVERROR(ENOMEM);
    }

    if (get_buffer(pb, buf, num_bytes) < num_bytes) {
        av_freep(&sc->sample_sizes);
        av_free(buf);
        return -1;
    }

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

1375
    for(i=0; i<entries; i++)
1376 1377 1378
        sc->sample_sizes[i] = get_bits_long(&gb, field_size);

    av_free(buf);
1379 1380 1381
    return 0;
}

1382
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1383
{
1384 1385
    AVStream *st;
    MOVStreamContext *sc;
1386
    unsigned int i, entries;
1387 1388
    int64_t duration=0;
    int64_t total_sample_count=0;
1389

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

1395
    get_byte(pb); /* version */
1396
    get_be24(pb); /* flags */
1397
    entries = get_be32(pb);
1398 1399 1400

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

1401
    if(entries >= UINT_MAX / sizeof(*sc->stts_data))
1402
        return -1;
1403
    sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));
1404
    if (!sc->stts_data)
1405 1406
        return AVERROR(ENOMEM);
    sc->stts_count = entries;
1407

1408
    for(i=0; i<entries; i++) {
M
cleanup  
Michael Niedermayer 已提交
1409 1410
        int sample_duration;
        int sample_count;
1411

1412
        sample_count=get_be32(pb);
1413
        sample_duration = get_be32(pb);
1414 1415 1416
        sc->stts_data[i].count= sample_count;
        sc->stts_data[i].duration= sample_duration;

M
Michel Bardiaux 已提交
1417
        dprintf(c->fc, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1418

B
Baptiste Coudurier 已提交
1419
        duration+=(int64_t)sample_duration*sample_count;
1420 1421 1422
        total_sample_count+=sample_count;
    }

1423 1424 1425
    st->nb_frames= total_sample_count;
    if(duration)
        st->duration= duration;
1426 1427 1428
    return 0;
}

1429
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
M
Michael Niedermayer 已提交
1430
{
1431 1432
    AVStream *st;
    MOVStreamContext *sc;
M
Michael Niedermayer 已提交
1433 1434
    unsigned int i, entries;

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

M
Michael Niedermayer 已提交
1440
    get_byte(pb); /* version */
1441
    get_be24(pb); /* flags */
M
Michael Niedermayer 已提交
1442
    entries = get_be32(pb);
1443 1444 1445

    dprintf(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);

1446
    if(entries >= UINT_MAX / sizeof(*sc->ctts_data))
M
Michael Niedermayer 已提交
1447
        return -1;
1448
    sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
1449
    if (!sc->ctts_data)
1450 1451
        return AVERROR(ENOMEM);
    sc->ctts_count = entries;
1452

M
Michael Niedermayer 已提交
1453
    for(i=0; i<entries; i++) {
1454 1455 1456 1457 1458
        int count    =get_be32(pb);
        int duration =get_be32(pb);

        sc->ctts_data[i].count   = count;
        sc->ctts_data[i].duration= duration;
1459 1460
        if (duration < 0)
            sc->dts_shift = FFMAX(sc->dts_shift, -duration);
M
Michael Niedermayer 已提交
1461
    }
1462

B
Baptiste Coudurier 已提交
1463
    dprintf(c->fc, "dts shift %d\n", sc->dts_shift);
1464

M
Michael Niedermayer 已提交
1465 1466 1467
    return 0;
}

1468 1469 1470
static void mov_build_index(MOVContext *mov, AVStream *st)
{
    MOVStreamContext *sc = st->priv_data;
1471
    int64_t current_offset;
1472 1473 1474 1475
    int64_t current_dts = 0;
    unsigned int stts_index = 0;
    unsigned int stsc_index = 0;
    unsigned int stss_index = 0;
1476
    unsigned int stps_index = 0;
1477
    unsigned int i, j;
1478
    uint64_t stream_size = 0;
1479

1480 1481
    /* adjust first dts according to edit list */
    if (sc->time_offset) {
1482
        int rescaled = sc->time_offset < 0 ? av_rescale(sc->time_offset, sc->time_scale, mov->time_scale) : sc->time_offset;
1483
        current_dts = -rescaled;
1484 1485 1486 1487 1488 1489
        if (sc->ctts_data && sc->ctts_data[0].duration / sc->stts_data[0].duration > 16) {
            /* 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;
        }
1490 1491
    }

1492
    /* only use old uncompressed audio chunk demuxing when stts specifies it */
1493
    if (!(st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1494
          sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
1495 1496
        unsigned int current_sample = 0;
        unsigned int stts_sample = 0;
1497
        unsigned int sample_size;
1498 1499 1500
        unsigned int distance = 0;
        int key_off = sc->keyframes && sc->keyframes[0] == 1;

1501 1502
        current_dts -= sc->dts_shift;

1503 1504 1505 1506 1507 1508 1509
        if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries))
            return;
        st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries));
        if (!st->index_entries)
            return;
        st->index_entries_allocated_size = sc->sample_count*sizeof(*st->index_entries);

1510 1511
        for (i = 0; i < sc->chunk_count; i++) {
            current_offset = sc->chunk_offsets[i];
1512 1513
            if (stsc_index + 1 < sc->stsc_count &&
                i + 1 == sc->stsc_data[stsc_index + 1].first)
1514
                stsc_index++;
1515
            for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
1516
                int keyframe = 0;
1517 1518
                if (current_sample >= sc->sample_count) {
                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
1519
                    return;
1520
                }
1521 1522 1523

                if (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index]) {
                    keyframe = 1;
1524 1525
                    if (stss_index + 1 < sc->keyframe_count)
                        stss_index++;
1526 1527 1528 1529
                } 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++;
1530
                }
1531 1532
                if (keyframe)
                    distance = 0;
1533
                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
1534
                if(sc->pseudo_stream_id == -1 ||
1535
                   sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
1536 1537 1538 1539 1540 1541
                    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;
1542 1543 1544 1545
                    dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
                            "size %d, distance %d, keyframe %d\n", st->index, current_sample,
                            current_offset, current_dts, sample_size, distance, keyframe);
                }
1546

1547
                current_offset += sample_size;
1548
                stream_size += sample_size;
1549
                current_dts += sc->stts_data[stts_index].duration;
1550 1551 1552 1553 1554 1555 1556 1557 1558
                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++;
                }
            }
        }
1559 1560
        if (st->duration > 0)
            st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;
1561
    } else {
1562
        unsigned chunk_samples, total = 0;
1563

1564 1565 1566
        // compute total chunk count
        for (i = 0; i < sc->stsc_count; i++) {
            unsigned count, chunk_count;
1567

1568
            chunk_samples = sc->stsc_data[i].count;
1569 1570 1571 1572 1573
            if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
                av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
                return;
            }

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 1599 1600 1601 1602 1603 1604 1605
            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;
        }

        dprintf(mov->fc, "chunk count %d\n", total);
        if (total >= UINT_MAX / sizeof(*st->index_entries))
            return;
        st->index_entries = av_malloc(total*sizeof(*st->index_entries));
        if (!st->index_entries)
            return;
        st->index_entries_allocated_size = total*sizeof(*st->index_entries);

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

1606
            while (chunk_samples > 0) {
1607
                AVIndexEntry *e;
1608 1609 1610 1611 1612 1613 1614 1615 1616 1617
                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;
1618
                    } else {
1619 1620
                        samples = FFMIN(1024, chunk_samples);
                        size = samples * sc->sample_size;
1621 1622
                    }
                }
1623

1624 1625 1626 1627 1628 1629 1630 1631 1632 1633
                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;
1634 1635
                dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "
                        "size %d, duration %d\n", st->index, i, current_offset, current_dts,
1636 1637 1638
                        size, samples);

                current_offset += size;
1639
                current_dts += samples;
1640
                chunk_samples -= samples;
1641 1642 1643 1644
            }
        }
    }
}
1645

1646 1647
static int mov_open_dref(ByteIOContext **pb, char *src, MOVDref *ref)
{
1648 1649
    /* try relative path, we do not try the absolute because it can leak information about our
       system to an attacker */
1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671
    if (ref->nlvl_to > 0 && ref->nlvl_from > 0) {
        char filename[1024];
        char *src_path;
        int i, l;

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

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

        /* compose filename if next level down to target was found */
1672
        if (i == ref->nlvl_to - 1 && src_path - src  < sizeof(filename)) {
1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688
            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);

            if (!url_fopen(pb, filename, URL_RDONLY))
                return 0;
        }
    }

    return AVERROR(ENOENT);
};

1689
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1690 1691 1692
{
    AVStream *st;
    MOVStreamContext *sc;
1693
    int ret;
1694 1695

    st = av_new_stream(c->fc, c->fc->nb_streams);
B
Baptiste Coudurier 已提交
1696
    if (!st) return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
1697
    sc = av_mallocz(sizeof(MOVStreamContext));
1698
    if (!sc) return AVERROR(ENOMEM);
1699 1700

    st->priv_data = sc;
1701
    st->codec->codec_type = AVMEDIA_TYPE_DATA;
1702
    sc->ffindex = st->index;
1703

1704 1705 1706 1707
    if ((ret = mov_read_default(c, pb, atom)) < 0)
        return ret;

    /* sanity checks */
1708 1709
    if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
                            (!sc->sample_size && !sc->sample_count))) {
1710 1711
        av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
               st->index);
1712 1713
        return 0;
    }
1714

1715 1716
    if (!sc->time_scale) {
        av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", st->index);
1717
        sc->time_scale = c->time_scale;
1718 1719 1720
        if (!sc->time_scale)
            sc->time_scale = 1;
    }
1721

1722
    av_set_pts_info(st, 64, 1, sc->time_scale);
1723

1724
    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
1725 1726 1727 1728 1729
        !st->codec->frame_size && sc->stts_count == 1) {
        st->codec->frame_size = av_rescale(sc->stts_data[0].duration,
                                           st->codec->sample_rate, sc->time_scale);
        dprintf(c->fc, "frame size %d\n", st->codec->frame_size);
    }
1730 1731 1732 1733

    mov_build_index(c, st);

    if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
1734 1735 1736 1737 1738 1739 1740
        MOVDref *dref = &sc->drefs[sc->dref_id - 1];
        if (mov_open_dref(&sc->pb, c->fc->filename, dref) < 0)
            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);
1741 1742 1743
    } else
        sc->pb = c->fc->pb;

1744
    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
1745
        if (st->codec->width != sc->width || st->codec->height != sc->height) {
B
Baptiste Coudurier 已提交
1746 1747 1748 1749 1750 1751
            AVRational r = av_d2q(((double)st->codec->height * sc->width) /
                                  ((double)st->codec->width * sc->height), INT_MAX);
            if (st->sample_aspect_ratio.num)
                st->sample_aspect_ratio = av_mul_q(st->sample_aspect_ratio, r);
            else
                st->sample_aspect_ratio = r;
1752 1753 1754 1755
        }

        av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
                  sc->time_scale*st->nb_frames, st->duration, INT_MAX);
1756 1757
    }

1758
    switch (st->codec->codec_id) {
1759
#if CONFIG_H261_DECODER
1760 1761
    case CODEC_ID_H261:
#endif
1762
#if CONFIG_H263_DECODER
1763 1764
    case CODEC_ID_H263:
#endif
1765 1766 1767
#if CONFIG_H264_DECODER
    case CODEC_ID_H264:
#endif
1768
#if CONFIG_MPEG4_DECODER
1769 1770
    case CODEC_ID_MPEG4:
#endif
1771
        st->codec->width = 0; /* let decoder init width/height */
1772 1773 1774
        st->codec->height= 0;
        break;
    }
B
Baptiste Coudurier 已提交
1775 1776 1777

    /* Do not need those anymore. */
    av_freep(&sc->chunk_offsets);
1778
    av_freep(&sc->stsc_data);
B
Baptiste Coudurier 已提交
1779 1780 1781
    av_freep(&sc->sample_sizes);
    av_freep(&sc->keyframes);
    av_freep(&sc->stts_data);
1782
    av_freep(&sc->stps_data);
B
Baptiste Coudurier 已提交
1783

1784
    return 0;
1785 1786
}

1787
static int mov_read_ilst(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1788 1789 1790 1791 1792 1793 1794 1795
{
    int ret;
    c->itunes_metadata = 1;
    ret = mov_read_default(c, pb, atom);
    c->itunes_metadata = 0;
    return ret;
}

1796
static int mov_read_meta(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1797
{
1798 1799 1800 1801 1802 1803 1804 1805 1806 1807
    while (atom.size > 8) {
        uint32_t tag = get_le32(pb);
        atom.size -= 4;
        if (tag == MKTAG('h','d','l','r')) {
            url_fseek(pb, -8, SEEK_CUR);
            atom.size += 8;
            return mov_read_default(c, pb, atom);
        }
    }
    return 0;
1808 1809
}

1810
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1811
{
1812 1813 1814 1815 1816
    int i;
    int width;
    int height;
    int64_t disp_transform[2];
    int display_matrix[3][2];
1817 1818 1819 1820 1821 1822 1823 1824
    AVStream *st;
    MOVStreamContext *sc;
    int version;

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

1826
    version = get_byte(pb);
1827
    get_be24(pb); /* flags */
1828 1829 1830 1831 1832 1833 1834
    /*
    MOV_TRACK_ENABLED 0x0001
    MOV_TRACK_IN_MOVIE 0x0002
    MOV_TRACK_IN_PREVIEW 0x0004
    MOV_TRACK_IN_POSTER 0x0008
    */

B
Baptiste Coudurier 已提交
1835 1836 1837 1838 1839 1840 1841
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
1842 1843
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
    get_be32(pb); /* reserved */
1844

1845 1846
    /* highlevel (considering edits) duration in movie timebase */
    (version == 1) ? get_be64(pb) : get_be32(pb);
1847 1848 1849 1850 1851 1852 1853 1854
    get_be32(pb); /* reserved */
    get_be32(pb); /* reserved */

    get_be16(pb); /* layer */
    get_be16(pb); /* alternate group */
    get_be16(pb); /* volume */
    get_be16(pb); /* reserved */

1855 1856 1857 1858 1859 1860 1861 1862
    //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
    // they're kept in fixed point format through all calculations
    // ignore u,v,z b/c we don't need the scale factor to calc aspect ratio
    for (i = 0; i < 3; i++) {
        display_matrix[i][0] = get_be32(pb);   // 16.16 fixed point
        display_matrix[i][1] = get_be32(pb);   // 16.16 fixed point
        get_be32(pb);           // 2.30 fixed point (not used)
    }
1863

1864 1865
    width = get_be32(pb);       // 16.16 fixed point track width
    height = get_be32(pb);      // 16.16 fixed point track height
1866 1867
    sc->width = width >> 16;
    sc->height = height >> 16;
1868

1869
    // transform the display width/height according to the matrix
1870
    // skip this if the display matrix is the default identity matrix
1871
    // or if it is rotating the picture, ex iPhone 3GS
1872 1873
    // to keep the same scale, use [width height 1<<16]
    if (width && height &&
1874 1875 1876 1877 1878
        ((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])) {
1879 1880 1881 1882 1883 1884 1885
        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
1886
        st->sample_aspect_ratio = av_d2q(
1887 1888 1889
            ((double) disp_transform[0] * height) /
            ((double) disp_transform[1] * width), INT_MAX);
    }
1890 1891 1892
    return 0;
}

1893
static int mov_read_tfhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1894 1895 1896 1897 1898 1899 1900 1901 1902
{
    MOVFragment *frag = &c->fragment;
    MOVTrackExt *trex = NULL;
    int flags, track_id, i;

    get_byte(pb); /* version */
    flags = get_be24(pb);

    track_id = get_be32(pb);
1903
    if (!track_id)
B
Baptiste Coudurier 已提交
1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927
        return -1;
    frag->track_id = track_id;
    for (i = 0; i < c->trex_count; i++)
        if (c->trex_data[i].track_id == frag->track_id) {
            trex = &c->trex_data[i];
            break;
        }
    if (!trex) {
        av_log(c->fc, AV_LOG_ERROR, "could not find corresponding trex\n");
        return -1;
    }

    if (flags & 0x01) frag->base_data_offset = get_be64(pb);
    else              frag->base_data_offset = frag->moof_offset;
    if (flags & 0x02) frag->stsd_id          = get_be32(pb);
    else              frag->stsd_id          = trex->stsd_id;

    frag->duration = flags & 0x08 ? get_be32(pb) : trex->duration;
    frag->size     = flags & 0x10 ? get_be32(pb) : trex->size;
    frag->flags    = flags & 0x20 ? get_be32(pb) : trex->flags;
    dprintf(c->fc, "frag flags 0x%x\n", frag->flags);
    return 0;
}

1928
static int mov_read_trex(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1929 1930 1931 1932 1933
{
    MOVTrackExt *trex;

    if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
        return -1;
1934 1935
    trex = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data));
    if (!trex)
B
Baptiste Coudurier 已提交
1936
        return AVERROR(ENOMEM);
1937
    c->trex_data = trex;
B
Baptiste Coudurier 已提交
1938 1939 1940 1941 1942 1943 1944 1945 1946 1947 1948
    trex = &c->trex_data[c->trex_count++];
    get_byte(pb); /* version */
    get_be24(pb); /* flags */
    trex->track_id = get_be32(pb);
    trex->stsd_id  = get_be32(pb);
    trex->duration = get_be32(pb);
    trex->size     = get_be32(pb);
    trex->flags    = get_be32(pb);
    return 0;
}

1949
static int mov_read_trun(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1950 1951
{
    MOVFragment *frag = &c->fragment;
1952
    AVStream *st = NULL;
1953
    MOVStreamContext *sc;
B
Baptiste Coudurier 已提交
1954 1955 1956 1957 1958 1959
    uint64_t offset;
    int64_t dts;
    int data_offset = 0;
    unsigned entries, first_sample_flags = frag->flags;
    int flags, distance, i;

1960 1961 1962 1963 1964 1965 1966 1967
    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);
1968
        return -1;
1969
    }
1970
    sc = st->priv_data;
B
Baptiste Coudurier 已提交
1971 1972 1973 1974 1975 1976 1977 1978 1979
    if (sc->pseudo_stream_id+1 != frag->stsd_id)
        return 0;
    get_byte(pb); /* version */
    flags = get_be24(pb);
    entries = get_be32(pb);
    dprintf(c->fc, "flags 0x%x entries %d\n", flags, entries);
    if (flags & 0x001) data_offset        = get_be32(pb);
    if (flags & 0x004) first_sample_flags = get_be32(pb);
    if (flags & 0x800) {
1980
        MOVStts *ctts_data;
B
Baptiste Coudurier 已提交
1981 1982
        if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
            return -1;
1983 1984 1985
        ctts_data = av_realloc(sc->ctts_data,
                               (entries+sc->ctts_count)*sizeof(*sc->ctts_data));
        if (!ctts_data)
B
Baptiste Coudurier 已提交
1986
            return AVERROR(ENOMEM);
1987
        sc->ctts_data = ctts_data;
B
Baptiste Coudurier 已提交
1988 1989 1990 1991 1992 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005 2006
    }
    dts = st->duration;
    offset = frag->base_data_offset + data_offset;
    distance = 0;
    dprintf(c->fc, "first sample flags 0x%x\n", first_sample_flags);
    for (i = 0; i < entries; i++) {
        unsigned sample_size = frag->size;
        int sample_flags = i ? frag->flags : first_sample_flags;
        unsigned sample_duration = frag->duration;
        int keyframe;

        if (flags & 0x100) sample_duration = get_be32(pb);
        if (flags & 0x200) sample_size     = get_be32(pb);
        if (flags & 0x400) sample_flags    = get_be32(pb);
        if (flags & 0x800) {
            sc->ctts_data[sc->ctts_count].count = 1;
            sc->ctts_data[sc->ctts_count].duration = get_be32(pb);
            sc->ctts_count++;
        }
2007
        if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO ||
B
Baptiste Coudurier 已提交
2008 2009 2010 2011 2012 2013 2014 2015
             (flags & 0x004 && !i && !sample_flags) || sample_flags & 0x2000000))
            distance = 0;
        av_add_index_entry(st, offset, dts, sample_size, distance,
                           keyframe ? AVINDEX_KEYFRAME : 0);
        dprintf(c->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
                "size %d, distance %d, keyframe %d\n", st->index, sc->sample_count+i,
                offset, dts, sample_size, distance, keyframe);
        distance++;
2016
        dts += sample_duration;
B
Baptiste Coudurier 已提交
2017 2018 2019 2020 2021 2022 2023
        offset += sample_size;
    }
    frag->moof_offset = offset;
    st->duration = dts;
    return 0;
}

2024 2025 2026
/* 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/ */
2027
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
2028 2029 2030 2031 2032 2033 2034 2035 2036 2037 2038
{
    int err;

    if (atom.size < 8)
        return 0; /* continue */
    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
        url_fskip(pb, atom.size - 4);
        return 0;
    }
    atom.type = get_le32(pb);
    atom.size -= 8;
2039
    if (atom.type != MKTAG('m','d','a','t')) {
2040 2041 2042 2043 2044 2045 2046
        url_fskip(pb, atom.size);
        return 0;
    }
    err = mov_read_mdat(c, pb, atom);
    return err;
}

2047
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
2048
{
2049
#if CONFIG_ZLIB
2050
    ByteIOContext ctx;
2051 2052
    uint8_t *cmov_data;
    uint8_t *moov_data; /* uncompressed data */
2053
    long cmov_len, moov_len;
2054
    int ret = -1;
2055

2056
    get_be32(pb); /* dcom atom */
2057
    if (get_le32(pb) != MKTAG('d','c','o','m'))
2058
        return -1;
2059
    if (get_le32(pb) != MKTAG('z','l','i','b')) {
B
Benoit Fouet 已提交
2060
        av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !");
2061 2062 2063
        return -1;
    }
    get_be32(pb); /* cmvd atom */
2064
    if (get_le32(pb) != MKTAG('c','m','v','d'))
2065 2066
        return -1;
    moov_len = get_be32(pb); /* uncompressed size */
2067
    cmov_len = atom.size - 6 * 4;
2068

B
Baptiste Coudurier 已提交
2069
    cmov_data = av_malloc(cmov_len);
2070
    if (!cmov_data)
2071
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
2072
    moov_data = av_malloc(moov_len);
2073 2074
    if (!moov_data) {
        av_free(cmov_data);
2075
        return AVERROR(ENOMEM);
2076 2077
    }
    get_buffer(pb, cmov_data, cmov_len);
2078
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
2079
        goto free_and_return;
2080
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
2081
        goto free_and_return;
2082
    atom.type = MKTAG('m','o','o','v');
2083
    atom.size = moov_len;
2084
#ifdef DEBUG
M
Michael Niedermayer 已提交
2085
//    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
2086
#endif
2087
    ret = mov_read_default(c, &ctx, atom);
2088
free_and_return:
2089 2090 2091
    av_free(moov_data);
    av_free(cmov_data);
    return ret;
2092 2093 2094
#else
    av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
    return -1;
2095
#endif
2096
}
2097

G
Gael Chardon 已提交
2098
/* edit list atom */
2099
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
G
Gael Chardon 已提交
2100
{
2101
    MOVStreamContext *sc;
B
Baptiste Coudurier 已提交
2102 2103
    int i, edit_count;

2104 2105 2106 2107
    if (c->fc->nb_streams < 1)
        return 0;
    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;

B
Baptiste Coudurier 已提交
2108
    get_byte(pb); /* version */
2109
    get_be24(pb); /* flags */
B
Baptiste Coudurier 已提交
2110
    edit_count = get_be32(pb); /* entries */
B
Baptiste Coudurier 已提交
2111

2112 2113 2114
    if((uint64_t)edit_count*12+8 > atom.size)
        return -1;

B
Baptiste Coudurier 已提交
2115
    for(i=0; i<edit_count; i++){
2116
        int time;
2117
        int duration = get_be32(pb); /* Track duration */
2118
        time = get_be32(pb); /* Media time */
B
Baptiste Coudurier 已提交
2119
        get_be32(pb); /* Media rate */
2120 2121
        if (i == 0 && time >= -1) {
            sc->time_offset = time != -1 ? time : -duration;
2122
        }
B
Baptiste Coudurier 已提交
2123
    }
2124 2125 2126 2127 2128

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

2129
    dprintf(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count);
B
Baptiste Coudurier 已提交
2130
    return 0;
G
Gael Chardon 已提交
2131 2132
}

2133
static const MOVParseTableEntry mov_default_parse_table[] = {
2134
{ MKTAG('a','v','s','s'), mov_read_extradata },
2135 2136 2137 2138 2139 2140 2141 2142 2143 2144 2145
{ MKTAG('c','o','6','4'), mov_read_stco },
{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
{ MKTAG('d','i','n','f'), mov_read_default },
{ MKTAG('d','r','e','f'), mov_read_dref },
{ MKTAG('e','d','t','s'), mov_read_default },
{ MKTAG('e','l','s','t'), mov_read_elst },
{ MKTAG('e','n','d','a'), mov_read_enda },
{ MKTAG('f','i','e','l'), mov_read_extradata },
{ MKTAG('f','t','y','p'), mov_read_ftyp },
{ MKTAG('g','l','b','l'), mov_read_glbl },
{ MKTAG('h','d','l','r'), mov_read_hdlr },
2146
{ MKTAG('i','l','s','t'), mov_read_ilst },
2147 2148 2149 2150
{ MKTAG('j','p','2','h'), mov_read_extradata },
{ MKTAG('m','d','a','t'), mov_read_mdat },
{ MKTAG('m','d','h','d'), mov_read_mdhd },
{ MKTAG('m','d','i','a'), mov_read_default },
2151
{ MKTAG('m','e','t','a'), mov_read_meta },
2152 2153 2154 2155 2156 2157 2158 2159
{ MKTAG('m','i','n','f'), mov_read_default },
{ MKTAG('m','o','o','f'), mov_read_moof },
{ MKTAG('m','o','o','v'), mov_read_moov },
{ MKTAG('m','v','e','x'), mov_read_default },
{ MKTAG('m','v','h','d'), mov_read_mvhd },
{ MKTAG('S','M','I',' '), mov_read_smi }, /* Sorenson extension ??? */
{ MKTAG('a','l','a','c'), mov_read_extradata }, /* alac specific atom */
{ MKTAG('a','v','c','C'), mov_read_glbl },
2160
{ MKTAG('p','a','s','p'), mov_read_pasp },
2161 2162
{ MKTAG('s','t','b','l'), mov_read_default },
{ MKTAG('s','t','c','o'), mov_read_stco },
2163
{ MKTAG('s','t','p','s'), mov_read_stps },
2164 2165 2166 2167 2168
{ 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 },
2169
{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
2170 2171 2172 2173 2174 2175
{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
{ MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */
{ MKTAG('t','r','a','k'), mov_read_trak },
{ MKTAG('t','r','a','f'), mov_read_default },
{ MKTAG('t','r','e','x'), mov_read_trex },
{ MKTAG('t','r','u','n'), mov_read_trun },
B
Baptiste Coudurier 已提交
2176
{ MKTAG('u','d','t','a'), mov_read_default },
2177 2178 2179 2180
{ MKTAG('w','a','v','e'), mov_read_wave },
{ MKTAG('e','s','d','s'), mov_read_esds },
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
{ MKTAG('c','m','o','v'), mov_read_cmov },
B
Baptiste Coudurier 已提交
2181
{ 0, NULL }
2182 2183
};

F
Fabrice Bellard 已提交
2184 2185
static int mov_probe(AVProbeData *p)
{
2186 2187
    unsigned int offset;
    uint32_t tag;
2188
    int score = 0;
2189

F
Fabrice Bellard 已提交
2190
    /* check file header */
2191 2192 2193 2194
    offset = 0;
    for(;;) {
        /* ignore invalid offset */
        if ((offset + 8) > (unsigned int)p->buf_size)
2195
            return score;
2196
        tag = AV_RL32(p->buf + offset + 4);
2197
        switch(tag) {
2198
        /* check for obvious tags */
2199 2200 2201 2202 2203
        case MKTAG('j','P',' ',' '): /* jpeg 2000 signature */
        case MKTAG('m','o','o','v'):
        case MKTAG('m','d','a','t'):
        case MKTAG('p','n','o','t'): /* detect movs with preview pics like ew.mov and april.mov */
        case MKTAG('u','d','t','a'): /* Packet Video PVAuthor adds this and a lot of more junk */
2204
        case MKTAG('f','t','y','p'):
2205
            return AVPROBE_SCORE_MAX;
2206
        /* those are more common words, so rate then a bit less */
2207 2208 2209 2210 2211
        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'):
2212
            return AVPROBE_SCORE_MAX - 5;
B
Baptiste Coudurier 已提交
2213
        case MKTAG(0x82,0x82,0x7f,0x7d):
2214 2215 2216
        case MKTAG('s','k','i','p'):
        case MKTAG('u','u','i','d'):
        case MKTAG('p','r','f','l'):
2217
            offset = AV_RB32(p->buf+offset) + offset;
2218 2219
            /* if we only find those cause probedata is too small at least rate them */
            score = AVPROBE_SCORE_MAX - 50;
2220 2221 2222
            break;
        default:
            /* unrecognized tag */
2223
            return score;
2224
        }
2225
    }
2226
    return score;
F
Fabrice Bellard 已提交
2227 2228
}

Z
Zdenek Kabelac 已提交
2229
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
2230
{
2231
    MOVContext *mov = s->priv_data;
2232
    ByteIOContext *pb = s->pb;
B
Baptiste Coudurier 已提交
2233
    int err;
2234
    MOVAtom atom = { 0 };
2235 2236

    mov->fc = s;
2237 2238
    /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
    if(!url_is_streamed(pb))
2239
        atom.size = url_fsize(pb);
2240
    else
B
Baptiste Coudurier 已提交
2241
        atom.size = INT64_MAX;
2242 2243

    /* check MOV header */
B
Baptiste Coudurier 已提交
2244 2245 2246 2247 2248 2249
    if ((err = mov_read_default(mov, pb, atom)) < 0) {
        av_log(s, AV_LOG_ERROR, "error reading header: %d\n", err);
        return err;
    }
    if (!mov->found_moov) {
        av_log(s, AV_LOG_ERROR, "moov atom not found\n");
2250
        return -1;
2251
    }
B
Baptiste Coudurier 已提交
2252
    dprintf(mov->fc, "on_parse_exit_offset=%lld\n", url_ftell(pb));
2253

2254 2255 2256
    return 0;
}

2257
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
2258
{
2259
    AVIndexEntry *sample = NULL;
2260
    int64_t best_dts = INT64_MAX;
2261
    int i;
B
Baptiste Coudurier 已提交
2262
    for (i = 0; i < s->nb_streams; i++) {
2263 2264
        AVStream *avst = s->streams[i];
        MOVStreamContext *msc = avst->priv_data;
2265
        if (msc->pb && msc->current_sample < avst->nb_index_entries) {
2266
            AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
2267
            int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
B
Baptiste Coudurier 已提交
2268
            dprintf(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
B
Baptiste Coudurier 已提交
2269 2270
            if (!sample || (url_is_streamed(s->pb) && current_sample->pos < sample->pos) ||
                (!url_is_streamed(s->pb) &&
2271
                 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
B
Baptiste Coudurier 已提交
2272
                 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
2273
                  (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
2274 2275
                sample = current_sample;
                best_dts = dts;
2276
                *st = avst;
2277
            }
2278 2279
        }
    }
2280 2281 2282 2283 2284 2285 2286 2287 2288 2289 2290 2291
    return sample;
}

static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
{
    MOVContext *mov = s->priv_data;
    MOVStreamContext *sc;
    AVIndexEntry *sample;
    AVStream *st = NULL;
    int ret;
 retry:
    sample = mov_find_next_sample(s, &st);
2292 2293 2294
    if (!sample) {
        mov->found_mdat = 0;
        if (!url_is_streamed(s->pb) ||
2295
            mov_read_default(mov, s->pb, (MOVAtom){ 0, INT64_MAX }) < 0 ||
2296
            url_feof(s->pb))
B
Baptiste Coudurier 已提交
2297
            return AVERROR_EOF;
2298 2299 2300
        dprintf(s, "read fragments, offset 0x%llx\n", url_ftell(s->pb));
        goto retry;
    }
2301
    sc = st->priv_data;
2302 2303
    /* must be done just before reading, to avoid infinite loop on sample */
    sc->current_sample++;
2304 2305

    if (st->discard != AVDISCARD_ALL) {
R
Reimar Döffinger 已提交
2306 2307 2308 2309 2310 2311
        if (url_fseek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
            av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
                   sc->ffindex, sample->pos);
            return -1;
        }
        ret = av_get_packet(sc->pb, pkt, sample->size);
2312 2313
        if (ret < 0)
            return ret;
R
Reimar Döffinger 已提交
2314 2315 2316 2317 2318 2319 2320 2321 2322
#if CONFIG_DV_DEMUXER
        if (mov->dv_demux && sc->dv_audio_container) {
            dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);
            av_free(pkt->data);
            pkt->size = 0;
            ret = dv_get_packet(mov->dv_demux, pkt);
            if (ret < 0)
                return ret;
        }
2323
#endif
2324 2325
    }

2326 2327 2328
    pkt->stream_index = sc->ffindex;
    pkt->dts = sample->timestamp;
    if (sc->ctts_data) {
2329
        pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
2330
        /* update ctts context */
2331 2332 2333 2334 2335
        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;
2336
        }
2337 2338
        if (sc->wrong_dts)
            pkt->dts = AV_NOPTS_VALUE;
2339
    } else {
2340
        int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
2341 2342
            st->index_entries[sc->current_sample].timestamp : st->duration;
        pkt->duration = next_dts - pkt->dts;
2343
        pkt->pts = pkt->dts;
2344
    }
2345 2346
    if (st->discard == AVDISCARD_ALL)
        goto retry;
2347 2348
    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? PKT_FLAG_KEY : 0;
    pkt->pos = sample->pos;
2349 2350
    dprintf(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64", duration %d\n",
            pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration);
2351 2352
    return 0;
}
2353

2354
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
2355 2356 2357 2358
{
    MOVStreamContext *sc = st->priv_data;
    int sample, time_sample;
    int i;
2359

2360
    sample = av_index_search_timestamp(st, timestamp, flags);
2361
    dprintf(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
2362 2363 2364
    if (sample < 0) /* not sure what to do */
        return -1;
    sc->current_sample = sample;
2365
    dprintf(s, "stream %d, found sample %d\n", st->index, sc->current_sample);
2366 2367 2368 2369
    /* adjust ctts index */
    if (sc->ctts_data) {
        time_sample = 0;
        for (i = 0; i < sc->ctts_count; i++) {
2370 2371
            int next = time_sample + sc->ctts_data[i].count;
            if (next > sc->current_sample) {
2372 2373
                sc->ctts_index = i;
                sc->ctts_sample = sc->current_sample - time_sample;
2374
                break;
2375
            }
2376
            time_sample = next;
2377 2378
        }
    }
2379
    return sample;
2380 2381
}

2382
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
G
Gael Chardon 已提交
2383
{
2384 2385 2386 2387
    AVStream *st;
    int64_t seek_timestamp, timestamp;
    int sample;
    int i;
G
Gael Chardon 已提交
2388

2389
    if (stream_index >= s->nb_streams)
G
Gael Chardon 已提交
2390
        return -1;
2391 2392
    if (sample_time < 0)
        sample_time = 0;
G
Gael Chardon 已提交
2393

2394
    st = s->streams[stream_index];
2395
    sample = mov_seek_stream(s, st, sample_time, flags);
2396
    if (sample < 0)
G
Gael Chardon 已提交
2397 2398
        return -1;

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

2402 2403
    for (i = 0; i < s->nb_streams; i++) {
        st = s->streams[i];
2404
        if (stream_index == i)
2405
            continue;
G
Gael Chardon 已提交
2406

2407
        timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
2408
        mov_seek_stream(s, st, timestamp, flags);
2409
    }
G
Gael Chardon 已提交
2410 2411 2412
    return 0;
}

Z
Zdenek Kabelac 已提交
2413
static int mov_read_close(AVFormatContext *s)
2414
{
2415
    MOVContext *mov = s->priv_data;
2416 2417 2418
    int i, j;

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

2422
        av_freep(&sc->ctts_data);
2423
        for (j = 0; j < sc->drefs_count; j++) {
2424
            av_freep(&sc->drefs[j].path);
2425 2426
            av_freep(&sc->drefs[j].dir);
        }
2427 2428 2429
        av_freep(&sc->drefs);
        if (sc->pb && sc->pb != s->pb)
            url_fclose(sc->pb);
2430 2431

        av_freep(&st->codec->palctrl);
2432
    }
2433 2434 2435

    if (mov->dv_demux) {
        for(i = 0; i < mov->dv_fctx->nb_streams; i++) {
2436 2437 2438 2439 2440 2441
            av_freep(&mov->dv_fctx->streams[i]->codec);
            av_freep(&mov->dv_fctx->streams[i]);
        }
        av_freep(&mov->dv_fctx);
        av_freep(&mov->dv_demux);
    }
2442

B
Baptiste Coudurier 已提交
2443
    av_freep(&mov->trex_data);
2444

2445 2446 2447
    return 0;
}

2448
AVInputFormat mov_demuxer = {
2449
    "mov,mp4,m4a,3gp,3g2,mj2",
2450
    NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
F
Fabrice Bellard 已提交
2451 2452
    sizeof(MOVContext),
    mov_probe,
2453 2454 2455
    mov_read_header,
    mov_read_packet,
    mov_read_close,
G
Gael Chardon 已提交
2456
    mov_read_seek,
2457
};