mov.c 78.5 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
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;
    uint16_t str_size;
B
Baptiste Coudurier 已提交
104
    int (*parse)(MOVContext*, ByteIOContext*, unsigned) = NULL;
105 106 107 108

    switch (atom.type) {
    case MKTAG(0xa9,'n','a','m'): key = "title";     break;
    case MKTAG(0xa9,'a','u','t'):
109 110
    case MKTAG(0xa9,'A','R','T'): key = "author";    break;
    case MKTAG(0xa9,'w','r','t'): key = "composer";  break;
111
    case MKTAG( 'c','p','r','t'):
112 113 114 115 116 117 118
    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;
    case MKTAG(0xa9,'d','a','y'): key = "year";      break;
    case MKTAG(0xa9,'g','e','n'): key = "genre";     break;
    case MKTAG(0xa9,'t','o','o'):
119
    case MKTAG(0xa9,'e','n','c'): key = "encoder";   break;
120 121 122 123 124
    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 已提交
125 126
    case MKTAG( 't','r','k','n'): key = "track";
        parse = mov_metadata_trkn; break;
127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    }

    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')) {
            get_be32(pb); // type
            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
        ff_mov_lang_to_iso639(get_be16(pb), language);
        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 已提交
158 159 160 161

    if (parse)
        parse(c, pb, str_size);
    else {
B
Baptiste Coudurier 已提交
162 163 164 165 166 167 168
        get_buffer(pb, str, str_size);
        str[str_size] = 0;
        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 已提交
169
    }
170 171 172 173 174 175 176 177
#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;
}
178

179
static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
180
{
181
    int64_t total_size = 0;
182
    MOVAtom a;
183 184
    int i;
    int err = 0;
185 186

    a.offset = atom.offset;
187

188
    if (atom.size < 0)
B
Baptiste Coudurier 已提交
189
        atom.size = INT64_MAX;
190
    while(((total_size + 8) < atom.size) && !url_feof(pb) && !err) {
191
        int (*parse)(MOVContext*, ByteIOContext*, MOVAtom) = NULL;
192
        a.size = atom.size;
B
Baptiste Coudurier 已提交
193
        a.type=0;
194
        if(atom.size >= 8) {
195
            a.size = get_be32(pb);
196
            a.type = get_le32(pb);
197
        }
198
        total_size += 8;
199
        a.offset += 8;
200 201
        dprintf(c->fc, "type: %08x  %.4s  sz: %"PRIx64"  %"PRIx64"   %"PRIx64"\n",
                a.type, (char*)&a.type, a.size, atom.size, total_size);
202
        if (a.size == 1) { /* 64 bit extended size */
203
            a.size = get_be64(pb) - 8;
204 205
            a.offset += 8;
            total_size += 8;
206
        }
207 208 209
        if (a.size == 0) {
            a.size = atom.size - total_size;
            if (a.size <= 8)
210
                break;
211 212
        }
        a.size -= 8;
213
        if(a.size < 0)
214
            break;
B
Baptiste Coudurier 已提交
215
        a.size = FFMIN(a.size, atom.size - total_size);
216

217 218 219 220 221
        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;
            }
222

223 224 225 226 227 228
        // 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 */
229
            url_fskip(pb, a.size);
230
        } else {
231
            int64_t start_pos = url_ftell(pb);
232
            int64_t left;
233
            err = parse(c, pb, a);
234
            if (url_is_streamed(pb) && c->found_moov && c->found_mdat)
B
Baptiste Coudurier 已提交
235
                break;
236 237 238
            left = a.size - url_ftell(pb) + start_pos;
            if (left > 0) /* skip garbage at atom end */
                url_fskip(pb, left);
239
        }
240

241
        a.offset += a.size;
242
        total_size += a.size;
243 244
    }

B
Baptiste Coudurier 已提交
245
    if (!err && total_size < atom.size && atom.size < 0x7ffff)
246
        url_fskip(pb, atom.size - total_size);
247

248 249 250
    return err;
}

251
static int mov_read_dref(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
252
{
253 254
    AVStream *st;
    MOVStreamContext *sc;
255 256
    int entries, i, j;

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

262 263 264 265 266
    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));
267 268 269
    if (!sc->drefs)
        return AVERROR(ENOMEM);
    sc->drefs_count = entries;
270 271

    for (i = 0; i < sc->drefs_count; i++) {
272
        MOVDref *dref = &sc->drefs[i];
273
        uint32_t size = get_be32(pb);
274
        int64_t next = url_ftell(pb) + size - 4;
275 276 277 278 279 280 281 282 283 284 285 286 287 288

        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);
289 290 291
            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);
292

293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
            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);
310 311 312 313 314 315 316 317

            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
318
                    av_free(dref->path);
319
                    dref->path = av_mallocz(len+1);
320 321
                    if (!dref->path)
                        return AVERROR(ENOMEM);
322
                    get_buffer(pb, dref->path, len);
323
                    if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
324 325 326 327 328 329 330 331
                        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);
332 333 334 335 336 337 338 339 340 341 342
                } 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);
343 344 345 346 347 348 349 350 351
                } else
                    url_fskip(pb, len);
            }
        }
        url_fseek(pb, next, SEEK_SET);
    }
    return 0;
}

352
static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
353
{
354
    AVStream *st;
355 356
    uint32_t type;
    uint32_t ctype;
357

358 359 360 361 362
    if (c->fc->nb_streams < 1) // meta before first trak
        return 0;

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

363
    get_byte(pb); /* version */
364
    get_be24(pb); /* flags */
365 366 367 368 369

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

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

373
    if     (type == MKTAG('v','i','d','e'))
374
        st->codec->codec_type = CODEC_TYPE_VIDEO;
375
    else if(type == MKTAG('s','o','u','n'))
376
        st->codec->codec_type = CODEC_TYPE_AUDIO;
377
    else if(type == MKTAG('m','1','a',' '))
378
        st->codec->codec_id = CODEC_ID_MP2;
379
    else if(type == MKTAG('s','u','b','p'))
380
        st->codec->codec_type = CODEC_TYPE_SUBTITLE;
381

382 383 384 385
    get_be32(pb); /* component  manufacture */
    get_be32(pb); /* component flags */
    get_be32(pb); /* component flags mask */

386
    if(atom.size <= 24)
387
        return 0; /* nothing left to read */
388

389
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
390 391 392
    return 0;
}

393
int ff_mp4_read_descr_len(ByteIOContext *pb)
394
{
395
    int len = 0;
396 397
    int count = 4;
    while (count--) {
398
        int c = get_byte(pb);
399 400 401
        len = (len << 7) | (c & 0x7f);
        if (!(c & 0x80))
            break;
402 403 404 405
    }
    return len;
}

406
int mp4_read_descr(AVFormatContext *fc, ByteIOContext *pb, int *tag)
407 408 409
{
    int len;
    *tag = get_byte(pb);
410 411
    len = ff_mp4_read_descr_len(pb);
    dprintf(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
412 413 414
    return len;
}

415 416 417 418
#define MP4ESDescrTag                   0x03
#define MP4DecConfigDescrTag            0x04
#define MP4DecSpecificDescrTag          0x05

419
static const AVCodecTag mp4_audio_types[] = {
420 421 422 423
    { 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 */
424
    { CODEC_ID_MP4ALS, AOT_ALS  }, /* MPEG-4 ALS */
425
    { CODEC_ID_NONE,   AOT_NULL },
426 427
};

428
int ff_mov_read_esds(AVFormatContext *fc, ByteIOContext *pb, MOVAtom atom)
429
{
430
    AVStream *st;
431
    int tag, len;
432

433
    if (fc->nb_streams < 1)
434
        return 0;
435
    st = fc->streams[fc->nb_streams-1];
436

437
    get_be32(pb); /* version + flags */
438
    len = mp4_read_descr(fc, pb, &tag);
439
    if (tag == MP4ESDescrTag) {
440 441
        get_be16(pb); /* ID */
        get_byte(pb); /* priority */
442
    } else
443
        get_be16(pb); /* ID */
444

445
    len = mp4_read_descr(fc, pb, &tag);
446
    if (tag == MP4DecConfigDescrTag) {
447 448 449 450 451 452
        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 */

453
        st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
454
        dprintf(fc, "esds object type id 0x%02x\n", object_type_id);
455
        len = mp4_read_descr(fc, pb, &tag);
456
        if (tag == MP4DecSpecificDescrTag) {
457
            dprintf(fc, "Specific MPEG4 header len=%d\n", len);
B
Baptiste Coudurier 已提交
458 459
            if((uint64_t)len > (1<<30))
                return -1;
B
Baptiste Coudurier 已提交
460
            st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
461 462
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
463 464
            get_buffer(pb, st->codec->extradata, len);
            st->codec->extradata_size = len;
465 466 467 468
            if (st->codec->codec_id == CODEC_ID_AAC) {
                MPEG4AudioConfig cfg;
                ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
                                         st->codec->extradata_size);
469
                st->codec->channels = cfg.channels;
470 471 472 473
                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 ?
474
                dprintf(fc, "mp4a config channels %d obj %d ext obj %d "
475 476 477
                        "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);
478 479
                if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,
                                                            cfg.object_type)))
480
                    st->codec->codec_id = CODEC_ID_AAC;
B
Baptiste Coudurier 已提交
481
            }
482
        }
483 484 485 486
    }
    return 0;
}

487 488 489 490 491
static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
    return ff_mov_read_esds(c->fc, pb, atom);
}

492 493 494 495
static int mov_read_pasp(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
    const int num = get_be32(pb);
    const int den = get_be32(pb);
496 497 498 499 500 501
    AVStream *st;

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

502
    if (den != 0) {
503 504
        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))
505
            av_log(c->fc, AV_LOG_WARNING,
506 507
                   "sample aspect ratio already set to %d:%d, overriding by 'pasp' atom\n",
                   st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
508 509 510 511 512 513
        st->sample_aspect_ratio.num = num;
        st->sample_aspect_ratio.den = den;
    }
    return 0;
}

514
/* this atom contains actual media data */
515
static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
516
{
517 518 519 520 521 522
    if(atom.size == 0) /* wrong one (MP4) */
        return 0;
    c->found_mdat=1;
    return 0; /* now go for moov */
}

523
/* read major brand, minor version and compatible brands and store them as metadata */
524
static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
525
{
526 527 528 529 530 531 532
    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 已提交
533
    if (strcmp(type, "qt  "))
534
        c->isom = 1;
535
    av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551
    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);

552 553 554
    return 0;
}

555
/* this atom should contain all header atoms */
556
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
557
{
558 559
    if (mov_read_default(c, pb, atom) < 0)
        return -1;
560 561 562 563 564 565
    /* 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 */
}

566
static int mov_read_moof(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
567 568 569 570 571
{
    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);
}
572

573
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
574
{
575 576 577
    AVStream *st;
    MOVStreamContext *sc;
    int version;
578
    char language[4] = {0};
579
    unsigned lang;
580

581 582 583 584 585 586
    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);
587
    if (version > 1)
B
Baptiste Coudurier 已提交
588
        return -1; /* unsupported */
589

590
    get_be24(pb); /* flags */
B
clean  
Baptiste Coudurier 已提交
591 592 593 594 595 596 597
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
598

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

602
    lang = get_be16(pb); /* language */
603 604
    if (ff_mov_lang_to_iso639(lang, language))
        av_metadata_set(&st->metadata, "language", language);
605 606 607 608 609
    get_be16(pb); /* quality */

    return 0;
}

610
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
611
{
B
Baptiste Coudurier 已提交
612
    int version = get_byte(pb); /* version */
613
    get_be24(pb); /* flags */
614

B
Baptiste Coudurier 已提交
615 616 617 618 619 620 621
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
622
    c->time_scale = get_be32(pb); /* time scale */
623 624 625

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

B
Baptiste Coudurier 已提交
626
    c->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645
    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;
}

646
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
647
{
648 649 650 651 652
    AVStream *st;

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

654 655
    if((uint64_t)atom.size > (1<<30))
        return -1;
656

657 658
    // currently SVQ3 decoder expect full STSD header - so let's fake it
    // this should be fixed and just SMI header should be passed
659
    av_free(st->codec->extradata);
660 661 662
    st->codec->extradata = av_mallocz(atom.size + 0x5a + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
663 664 665 666
    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);
667 668
    return 0;
}
669

670
static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
671
{
672 673 674 675 676 677
    AVStream *st;
    int little_endian;

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

679
    little_endian = get_be16(pb);
680 681
    dprintf(c->fc, "enda %d\n", little_endian);
    if (little_endian == 1) {
682 683 684 685 686 687 688
        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;
689 690 691 692 693 694
        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;
695 696 697 698 699 700 701
        default:
            break;
        }
    }
    return 0;
}

702
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
703
static int mov_read_extradata(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
704
{
705 706
    AVStream *st;
    uint64_t size;
707
    uint8_t *buf;
708 709 710 711 712

    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;
713
    if(size > INT_MAX || (uint64_t)atom.size > INT_MAX)
714
        return -1;
715 716 717 718 719 720 721 722 723
    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);
724 725 726
    return 0;
}

727
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
R
Roberto Togni 已提交
728
{
729 730 731 732 733
    AVStream *st;

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

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

738 739 740
    if (st->codec->codec_id == CODEC_ID_QDM2) {
        // pass all frma atom to codec, needed at least for QDM2
        av_free(st->codec->extradata);
741 742 743
        st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
        if (!st->codec->extradata)
            return AVERROR(ENOMEM);
744
        st->codec->extradata_size = atom.size;
745
        get_buffer(pb, st->codec->extradata, atom.size);
746
    } else if (atom.size > 8) { /* to read frma, esds atoms */
747 748
        if (mov_read_default(c, pb, atom) < 0)
            return -1;
749
    } else
750
        url_fskip(pb, atom.size);
R
Roberto Togni 已提交
751 752 753
    return 0;
}

754 755 756 757
/**
 * This function reads atom content and puts data in extradata without tag
 * nor size unlike mov_read_extradata.
 */
758
static int mov_read_glbl(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
759
{
760 761 762 763 764
    AVStream *st;

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

766 767 768
    if((uint64_t)atom.size > (1<<30))
        return -1;

769
    av_free(st->codec->extradata);
770 771 772
    st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
773
    st->codec->extradata_size = atom.size;
774
    get_buffer(pb, st->codec->extradata, atom.size);
775 776 777
    return 0;
}

778
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
779
{
780 781
    AVStream *st;
    MOVStreamContext *sc;
782
    unsigned int i, entries;
783

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

789
    get_byte(pb); /* version */
790
    get_be24(pb); /* flags */
791 792

    entries = get_be32(pb);
793

794 795
    if(entries >= UINT_MAX/sizeof(int64_t))
        return -1;
796

B
Baptiste Coudurier 已提交
797
    sc->chunk_offsets = av_malloc(entries * sizeof(int64_t));
798
    if (!sc->chunk_offsets)
799 800 801
        return AVERROR(ENOMEM);
    sc->chunk_count = entries;

802 803
    if      (atom.type == MKTAG('s','t','c','o'))
        for(i=0; i<entries; i++)
804
            sc->chunk_offsets[i] = get_be32(pb);
805 806
    else if (atom.type == MKTAG('c','o','6','4'))
        for(i=0; i<entries; i++)
807
            sc->chunk_offsets[i] = get_be64(pb);
808
    else
809
        return -1;
810

811 812 813
    return 0;
}

814 815 816 817
/**
 * Compute codec id for 'lpcm' tag.
 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
 */
818
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
819 820 821 822
{
    if (flags & 1) { // floating point
        if (flags & 2) { // big endian
            if      (bps == 32) return CODEC_ID_PCM_F32BE;
823
            else if (bps == 64) return CODEC_ID_PCM_F64BE;
824
        } else {
825 826
            if      (bps == 32) return CODEC_ID_PCM_F32LE;
            else if (bps == 64) return CODEC_ID_PCM_F64LE;
827 828 829 830 831 832 833 834 835 836 837 838 839 840
        }
    } 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 已提交
841
            else if (bps == 16) return CODEC_ID_PCM_S16LE;
842 843 844 845
            else if (bps == 24) return CODEC_ID_PCM_S24LE;
            else if (bps == 32) return CODEC_ID_PCM_S32LE;
        }
    }
D
Diego Pettenò 已提交
846
    return CODEC_ID_NONE;
847 848
}

849
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
850
{
851 852
    AVStream *st;
    MOVStreamContext *sc;
853
    int j, entries, pseudo_stream_id;
854

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

860
    get_byte(pb); /* version */
861
    get_be24(pb); /* flags */
862 863 864

    entries = get_be32(pb);

865 866
    for(pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
        //Parsing Sample description table
867
        enum CodecID id;
868
        int dref_id = 1;
869
        MOVAtom a = { 0, 0, 0 };
870
        int64_t start_pos = url_ftell(pb);
871
        int size = get_be32(pb); /* size */
872
        uint32_t format = get_le32(pb); /* data format */
873

874 875 876 877 878
        if (size >= 16) {
            get_be32(pb); /* reserved */
            get_be16(pb); /* reserved */
            dref_id = get_be16(pb);
        }
879

880
        if (st->codec->codec_tag &&
881
            st->codec->codec_tag != format &&
882
            (c->fc->video_codec_id ? ff_codec_get_id(codec_movvideo_tags, format) != c->fc->video_codec_id
883
                                   : st->codec->codec_tag != MKTAG('j','p','e','g'))
884
           ){
D
Diego Biurrun 已提交
885 886 887
            /* 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 已提交
888
            av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
889 890 891
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
            continue;
        }
892
        sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
893
        sc->dref_id= dref_id;
894

895
        st->codec->codec_tag = format;
896
        id = ff_codec_get_id(codec_movaudio_tags, format);
897
        if (id<=0 && ((format&0xFFFF) == 'm'+('s'<<8) || (format&0xFFFF) == 'T'+('S'<<8)))
898
            id = ff_codec_get_id(ff_codec_wav_tags, bswap_32(format)&0xFFFF);
M
Michael Niedermayer 已提交
899

900
        if (st->codec->codec_type != CODEC_TYPE_VIDEO && id > 0) {
901
            st->codec->codec_type = CODEC_TYPE_AUDIO;
902
        } else if (st->codec->codec_type != CODEC_TYPE_AUDIO && /* do not overwrite codec type */
903
                   format && format != MKTAG('m','p','4','s')) { /* skip old asf mpeg4 tag */
904
            id = ff_codec_get_id(codec_movvideo_tags, format);
905
            if (id <= 0)
906
                id = ff_codec_get_id(ff_codec_bmp_tags, format);
907 908
            if (id > 0)
                st->codec->codec_type = CODEC_TYPE_VIDEO;
909
            else if(st->codec->codec_type == CODEC_TYPE_DATA){
910
                id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
911 912 913
                if(id > 0)
                    st->codec->codec_type = CODEC_TYPE_SUBTITLE;
            }
914 915
        }

916 917 918
        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);
919

920
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
921 922 923 924
            uint8_t codec_name[32];
            unsigned int color_depth;
            int color_greyscale;

925
            st->codec->codec_id = id;
926 927 928 929
            get_be16(pb); /* version */
            get_be16(pb); /* revision level */
            get_be32(pb); /* vendor */
            get_be32(pb); /* temporal quality */
D
Diego Biurrun 已提交
930
            get_be32(pb); /* spatial quality */
931 932 933 934

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

935 936 937
            get_be32(pb); /* horiz resolution */
            get_be32(pb); /* vert resolution */
            get_be32(pb); /* data size, always 0 */
B
Baptiste Coudurier 已提交
938
            get_be16(pb); /* frames per samples */
939

B
Baptiste Coudurier 已提交
940
            get_buffer(pb, codec_name, 32); /* codec name, pascal string */
B
Baptiste Coudurier 已提交
941
            if (codec_name[0] <= 31) {
942 943 944 945
                int i;
                int pos = 0;
                for (i = 0; i < codec_name[0] && pos < sizeof(st->codec->codec_name) - 3; i++) {
                    uint8_t tmp;
946
                    PUT_UTF8(codec_name[i+1], tmp, st->codec->codec_name[pos++] = tmp;)
947 948
                }
                st->codec->codec_name[pos] = 0;
B
Baptiste Coudurier 已提交
949
            }
950

951
            st->codec->bits_per_coded_sample = get_be16(pb); /* depth */
952
            st->codec->color_table_id = get_be16(pb); /* colortable id */
953
            dprintf(c->fc, "depth %d, ctab id %d\n",
954
                   st->codec->bits_per_coded_sample, st->codec->color_table_id);
955
            /* figure out the palette situation */
956 957
            color_depth = st->codec->bits_per_coded_sample & 0x1F;
            color_greyscale = st->codec->bits_per_coded_sample & 0x20;
958 959

            /* if the depth is 2, 4, or 8 bpp, file is palettized */
960
            if ((color_depth == 2) || (color_depth == 4) ||
961
                (color_depth == 8)) {
962 963 964 965
                /* for palette traversal */
                unsigned int color_start, color_count, color_end;
                unsigned char r, g, b;

966
                st->codec->palctrl = av_malloc(sizeof(*st->codec->palctrl));
967
                if (color_greyscale) {
968
                    int color_index, color_dec;
969
                    /* compute the greyscale palette */
970
                    st->codec->bits_per_coded_sample = color_depth;
971 972 973 974 975
                    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;
976
                        st->codec->palctrl->palette[j] =
977 978 979 980 981
                            (r << 16) | (g << 8) | (b);
                        color_index -= color_dec;
                        if (color_index < 0)
                            color_index = 0;
                    }
982
                } else if (st->codec->color_table_id) {
983
                    const uint8_t *color_table;
984 985 986
                    /* if flag bit 3 is set, use the default palette */
                    color_count = 1 << color_depth;
                    if (color_depth == 2)
M
Michael Niedermayer 已提交
987
                        color_table = ff_qt_default_palette_4;
988
                    else if (color_depth == 4)
M
Michael Niedermayer 已提交
989
                        color_table = ff_qt_default_palette_16;
990
                    else
M
Michael Niedermayer 已提交
991
                        color_table = ff_qt_default_palette_256;
992 993

                    for (j = 0; j < color_count; j++) {
994 995 996
                        r = color_table[j * 3 + 0];
                        g = color_table[j * 3 + 1];
                        b = color_table[j * 3 + 2];
997
                        st->codec->palctrl->palette[j] =
998 999 1000 1001 1002 1003 1004
                            (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);
1005 1006
                    if ((color_start <= 255) &&
                        (color_end <= 255)) {
M
Mike Melanson 已提交
1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018
                        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);
1019
                            st->codec->palctrl->palette[j] =
M
Mike Melanson 已提交
1020
                                (r << 16) | (g << 8) | (b);
1021
                        }
1022 1023
                    }
                }
1024
                st->codec->palctrl->palette_changed = 1;
1025
            }
1026
        } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
1027
            int bits_per_sample, flags;
1028
            uint16_t version = get_be16(pb);
1029

1030
            st->codec->codec_id = id;
1031 1032
            get_be16(pb); /* revision level */
            get_be32(pb); /* vendor */
1033

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

1038
            sc->audio_cid = get_be16(pb);
1039 1040 1041 1042
            get_be16(pb); /* packet size = 0 */

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

1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055
            //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 */
1056
                    st->codec->bits_per_coded_sample = get_be32(pb); /* bits per channel if sound is uncompressed */
1057
                    flags = get_be32(pb); /* lcpm format specific flag */
B
Baptiste Coudurier 已提交
1058 1059
                    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 */
1060
                    if (format == MKTAG('l','p','c','m'))
1061
                        st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, flags);
1062 1063 1064
                }
            }

1065
            switch (st->codec->codec_id) {
1066 1067
            case CODEC_ID_PCM_S8:
            case CODEC_ID_PCM_U8:
1068
                if (st->codec->bits_per_coded_sample == 16)
1069 1070
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
                break;
1071
            case CODEC_ID_PCM_S16LE:
1072
            case CODEC_ID_PCM_S16BE:
1073
                if (st->codec->bits_per_coded_sample == 8)
1074
                    st->codec->codec_id = CODEC_ID_PCM_S8;
1075
                else if (st->codec->bits_per_coded_sample == 24)
1076 1077 1078
                    st->codec->codec_id =
                        st->codec->codec_id == CODEC_ID_PCM_S16BE ?
                        CODEC_ID_PCM_S24BE : CODEC_ID_PCM_S24LE;
1079
                break;
1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092
            /* 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;
1093 1094 1095 1096
            case CODEC_ID_GSM:
                sc->samples_per_frame = 160;
                sc->bytes_per_frame = 33;
                break;
1097 1098
            default:
                break;
1099
            }
1100

1101 1102
            bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
            if (bits_per_sample) {
1103
                st->codec->bits_per_coded_sample = bits_per_sample;
1104 1105
                sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
            }
1106
        } else if(st->codec->codec_type==CODEC_TYPE_SUBTITLE){
1107 1108 1109
            // 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) };
1110
            if (format != AV_RL32("mp4s")) // mp4s contains a regular esds atom
R
Reimar Döffinger 已提交
1111
                mov_read_glbl(c, pb, fake_atom);
1112
            st->codec->codec_id= id;
1113 1114
            st->codec->width = sc->width;
            st->codec->height = sc->height;
1115 1116 1117
        } else {
            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
1118
        }
1119 1120
        /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
        a.size = size - (url_ftell(pb) - start_pos);
1121 1122 1123 1124
        if (a.size > 8) {
            if (mov_read_default(c, pb, a) < 0)
                return -1;
        } else if (a.size > 0)
1125
            url_fskip(pb, a.size);
1126
    }
1127

B
Baptiste Coudurier 已提交
1128
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
1129
        st->codec->sample_rate= sc->time_scale;
1130

1131
    /* special codec parameters handling */
1132
    switch (st->codec->codec_id) {
1133
#if CONFIG_DV_DEMUXER
1134
    case CODEC_ID_DVAUDIO:
1135
        c->dv_fctx = avformat_alloc_context();
1136 1137 1138 1139 1140 1141 1142 1143
        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;
1144
#endif
1145
    /* no ifdef since parameters are always those */
1146
    case CODEC_ID_QCELP:
1147 1148 1149
        // 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;
1150
        st->codec->frame_size= 160;
1151
        st->codec->channels= 1; /* really needed */
1152
        break;
1153
    case CODEC_ID_AMR_NB:
1154
    case CODEC_ID_AMR_WB:
B
Baptiste Coudurier 已提交
1155
        st->codec->frame_size= sc->samples_per_frame;
1156
        st->codec->channels= 1; /* really needed */
1157
        /* force sample rate for amr, stsd in 3gp does not store sample rate */
B
Baptiste Coudurier 已提交
1158
        if (st->codec->codec_id == CODEC_ID_AMR_NB)
1159
            st->codec->sample_rate = 8000;
B
Baptiste Coudurier 已提交
1160 1161
        else if (st->codec->codec_id == CODEC_ID_AMR_WB)
            st->codec->sample_rate = 16000;
1162
        break;
1163
    case CODEC_ID_MP2:
1164
    case CODEC_ID_MP3:
1165
        st->codec->codec_type = CODEC_TYPE_AUDIO; /* force type after stsd for m1a hdlr */
A
Aurelien Jacobs 已提交
1166
        st->need_parsing = AVSTREAM_PARSE_FULL;
1167
        break;
1168
    case CODEC_ID_GSM:
1169 1170 1171 1172
    case CODEC_ID_ADPCM_MS:
    case CODEC_ID_ADPCM_IMA_WAV:
        st->codec->block_align = sc->bytes_per_frame;
        break;
1173
    case CODEC_ID_ALAC:
1174
        if (st->codec->extradata_size == 36) {
1175 1176
            st->codec->frame_size = AV_RB32(st->codec->extradata+12);
            st->codec->channels   = AV_RB8 (st->codec->extradata+21);
1177
        }
1178
        break;
1179 1180 1181
    default:
        break;
    }
1182

1183 1184 1185
    return 0;
}

1186
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1187
{
1188 1189
    AVStream *st;
    MOVStreamContext *sc;
1190
    unsigned int i, entries;
1191

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

1197
    get_byte(pb); /* version */
1198
    get_be24(pb); /* flags */
1199 1200

    entries = get_be32(pb);
1201

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

1204 1205
    if(entries >= UINT_MAX / sizeof(*sc->stsc_data))
        return -1;
1206 1207
    sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
    if (!sc->stsc_data)
1208 1209 1210
        return AVERROR(ENOMEM);
    sc->stsc_count = entries;

1211
    for(i=0; i<entries; i++) {
1212 1213 1214
        sc->stsc_data[i].first = get_be32(pb);
        sc->stsc_data[i].count = get_be32(pb);
        sc->stsc_data[i].id = get_be32(pb);
1215 1216 1217 1218
    }
    return 0;
}

1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
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;
}

1248
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1249
{
1250 1251
    AVStream *st;
    MOVStreamContext *sc;
1252
    unsigned int i, entries;
1253

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

1259
    get_byte(pb); /* version */
1260
    get_be24(pb); /* flags */
1261 1262

    entries = get_be32(pb);
1263

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

B
Baptiste Coudurier 已提交
1266
    if(entries >= UINT_MAX / sizeof(int))
1267
        return -1;
B
Baptiste Coudurier 已提交
1268
    sc->keyframes = av_malloc(entries * sizeof(int));
1269
    if (!sc->keyframes)
1270 1271 1272
        return AVERROR(ENOMEM);
    sc->keyframe_count = entries;

1273 1274
    for(i=0; i<entries; i++) {
        sc->keyframes[i] = get_be32(pb);
1275
        //dprintf(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
1276 1277 1278 1279
    }
    return 0;
}

1280
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1281
{
1282 1283
    AVStream *st;
    MOVStreamContext *sc;
1284 1285 1286
    unsigned int i, entries, sample_size, field_size, num_bytes;
    GetBitContext gb;
    unsigned char* buf;
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
    if (atom.type == MKTAG('s','t','s','z')) {
1297 1298 1299 1300
        sample_size = get_be32(pb);
        if (!sc->sample_size) /* do not overwrite value computed in stsd */
            sc->sample_size = sample_size;
        field_size = 32;
1301 1302 1303 1304 1305
    } else {
        sample_size = 0;
        get_be24(pb); /* reserved */
        field_size = get_byte(pb);
    }
1306
    entries = get_be32(pb);
1307 1308

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

1310
    sc->sample_count = entries;
1311 1312 1313
    if (sample_size)
        return 0;

1314 1315 1316 1317 1318
    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;
    }

1319
    if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size)
1320
        return -1;
B
Baptiste Coudurier 已提交
1321
    sc->sample_sizes = av_malloc(entries * sizeof(int));
1322
    if (!sc->sample_sizes)
1323 1324
        return AVERROR(ENOMEM);

1325 1326
    num_bytes = (entries*field_size+4)>>3;

1327
    buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE);
1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340
    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);

1341
    for(i=0; i<entries; i++)
1342 1343 1344
        sc->sample_sizes[i] = get_bits_long(&gb, field_size);

    av_free(buf);
1345 1346 1347
    return 0;
}

1348
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1349
{
1350 1351
    AVStream *st;
    MOVStreamContext *sc;
1352
    unsigned int i, entries;
1353 1354
    int64_t duration=0;
    int64_t total_sample_count=0;
1355

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

1361
    get_byte(pb); /* version */
1362
    get_be24(pb); /* flags */
1363
    entries = get_be32(pb);
1364 1365 1366

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

1367
    if(entries >= UINT_MAX / sizeof(*sc->stts_data))
1368
        return -1;
1369
    sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));
1370
    if (!sc->stts_data)
1371 1372
        return AVERROR(ENOMEM);
    sc->stts_count = entries;
1373

1374
    for(i=0; i<entries; i++) {
M
cleanup  
Michael Niedermayer 已提交
1375 1376
        int sample_duration;
        int sample_count;
1377

1378
        sample_count=get_be32(pb);
1379
        sample_duration = get_be32(pb);
1380 1381 1382
        sc->stts_data[i].count= sample_count;
        sc->stts_data[i].duration= sample_duration;

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

B
Baptiste Coudurier 已提交
1385
        duration+=(int64_t)sample_duration*sample_count;
1386 1387 1388
        total_sample_count+=sample_count;
    }

1389 1390 1391
    st->nb_frames= total_sample_count;
    if(duration)
        st->duration= duration;
1392 1393 1394
    return 0;
}

1395
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
M
Michael Niedermayer 已提交
1396
{
1397 1398
    AVStream *st;
    MOVStreamContext *sc;
M
Michael Niedermayer 已提交
1399 1400
    unsigned int i, entries;

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

M
Michael Niedermayer 已提交
1406
    get_byte(pb); /* version */
1407
    get_be24(pb); /* flags */
M
Michael Niedermayer 已提交
1408
    entries = get_be32(pb);
1409 1410 1411

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

1412
    if(entries >= UINT_MAX / sizeof(*sc->ctts_data))
M
Michael Niedermayer 已提交
1413
        return -1;
1414
    sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
1415
    if (!sc->ctts_data)
1416 1417
        return AVERROR(ENOMEM);
    sc->ctts_count = entries;
1418

M
Michael Niedermayer 已提交
1419
    for(i=0; i<entries; i++) {
1420 1421 1422 1423 1424
        int count    =get_be32(pb);
        int duration =get_be32(pb);

        sc->ctts_data[i].count   = count;
        sc->ctts_data[i].duration= duration;
1425 1426
        if (duration < 0)
            sc->dts_shift = FFMAX(sc->dts_shift, -duration);
M
Michael Niedermayer 已提交
1427
    }
1428

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

M
Michael Niedermayer 已提交
1431 1432 1433
    return 0;
}

1434 1435 1436
static void mov_build_index(MOVContext *mov, AVStream *st)
{
    MOVStreamContext *sc = st->priv_data;
1437
    int64_t current_offset;
1438 1439 1440 1441
    int64_t current_dts = 0;
    unsigned int stts_index = 0;
    unsigned int stsc_index = 0;
    unsigned int stss_index = 0;
1442
    unsigned int stps_index = 0;
1443
    unsigned int i, j;
1444
    uint64_t stream_size = 0;
1445

1446 1447
    /* adjust first dts according to edit list */
    if (sc->time_offset) {
1448
        int rescaled = sc->time_offset < 0 ? av_rescale(sc->time_offset, sc->time_scale, mov->time_scale) : sc->time_offset;
1449
        current_dts = -rescaled;
1450 1451 1452 1453 1454 1455
        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;
        }
1456 1457
    }

1458 1459 1460
    /* only use old uncompressed audio chunk demuxing when stts specifies it */
    if (!(st->codec->codec_type == CODEC_TYPE_AUDIO &&
          sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
1461 1462
        unsigned int current_sample = 0;
        unsigned int stts_sample = 0;
1463
        unsigned int sample_size;
1464 1465 1466
        unsigned int distance = 0;
        int key_off = sc->keyframes && sc->keyframes[0] == 1;

1467 1468
        current_dts -= sc->dts_shift;

1469 1470
        for (i = 0; i < sc->chunk_count; i++) {
            current_offset = sc->chunk_offsets[i];
1471 1472
            if (stsc_index + 1 < sc->stsc_count &&
                i + 1 == sc->stsc_data[stsc_index + 1].first)
1473
                stsc_index++;
1474
            for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
1475
                int keyframe = 0;
1476 1477
                if (current_sample >= sc->sample_count) {
                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
1478
                    return;
1479
                }
1480 1481 1482

                if (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index]) {
                    keyframe = 1;
1483 1484
                    if (stss_index + 1 < sc->keyframe_count)
                        stss_index++;
1485 1486 1487 1488
                } 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++;
1489
                }
1490 1491
                if (keyframe)
                    distance = 0;
1492
                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
1493
                if(sc->pseudo_stream_id == -1 ||
1494
                   sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
1495 1496
                    av_add_index_entry(st, current_offset, current_dts, sample_size, distance,
                                    keyframe ? AVINDEX_KEYFRAME : 0);
1497 1498 1499 1500
                    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);
                }
1501

1502
                current_offset += sample_size;
1503
                stream_size += sample_size;
1504
                current_dts += sc->stts_data[stts_index].duration;
1505 1506 1507 1508 1509 1510 1511 1512 1513
                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++;
                }
            }
        }
1514 1515
        if (st->duration > 0)
            st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;
1516
    } else {
1517
        for (i = 0; i < sc->chunk_count; i++) {
1518 1519
            unsigned chunk_samples;

1520
            current_offset = sc->chunk_offsets[i];
1521 1522
            if (stsc_index + 1 < sc->stsc_count &&
                i + 1 == sc->stsc_data[stsc_index + 1].first)
1523
                stsc_index++;
1524
            chunk_samples = sc->stsc_data[stsc_index].count;
1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541

            if (sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
                av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
                return;
            }

            while (chunk_samples > 0) {
                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;
1542
                    } else {
1543 1544
                        samples = FFMIN(1024, chunk_samples);
                        size = samples * sc->sample_size;
1545 1546
                    }
                }
1547 1548

                av_add_index_entry(st, current_offset, current_dts, size, 0, AVINDEX_KEYFRAME);
1549 1550
                dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "
                        "size %d, duration %d\n", st->index, i, current_offset, current_dts,
1551 1552 1553
                        size, samples);

                current_offset += size;
1554
                current_dts += samples;
1555
                chunk_samples -= samples;
1556 1557 1558 1559
            }
        }
    }
}
1560

1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606
static int mov_open_dref(ByteIOContext **pb, char *src, MOVDref *ref)
{
    /* try absolute path */
    if (!url_fopen(pb, ref->path, URL_RDONLY))
        return 0;

    /* try relative path */
    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 */
        if (i == ref->nlvl_to - 1) {
            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);
};

1607
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1608 1609 1610
{
    AVStream *st;
    MOVStreamContext *sc;
1611
    int ret;
1612 1613

    st = av_new_stream(c->fc, c->fc->nb_streams);
B
Baptiste Coudurier 已提交
1614
    if (!st) return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
1615
    sc = av_mallocz(sizeof(MOVStreamContext));
1616
    if (!sc) return AVERROR(ENOMEM);
1617 1618

    st->priv_data = sc;
1619
    st->codec->codec_type = CODEC_TYPE_DATA;
1620
    sc->ffindex = st->index;
1621

1622 1623 1624 1625
    if ((ret = mov_read_default(c, pb, atom)) < 0)
        return ret;

    /* sanity checks */
1626 1627
    if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
                            (!sc->sample_size && !sc->sample_count))) {
1628 1629
        av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
               st->index);
1630 1631
        return 0;
    }
1632

1633 1634
    if (!sc->time_scale) {
        av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", st->index);
1635
        sc->time_scale = c->time_scale;
1636 1637 1638
        if (!sc->time_scale)
            sc->time_scale = 1;
    }
1639

1640
    av_set_pts_info(st, 64, 1, sc->time_scale);
1641

1642
    if (st->codec->codec_type == CODEC_TYPE_AUDIO &&
1643 1644 1645 1646 1647
        !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);
    }
1648 1649 1650 1651

    mov_build_index(c, st);

    if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
1652 1653 1654 1655 1656 1657 1658
        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);
1659 1660 1661 1662
    } else
        sc->pb = c->fc->pb;

    switch (st->codec->codec_id) {
1663
#if CONFIG_H261_DECODER
1664 1665
    case CODEC_ID_H261:
#endif
1666
#if CONFIG_H263_DECODER
1667 1668
    case CODEC_ID_H263:
#endif
1669 1670 1671
#if CONFIG_H264_DECODER
    case CODEC_ID_H264:
#endif
1672
#if CONFIG_MPEG4_DECODER
1673 1674
    case CODEC_ID_MPEG4:
#endif
1675
        st->codec->width = 0; /* let decoder init width/height */
1676 1677 1678
        st->codec->height= 0;
        break;
    }
B
Baptiste Coudurier 已提交
1679 1680 1681

    /* Do not need those anymore. */
    av_freep(&sc->chunk_offsets);
1682
    av_freep(&sc->stsc_data);
B
Baptiste Coudurier 已提交
1683 1684 1685
    av_freep(&sc->sample_sizes);
    av_freep(&sc->keyframes);
    av_freep(&sc->stts_data);
1686
    av_freep(&sc->stps_data);
B
Baptiste Coudurier 已提交
1687

1688
    return 0;
1689 1690
}

1691
static int mov_read_ilst(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1692 1693 1694 1695 1696 1697 1698 1699
{
    int ret;
    c->itunes_metadata = 1;
    ret = mov_read_default(c, pb, atom);
    c->itunes_metadata = 0;
    return ret;
}

1700
static int mov_read_meta(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1701
{
1702 1703 1704 1705 1706 1707 1708 1709 1710 1711
    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;
1712 1713
}

1714
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1715
{
1716 1717 1718 1719 1720
    int i;
    int width;
    int height;
    int64_t disp_transform[2];
    int display_matrix[3][2];
1721 1722 1723 1724 1725 1726 1727 1728
    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;
1729

1730
    version = get_byte(pb);
1731
    get_be24(pb); /* flags */
1732 1733 1734 1735 1736 1737 1738
    /*
    MOV_TRACK_ENABLED 0x0001
    MOV_TRACK_IN_MOVIE 0x0002
    MOV_TRACK_IN_PREVIEW 0x0004
    MOV_TRACK_IN_POSTER 0x0008
    */

B
Baptiste Coudurier 已提交
1739 1740 1741 1742 1743 1744 1745
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
1746 1747
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
    get_be32(pb); /* reserved */
1748

1749 1750
    /* highlevel (considering edits) duration in movie timebase */
    (version == 1) ? get_be64(pb) : get_be32(pb);
1751 1752 1753 1754 1755 1756 1757 1758
    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 */

1759 1760 1761 1762 1763 1764 1765 1766
    //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)
    }
1767

1768 1769
    width = get_be32(pb);       // 16.16 fixed point track width
    height = get_be32(pb);      // 16.16 fixed point track height
1770 1771
    sc->width = width >> 16;
    sc->height = height >> 16;
1772

1773
    // transform the display width/height according to the matrix
1774
    // skip this if the display matrix is the default identity matrix
1775
    // or if it is rotating the picture, ex iPhone 3GS
1776 1777
    // to keep the same scale, use [width height 1<<16]
    if (width && height &&
1778 1779 1780 1781 1782
        ((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])) {
1783 1784 1785 1786 1787 1788 1789
        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
1790
        st->sample_aspect_ratio = av_d2q(
1791 1792 1793
            ((double) disp_transform[0] * height) /
            ((double) disp_transform[1] * width), INT_MAX);
    }
1794 1795 1796
    return 0;
}

1797
static int mov_read_tfhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1798 1799 1800 1801 1802 1803 1804 1805 1806
{
    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);
1807
    if (!track_id)
B
Baptiste Coudurier 已提交
1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831
        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;
}

1832
static int mov_read_trex(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1833 1834 1835 1836 1837
{
    MOVTrackExt *trex;

    if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
        return -1;
1838 1839
    trex = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data));
    if (!trex)
B
Baptiste Coudurier 已提交
1840
        return AVERROR(ENOMEM);
1841
    c->trex_data = trex;
B
Baptiste Coudurier 已提交
1842 1843 1844 1845 1846 1847 1848 1849 1850 1851 1852
    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;
}

1853
static int mov_read_trun(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1854 1855
{
    MOVFragment *frag = &c->fragment;
1856
    AVStream *st = NULL;
1857
    MOVStreamContext *sc;
B
Baptiste Coudurier 已提交
1858 1859 1860 1861 1862 1863
    uint64_t offset;
    int64_t dts;
    int data_offset = 0;
    unsigned entries, first_sample_flags = frag->flags;
    int flags, distance, i;

1864 1865 1866 1867 1868 1869 1870 1871
    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);
1872
        return -1;
1873
    }
1874
    sc = st->priv_data;
B
Baptiste Coudurier 已提交
1875 1876 1877 1878 1879 1880 1881 1882 1883
    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) {
1884
        MOVStts *ctts_data;
B
Baptiste Coudurier 已提交
1885 1886
        if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
            return -1;
1887 1888 1889
        ctts_data = av_realloc(sc->ctts_data,
                               (entries+sc->ctts_count)*sizeof(*sc->ctts_data));
        if (!ctts_data)
B
Baptiste Coudurier 已提交
1890
            return AVERROR(ENOMEM);
1891
        sc->ctts_data = ctts_data;
B
Baptiste Coudurier 已提交
1892 1893 1894 1895 1896 1897 1898 1899 1900 1901 1902 1903 1904 1905 1906 1907 1908 1909 1910 1911 1912 1913 1914 1915 1916 1917 1918 1919
    }
    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++;
        }
        if ((keyframe = st->codec->codec_type == CODEC_TYPE_AUDIO ||
             (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++;
1920
        dts += sample_duration;
B
Baptiste Coudurier 已提交
1921 1922 1923 1924 1925 1926 1927
        offset += sample_size;
    }
    frag->moof_offset = offset;
    st->duration = dts;
    return 0;
}

1928 1929 1930
/* 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/ */
1931
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1932 1933 1934 1935 1936 1937 1938 1939 1940 1941 1942 1943
{
    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.offset += 8;
    atom.size -= 8;
1944
    if (atom.type != MKTAG('m','d','a','t')) {
1945 1946 1947 1948 1949 1950 1951
        url_fskip(pb, atom.size);
        return 0;
    }
    err = mov_read_mdat(c, pb, atom);
    return err;
}

1952
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1953
{
1954
#if CONFIG_ZLIB
1955
    ByteIOContext ctx;
1956 1957
    uint8_t *cmov_data;
    uint8_t *moov_data; /* uncompressed data */
1958
    long cmov_len, moov_len;
1959
    int ret = -1;
1960

1961
    get_be32(pb); /* dcom atom */
1962
    if (get_le32(pb) != MKTAG('d','c','o','m'))
1963
        return -1;
1964
    if (get_le32(pb) != MKTAG('z','l','i','b')) {
B
Benoit Fouet 已提交
1965
        av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !");
1966 1967 1968
        return -1;
    }
    get_be32(pb); /* cmvd atom */
1969
    if (get_le32(pb) != MKTAG('c','m','v','d'))
1970 1971
        return -1;
    moov_len = get_be32(pb); /* uncompressed size */
1972
    cmov_len = atom.size - 6 * 4;
1973

B
Baptiste Coudurier 已提交
1974
    cmov_data = av_malloc(cmov_len);
1975
    if (!cmov_data)
1976
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
1977
    moov_data = av_malloc(moov_len);
1978 1979
    if (!moov_data) {
        av_free(cmov_data);
1980
        return AVERROR(ENOMEM);
1981 1982
    }
    get_buffer(pb, cmov_data, cmov_len);
1983
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1984
        goto free_and_return;
1985
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
1986
        goto free_and_return;
1987
    atom.type = MKTAG('m','o','o','v');
1988 1989
    atom.offset = 0;
    atom.size = moov_len;
1990
#ifdef DEBUG
M
Michael Niedermayer 已提交
1991
//    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1992
#endif
1993
    ret = mov_read_default(c, &ctx, atom);
1994
free_and_return:
1995 1996 1997
    av_free(moov_data);
    av_free(cmov_data);
    return ret;
1998 1999 2000
#else
    av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
    return -1;
2001
#endif
2002
}
2003

G
Gael Chardon 已提交
2004
/* edit list atom */
2005
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
G
Gael Chardon 已提交
2006
{
2007
    MOVStreamContext *sc;
B
Baptiste Coudurier 已提交
2008 2009
    int i, edit_count;

2010 2011 2012 2013
    if (c->fc->nb_streams < 1)
        return 0;
    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;

B
Baptiste Coudurier 已提交
2014
    get_byte(pb); /* version */
2015
    get_be24(pb); /* flags */
B
Baptiste Coudurier 已提交
2016
    edit_count = get_be32(pb); /* entries */
B
Baptiste Coudurier 已提交
2017

2018 2019 2020
    if((uint64_t)edit_count*12+8 > atom.size)
        return -1;

B
Baptiste Coudurier 已提交
2021
    for(i=0; i<edit_count; i++){
2022
        int time;
2023
        int duration = get_be32(pb); /* Track duration */
2024
        time = get_be32(pb); /* Media time */
B
Baptiste Coudurier 已提交
2025
        get_be32(pb); /* Media rate */
2026 2027
        if (i == 0 && time >= -1) {
            sc->time_offset = time != -1 ? time : -duration;
2028
        }
B
Baptiste Coudurier 已提交
2029
    }
2030 2031 2032 2033 2034

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

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

2039
static const MOVParseTableEntry mov_default_parse_table[] = {
2040
{ MKTAG('a','v','s','s'), mov_read_extradata },
2041 2042 2043 2044 2045 2046 2047 2048 2049 2050 2051
{ 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 },
2052
{ MKTAG('i','l','s','t'), mov_read_ilst },
2053 2054 2055 2056
{ 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 },
2057
{ MKTAG('m','e','t','a'), mov_read_meta },
2058 2059 2060 2061 2062 2063 2064 2065
{ 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 },
2066
{ MKTAG('p','a','s','p'), mov_read_pasp },
2067 2068
{ MKTAG('s','t','b','l'), mov_read_default },
{ MKTAG('s','t','c','o'), mov_read_stco },
2069
{ MKTAG('s','t','p','s'), mov_read_stps },
2070 2071 2072 2073 2074
{ 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 },
2075
{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
2076 2077 2078 2079 2080 2081
{ 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 已提交
2082
{ MKTAG('u','d','t','a'), mov_read_default },
2083 2084 2085 2086
{ 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 已提交
2087
{ 0, NULL }
2088 2089
};

F
Fabrice Bellard 已提交
2090 2091
static int mov_probe(AVProbeData *p)
{
2092 2093
    unsigned int offset;
    uint32_t tag;
2094
    int score = 0;
2095

F
Fabrice Bellard 已提交
2096
    /* check file header */
2097 2098 2099 2100
    offset = 0;
    for(;;) {
        /* ignore invalid offset */
        if ((offset + 8) > (unsigned int)p->buf_size)
2101
            return score;
2102
        tag = AV_RL32(p->buf + offset + 4);
2103
        switch(tag) {
2104
        /* check for obvious tags */
2105 2106 2107 2108 2109
        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 */
2110
        case MKTAG('f','t','y','p'):
2111
            return AVPROBE_SCORE_MAX;
2112
        /* those are more common words, so rate then a bit less */
2113 2114 2115 2116 2117
        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'):
2118
            return AVPROBE_SCORE_MAX - 5;
B
Baptiste Coudurier 已提交
2119
        case MKTAG(0x82,0x82,0x7f,0x7d):
2120 2121 2122
        case MKTAG('s','k','i','p'):
        case MKTAG('u','u','i','d'):
        case MKTAG('p','r','f','l'):
2123
            offset = AV_RB32(p->buf+offset) + offset;
2124 2125
            /* if we only find those cause probedata is too small at least rate them */
            score = AVPROBE_SCORE_MAX - 50;
2126 2127 2128
            break;
        default:
            /* unrecognized tag */
2129
            return score;
2130
        }
2131
    }
2132
    return score;
F
Fabrice Bellard 已提交
2133 2134
}

Z
Zdenek Kabelac 已提交
2135
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
2136
{
2137
    MOVContext *mov = s->priv_data;
2138
    ByteIOContext *pb = s->pb;
B
Baptiste Coudurier 已提交
2139
    int err;
2140
    MOVAtom atom = { 0, 0, 0 };
2141 2142

    mov->fc = s;
2143 2144
    /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
    if(!url_is_streamed(pb))
2145
        atom.size = url_fsize(pb);
2146
    else
B
Baptiste Coudurier 已提交
2147
        atom.size = INT64_MAX;
2148 2149

    /* check MOV header */
B
Baptiste Coudurier 已提交
2150 2151 2152 2153 2154 2155
    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");
2156
        return -1;
2157
    }
B
Baptiste Coudurier 已提交
2158
    dprintf(mov->fc, "on_parse_exit_offset=%lld\n", url_ftell(pb));
2159

2160 2161 2162
    return 0;
}

2163
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
2164
{
2165
    AVIndexEntry *sample = NULL;
2166
    int64_t best_dts = INT64_MAX;
2167
    int i;
B
Baptiste Coudurier 已提交
2168
    for (i = 0; i < s->nb_streams; i++) {
2169 2170
        AVStream *avst = s->streams[i];
        MOVStreamContext *msc = avst->priv_data;
2171
        if (msc->pb && msc->current_sample < avst->nb_index_entries) {
2172
            AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
2173
            int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
B
Baptiste Coudurier 已提交
2174
            dprintf(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
B
Baptiste Coudurier 已提交
2175 2176
            if (!sample || (url_is_streamed(s->pb) && current_sample->pos < sample->pos) ||
                (!url_is_streamed(s->pb) &&
2177
                 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
B
Baptiste Coudurier 已提交
2178
                 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
2179
                  (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
2180 2181
                sample = current_sample;
                best_dts = dts;
2182
                *st = avst;
2183
            }
2184 2185
        }
    }
2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197
    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);
2198 2199 2200
    if (!sample) {
        mov->found_mdat = 0;
        if (!url_is_streamed(s->pb) ||
2201
            mov_read_default(mov, s->pb, (MOVAtom){ 0, 0, INT64_MAX }) < 0 ||
2202
            url_feof(s->pb))
B
Baptiste Coudurier 已提交
2203
            return AVERROR_EOF;
2204 2205 2206
        dprintf(s, "read fragments, offset 0x%llx\n", url_ftell(s->pb));
        goto retry;
    }
2207
    sc = st->priv_data;
2208 2209
    /* must be done just before reading, to avoid infinite loop on sample */
    sc->current_sample++;
2210 2211

    if (st->discard != AVDISCARD_ALL) {
R
Reimar Döffinger 已提交
2212 2213 2214 2215 2216 2217
        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);
2218 2219
        if (ret < 0)
            return ret;
R
Reimar Döffinger 已提交
2220 2221 2222 2223 2224 2225 2226 2227 2228
#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;
        }
2229
#endif
2230 2231
    }

2232 2233 2234
    pkt->stream_index = sc->ffindex;
    pkt->dts = sample->timestamp;
    if (sc->ctts_data) {
2235
        pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
2236
        /* update ctts context */
2237 2238 2239 2240 2241
        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;
2242
        }
2243 2244
        if (sc->wrong_dts)
            pkt->dts = AV_NOPTS_VALUE;
2245
    } else {
2246
        int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
2247 2248
            st->index_entries[sc->current_sample].timestamp : st->duration;
        pkt->duration = next_dts - pkt->dts;
2249
        pkt->pts = pkt->dts;
2250
    }
2251 2252
    if (st->discard == AVDISCARD_ALL)
        goto retry;
2253 2254
    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? PKT_FLAG_KEY : 0;
    pkt->pos = sample->pos;
2255 2256
    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);
2257 2258
    return 0;
}
2259

2260
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
2261 2262 2263 2264
{
    MOVStreamContext *sc = st->priv_data;
    int sample, time_sample;
    int i;
2265

2266
    sample = av_index_search_timestamp(st, timestamp, flags);
2267
    dprintf(s, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
2268 2269 2270
    if (sample < 0) /* not sure what to do */
        return -1;
    sc->current_sample = sample;
2271
    dprintf(s, "stream %d, found sample %d\n", st->index, sc->current_sample);
2272 2273 2274 2275
    /* adjust ctts index */
    if (sc->ctts_data) {
        time_sample = 0;
        for (i = 0; i < sc->ctts_count; i++) {
2276 2277
            int next = time_sample + sc->ctts_data[i].count;
            if (next > sc->current_sample) {
2278 2279
                sc->ctts_index = i;
                sc->ctts_sample = sc->current_sample - time_sample;
2280
                break;
2281
            }
2282
            time_sample = next;
2283 2284
        }
    }
2285
    return sample;
2286 2287
}

2288
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
G
Gael Chardon 已提交
2289
{
2290 2291 2292 2293
    AVStream *st;
    int64_t seek_timestamp, timestamp;
    int sample;
    int i;
G
Gael Chardon 已提交
2294

2295
    if (stream_index >= s->nb_streams)
G
Gael Chardon 已提交
2296
        return -1;
2297 2298
    if (sample_time < 0)
        sample_time = 0;
G
Gael Chardon 已提交
2299

2300
    st = s->streams[stream_index];
2301
    sample = mov_seek_stream(s, st, sample_time, flags);
2302
    if (sample < 0)
G
Gael Chardon 已提交
2303 2304
        return -1;

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

2308 2309
    for (i = 0; i < s->nb_streams; i++) {
        st = s->streams[i];
2310
        if (stream_index == i)
2311
            continue;
G
Gael Chardon 已提交
2312

2313
        timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
2314
        mov_seek_stream(s, st, timestamp, flags);
2315
    }
G
Gael Chardon 已提交
2316 2317 2318
    return 0;
}

Z
Zdenek Kabelac 已提交
2319
static int mov_read_close(AVFormatContext *s)
2320
{
2321
    MOVContext *mov = s->priv_data;
2322 2323 2324
    int i, j;

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

2328
        av_freep(&sc->ctts_data);
2329
        for (j = 0; j < sc->drefs_count; j++) {
2330
            av_freep(&sc->drefs[j].path);
2331 2332
            av_freep(&sc->drefs[j].dir);
        }
2333 2334 2335
        av_freep(&sc->drefs);
        if (sc->pb && sc->pb != s->pb)
            url_fclose(sc->pb);
2336 2337

        av_freep(&st->codec->palctrl);
2338
    }
2339 2340 2341

    if (mov->dv_demux) {
        for(i = 0; i < mov->dv_fctx->nb_streams; i++) {
2342 2343 2344 2345 2346 2347
            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);
    }
2348

B
Baptiste Coudurier 已提交
2349
    av_freep(&mov->trex_data);
2350

2351 2352 2353
    return 0;
}

2354
AVInputFormat mov_demuxer = {
2355
    "mov,mp4,m4a,3gp,3g2,mj2",
2356
    NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
F
Fabrice Bellard 已提交
2357 2358
    sizeof(MOVContext),
    mov_probe,
2359 2360 2361
    mov_read_header,
    mov_read_packet,
    mov_read_close,
G
Gael Chardon 已提交
2362
    mov_read_seek,
2363
};