mov.c 75.6 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 112 113 114 115 116 117
    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'):
118
    case MKTAG(0xa9,'e','n','c'): key = "encoder";   break;
B
Baptiste Coudurier 已提交
119 120
    case MKTAG( 't','r','k','n'): key = "track";
        parse = mov_metadata_trkn; break;
121 122 123 124 125 126 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
    }

    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 已提交
152 153 154 155

    if (parse)
        parse(c, pb, str_size);
    else {
B
Baptiste Coudurier 已提交
156 157 158 159 160 161 162
        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 已提交
163
    }
164 165 166 167 168 169 170 171
#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;
}
172

173
static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
174
{
175
    int64_t total_size = 0;
176
    MOVAtom a;
177 178
    int i;
    int err = 0;
179 180

    a.offset = atom.offset;
181

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

211 212 213 214 215
        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;
            }
216

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

235
        a.offset += a.size;
236
        total_size += a.size;
237 238
    }

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

242 243 244
    return err;
}

245
static int mov_read_dref(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
246
{
247 248
    AVStream *st;
    MOVStreamContext *sc;
249 250
    int entries, i, j;

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

256 257 258 259 260
    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));
261 262 263
    if (!sc->drefs)
        return AVERROR(ENOMEM);
    sc->drefs_count = entries;
264 265

    for (i = 0; i < sc->drefs_count; i++) {
266
        MOVDref *dref = &sc->drefs[i];
267
        uint32_t size = get_be32(pb);
268
        int64_t next = url_ftell(pb) + size - 4;
269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296

        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;
            char volume[28];
            int16_t type;

            url_fskip(pb, 10);

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

            url_fskip(pb, 112);

            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
297
                    av_free(dref->path);
298
                    dref->path = av_mallocz(len+1);
299 300
                    if (!dref->path)
                        return AVERROR(ENOMEM);
301
                    get_buffer(pb, dref->path, len);
302
                    if (len > volume_len && !strncmp(dref->path, volume, volume_len)) {
303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
                        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);
                } else
                    url_fskip(pb, len);
            }
        }
        url_fseek(pb, next, SEEK_SET);
    }
    return 0;
}

320
static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
321
{
322
    AVStream *st;
323 324
    uint32_t type;
    uint32_t ctype;
325

326 327 328 329 330
    if (c->fc->nb_streams < 1) // meta before first trak
        return 0;

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

331
    get_byte(pb); /* version */
332
    get_be24(pb); /* flags */
333 334 335 336 337

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

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

341
    if     (type == MKTAG('v','i','d','e'))
342
        st->codec->codec_type = CODEC_TYPE_VIDEO;
343
    else if(type == MKTAG('s','o','u','n'))
344
        st->codec->codec_type = CODEC_TYPE_AUDIO;
345
    else if(type == MKTAG('m','1','a',' '))
346
        st->codec->codec_id = CODEC_ID_MP2;
347
    else if(type == MKTAG('s','u','b','p'))
348
        st->codec->codec_type = CODEC_TYPE_SUBTITLE;
349

350 351 352 353
    get_be32(pb); /* component  manufacture */
    get_be32(pb); /* component flags */
    get_be32(pb); /* component flags mask */

354
    if(atom.size <= 24)
355
        return 0; /* nothing left to read */
356

357
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
358 359 360
    return 0;
}

361
int ff_mp4_read_descr_len(ByteIOContext *pb)
362
{
363
    int len = 0;
364 365
    int count = 4;
    while (count--) {
366
        int c = get_byte(pb);
367 368 369
        len = (len << 7) | (c & 0x7f);
        if (!(c & 0x80))
            break;
370 371 372 373
    }
    return len;
}

374
int mp4_read_descr(AVFormatContext *fc, ByteIOContext *pb, int *tag)
375 376 377
{
    int len;
    *tag = get_byte(pb);
378 379
    len = ff_mp4_read_descr_len(pb);
    dprintf(fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
380 381 382
    return len;
}

383 384 385 386
#define MP4ESDescrTag                   0x03
#define MP4DecConfigDescrTag            0x04
#define MP4DecSpecificDescrTag          0x05

387
static const AVCodecTag mp4_audio_types[] = {
388 389 390 391
    { 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 */
392
    { CODEC_ID_MP4ALS, AOT_ALS  }, /* MPEG-4 ALS */
393
    { CODEC_ID_NONE,   AOT_NULL },
394 395
};

396
int ff_mov_read_esds(AVFormatContext *fc, ByteIOContext *pb, MOVAtom atom)
397
{
398
    AVStream *st;
399
    int tag, len;
400

401
    if (fc->nb_streams < 1)
402
        return 0;
403
    st = fc->streams[fc->nb_streams-1];
404

405
    get_be32(pb); /* version + flags */
406
    len = mp4_read_descr(fc, pb, &tag);
407
    if (tag == MP4ESDescrTag) {
408 409
        get_be16(pb); /* ID */
        get_byte(pb); /* priority */
410
    } else
411
        get_be16(pb); /* ID */
412

413
    len = mp4_read_descr(fc, pb, &tag);
414
    if (tag == MP4DecConfigDescrTag) {
415 416 417 418 419 420
        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 */

421
        st->codec->codec_id= ff_codec_get_id(ff_mp4_obj_type, object_type_id);
422
        dprintf(fc, "esds object type id 0x%02x\n", object_type_id);
423
        len = mp4_read_descr(fc, pb, &tag);
424
        if (tag == MP4DecSpecificDescrTag) {
425
            dprintf(fc, "Specific MPEG4 header len=%d\n", len);
B
Baptiste Coudurier 已提交
426 427
            if((uint64_t)len > (1<<30))
                return -1;
B
Baptiste Coudurier 已提交
428
            st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
429 430
            if (!st->codec->extradata)
                return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
431 432
            get_buffer(pb, st->codec->extradata, len);
            st->codec->extradata_size = len;
433 434 435 436
            if (st->codec->codec_id == CODEC_ID_AAC) {
                MPEG4AudioConfig cfg;
                ff_mpeg4audio_get_config(&cfg, st->codec->extradata,
                                         st->codec->extradata_size);
437
                st->codec->channels = cfg.channels;
438 439 440 441
                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 ?
442
                dprintf(fc, "mp4a config channels %d obj %d ext obj %d "
443 444 445
                        "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);
446 447
                if (!(st->codec->codec_id = ff_codec_get_id(mp4_audio_types,
                                                            cfg.object_type)))
448
                    st->codec->codec_id = CODEC_ID_AAC;
B
Baptiste Coudurier 已提交
449
            }
450
        }
451 452 453 454
    }
    return 0;
}

455 456 457 458 459
static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
    return ff_mov_read_esds(c->fc, pb, atom);
}

460 461 462 463
static int mov_read_pasp(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
{
    const int num = get_be32(pb);
    const int den = get_be32(pb);
464 465 466 467 468 469
    AVStream *st;

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

470
    if (den != 0) {
471 472
        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))
473
            av_log(c->fc, AV_LOG_WARNING,
474 475
                   "sample aspect ratio already set to %d:%d, overriding by 'pasp' atom\n",
                   st->sample_aspect_ratio.num, st->sample_aspect_ratio.den);
476 477 478 479 480 481
        st->sample_aspect_ratio.num = num;
        st->sample_aspect_ratio.den = den;
    }
    return 0;
}

482
/* this atom contains actual media data */
483
static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
484
{
485 486 487 488 489 490
    if(atom.size == 0) /* wrong one (MP4) */
        return 0;
    c->found_mdat=1;
    return 0; /* now go for moov */
}

491
/* read major brand, minor version and compatible brands and store them as metadata */
492
static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
493
{
494 495 496 497 498 499 500
    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 已提交
501
    if (strcmp(type, "qt  "))
502
        c->isom = 1;
503
    av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519
    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);

520 521 522
    return 0;
}

523
/* this atom should contain all header atoms */
524
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
525
{
526 527
    if (mov_read_default(c, pb, atom) < 0)
        return -1;
528 529 530 531 532 533
    /* 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 */
}

534
static int mov_read_moof(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
535 536 537 538 539
{
    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);
}
540

541
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
542
{
543 544 545
    AVStream *st;
    MOVStreamContext *sc;
    int version;
546
    char language[4] = {0};
547
    unsigned lang;
548

549 550 551 552 553 554
    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);
555
    if (version > 1)
B
Baptiste Coudurier 已提交
556
        return -1; /* unsupported */
557

558
    get_be24(pb); /* flags */
B
clean  
Baptiste Coudurier 已提交
559 560 561 562 563 564 565
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
566

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

570
    lang = get_be16(pb); /* language */
571 572
    if (ff_mov_lang_to_iso639(lang, language))
        av_metadata_set(&st->metadata, "language", language);
573 574 575 576 577
    get_be16(pb); /* quality */

    return 0;
}

578
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
579
{
B
Baptiste Coudurier 已提交
580
    int version = get_byte(pb); /* version */
581
    get_be24(pb); /* flags */
582

B
Baptiste Coudurier 已提交
583 584 585 586 587 588 589
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
590
    c->time_scale = get_be32(pb); /* time scale */
591 592 593

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

B
Baptiste Coudurier 已提交
594
    c->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613
    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;
}

614
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
615
{
616 617 618 619 620
    AVStream *st;

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

622 623
    if((uint64_t)atom.size > (1<<30))
        return -1;
624

625 626
    // currently SVQ3 decoder expect full STSD header - so let's fake it
    // this should be fixed and just SMI header should be passed
627
    av_free(st->codec->extradata);
628 629 630
    st->codec->extradata = av_mallocz(atom.size + 0x5a + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
631 632 633 634
    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);
635 636
    return 0;
}
637

638
static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
639
{
640 641 642 643 644 645
    AVStream *st;
    int little_endian;

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

647
    little_endian = get_be16(pb);
648 649
    dprintf(c->fc, "enda %d\n", little_endian);
    if (little_endian == 1) {
650 651 652 653 654 655 656
        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;
657 658 659 660 661 662
        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;
663 664 665 666 667 668 669
        default:
            break;
        }
    }
    return 0;
}

670
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
671
static int mov_read_extradata(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
672
{
673 674
    AVStream *st;
    uint64_t size;
675
    uint8_t *buf;
676 677 678 679 680

    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;
681
    if(size > INT_MAX || (uint64_t)atom.size > INT_MAX)
682
        return -1;
683 684 685 686 687 688 689 690 691
    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);
692 693 694
    return 0;
}

695
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
R
Roberto Togni 已提交
696
{
697 698 699 700 701
    AVStream *st;

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

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

706 707 708
    if (st->codec->codec_id == CODEC_ID_QDM2) {
        // pass all frma atom to codec, needed at least for QDM2
        av_free(st->codec->extradata);
709 710 711
        st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
        if (!st->codec->extradata)
            return AVERROR(ENOMEM);
712
        st->codec->extradata_size = atom.size;
713
        get_buffer(pb, st->codec->extradata, atom.size);
714
    } else if (atom.size > 8) { /* to read frma, esds atoms */
715 716
        if (mov_read_default(c, pb, atom) < 0)
            return -1;
717
    } else
718
        url_fskip(pb, atom.size);
R
Roberto Togni 已提交
719 720 721
    return 0;
}

722 723 724 725
/**
 * This function reads atom content and puts data in extradata without tag
 * nor size unlike mov_read_extradata.
 */
726
static int mov_read_glbl(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
727
{
728 729 730 731 732
    AVStream *st;

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

734 735 736
    if((uint64_t)atom.size > (1<<30))
        return -1;

737
    av_free(st->codec->extradata);
738 739 740
    st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
    if (!st->codec->extradata)
        return AVERROR(ENOMEM);
741
    st->codec->extradata_size = atom.size;
742
    get_buffer(pb, st->codec->extradata, atom.size);
743 744 745
    return 0;
}

746
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
747
{
748 749
    AVStream *st;
    MOVStreamContext *sc;
750
    unsigned int i, entries;
751

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

757
    get_byte(pb); /* version */
758
    get_be24(pb); /* flags */
759 760

    entries = get_be32(pb);
761

762 763
    if(entries >= UINT_MAX/sizeof(int64_t))
        return -1;
764

B
Baptiste Coudurier 已提交
765
    sc->chunk_offsets = av_malloc(entries * sizeof(int64_t));
766
    if (!sc->chunk_offsets)
767 768 769
        return AVERROR(ENOMEM);
    sc->chunk_count = entries;

770 771
    if      (atom.type == MKTAG('s','t','c','o'))
        for(i=0; i<entries; i++)
772
            sc->chunk_offsets[i] = get_be32(pb);
773 774
    else if (atom.type == MKTAG('c','o','6','4'))
        for(i=0; i<entries; i++)
775
            sc->chunk_offsets[i] = get_be64(pb);
776
    else
777
        return -1;
778

779 780 781
    return 0;
}

782 783 784 785
/**
 * Compute codec id for 'lpcm' tag.
 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
 */
786
enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
787 788 789 790
{
    if (flags & 1) { // floating point
        if (flags & 2) { // big endian
            if      (bps == 32) return CODEC_ID_PCM_F32BE;
791
            else if (bps == 64) return CODEC_ID_PCM_F64BE;
792
        } else {
793 794
            if      (bps == 32) return CODEC_ID_PCM_F32LE;
            else if (bps == 64) return CODEC_ID_PCM_F64LE;
795 796 797 798 799 800 801 802 803 804 805 806 807 808
        }
    } 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 已提交
809
            else if (bps == 16) return CODEC_ID_PCM_S16LE;
810 811 812 813
            else if (bps == 24) return CODEC_ID_PCM_S24LE;
            else if (bps == 32) return CODEC_ID_PCM_S32LE;
        }
    }
D
Diego Pettenò 已提交
814
    return CODEC_ID_NONE;
815 816
}

817
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
818
{
819 820
    AVStream *st;
    MOVStreamContext *sc;
821
    int j, entries, pseudo_stream_id;
822

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

828
    get_byte(pb); /* version */
829
    get_be24(pb); /* flags */
830 831 832

    entries = get_be32(pb);

833 834
    for(pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) {
        //Parsing Sample description table
835
        enum CodecID id;
836
        int dref_id = 1;
837
        MOVAtom a = { 0, 0, 0 };
838
        int64_t start_pos = url_ftell(pb);
839
        int size = get_be32(pb); /* size */
840
        uint32_t format = get_le32(pb); /* data format */
841

842 843 844 845 846
        if (size >= 16) {
            get_be32(pb); /* reserved */
            get_be16(pb); /* reserved */
            dref_id = get_be16(pb);
        }
847

848
        if (st->codec->codec_tag &&
849
            st->codec->codec_tag != format &&
850
            (c->fc->video_codec_id ? ff_codec_get_id(codec_movvideo_tags, format) != c->fc->video_codec_id
851
                                   : st->codec->codec_tag != MKTAG('j','p','e','g'))
852
           ){
D
Diego Biurrun 已提交
853 854 855
            /* 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 已提交
856
            av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
857 858 859
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
            continue;
        }
860
        sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
861
        sc->dref_id= dref_id;
862

863
        st->codec->codec_tag = format;
864
        id = ff_codec_get_id(codec_movaudio_tags, format);
865
        if (id<=0 && ((format&0xFFFF) == 'm'+('s'<<8) || (format&0xFFFF) == 'T'+('S'<<8)))
866
            id = ff_codec_get_id(ff_codec_wav_tags, bswap_32(format)&0xFFFF);
M
Michael Niedermayer 已提交
867

868
        if (st->codec->codec_type != CODEC_TYPE_VIDEO && id > 0) {
869
            st->codec->codec_type = CODEC_TYPE_AUDIO;
870
        } else if (st->codec->codec_type != CODEC_TYPE_AUDIO && /* do not overwrite codec type */
871
                   format && format != MKTAG('m','p','4','s')) { /* skip old asf mpeg4 tag */
872
            id = ff_codec_get_id(codec_movvideo_tags, format);
873
            if (id <= 0)
874
                id = ff_codec_get_id(ff_codec_bmp_tags, format);
875 876
            if (id > 0)
                st->codec->codec_type = CODEC_TYPE_VIDEO;
877
            else if(st->codec->codec_type == CODEC_TYPE_DATA){
878
                id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
879 880 881
                if(id > 0)
                    st->codec->codec_type = CODEC_TYPE_SUBTITLE;
            }
882 883
        }

884 885 886
        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);
887

888
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
889 890 891 892
            uint8_t codec_name[32];
            unsigned int color_depth;
            int color_greyscale;

893
            st->codec->codec_id = id;
894 895 896 897
            get_be16(pb); /* version */
            get_be16(pb); /* revision level */
            get_be32(pb); /* vendor */
            get_be32(pb); /* temporal quality */
D
Diego Biurrun 已提交
898
            get_be32(pb); /* spatial quality */
899 900 901 902

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

903 904 905
            get_be32(pb); /* horiz resolution */
            get_be32(pb); /* vert resolution */
            get_be32(pb); /* data size, always 0 */
B
Baptiste Coudurier 已提交
906
            get_be16(pb); /* frames per samples */
907

B
Baptiste Coudurier 已提交
908
            get_buffer(pb, codec_name, 32); /* codec name, pascal string */
B
Baptiste Coudurier 已提交
909
            if (codec_name[0] <= 31) {
910 911 912 913
                int i;
                int pos = 0;
                for (i = 0; i < codec_name[0] && pos < sizeof(st->codec->codec_name) - 3; i++) {
                    uint8_t tmp;
914
                    PUT_UTF8(codec_name[i+1], tmp, st->codec->codec_name[pos++] = tmp;)
915 916
                }
                st->codec->codec_name[pos] = 0;
B
Baptiste Coudurier 已提交
917
            }
918

919
            st->codec->bits_per_coded_sample = get_be16(pb); /* depth */
920
            st->codec->color_table_id = get_be16(pb); /* colortable id */
921
            dprintf(c->fc, "depth %d, ctab id %d\n",
922
                   st->codec->bits_per_coded_sample, st->codec->color_table_id);
923
            /* figure out the palette situation */
924 925
            color_depth = st->codec->bits_per_coded_sample & 0x1F;
            color_greyscale = st->codec->bits_per_coded_sample & 0x20;
926 927

            /* if the depth is 2, 4, or 8 bpp, file is palettized */
928
            if ((color_depth == 2) || (color_depth == 4) ||
929
                (color_depth == 8)) {
930 931 932 933
                /* for palette traversal */
                unsigned int color_start, color_count, color_end;
                unsigned char r, g, b;

934
                st->codec->palctrl = av_malloc(sizeof(*st->codec->palctrl));
935
                if (color_greyscale) {
936
                    int color_index, color_dec;
937
                    /* compute the greyscale palette */
938
                    st->codec->bits_per_coded_sample = color_depth;
939 940 941 942 943
                    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;
944
                        st->codec->palctrl->palette[j] =
945 946 947 948 949
                            (r << 16) | (g << 8) | (b);
                        color_index -= color_dec;
                        if (color_index < 0)
                            color_index = 0;
                    }
950
                } else if (st->codec->color_table_id) {
951
                    const uint8_t *color_table;
952 953 954
                    /* if flag bit 3 is set, use the default palette */
                    color_count = 1 << color_depth;
                    if (color_depth == 2)
M
Michael Niedermayer 已提交
955
                        color_table = ff_qt_default_palette_4;
956
                    else if (color_depth == 4)
M
Michael Niedermayer 已提交
957
                        color_table = ff_qt_default_palette_16;
958
                    else
M
Michael Niedermayer 已提交
959
                        color_table = ff_qt_default_palette_256;
960 961

                    for (j = 0; j < color_count; j++) {
962 963 964
                        r = color_table[j * 3 + 0];
                        g = color_table[j * 3 + 1];
                        b = color_table[j * 3 + 2];
965
                        st->codec->palctrl->palette[j] =
966 967 968 969 970 971 972
                            (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);
973 974
                    if ((color_start <= 255) &&
                        (color_end <= 255)) {
M
Mike Melanson 已提交
975 976 977 978 979 980 981 982 983 984 985 986
                        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);
987
                            st->codec->palctrl->palette[j] =
M
Mike Melanson 已提交
988
                                (r << 16) | (g << 8) | (b);
989
                        }
990 991
                    }
                }
992
                st->codec->palctrl->palette_changed = 1;
993
            }
994
        } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
995
            int bits_per_sample, flags;
996
            uint16_t version = get_be16(pb);
997

998
            st->codec->codec_id = id;
999 1000
            get_be16(pb); /* revision level */
            get_be32(pb); /* vendor */
1001

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

1006
            sc->audio_cid = get_be16(pb);
1007 1008 1009 1010
            get_be16(pb); /* packet size = 0 */

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

1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023
            //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 */
1024
                    st->codec->bits_per_coded_sample = get_be32(pb); /* bits per channel if sound is uncompressed */
1025
                    flags = get_be32(pb); /* lcpm format specific flag */
B
Baptiste Coudurier 已提交
1026 1027
                    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 */
1028
                    if (format == MKTAG('l','p','c','m'))
1029
                        st->codec->codec_id = ff_mov_get_lpcm_codec_id(st->codec->bits_per_coded_sample, flags);
1030 1031 1032
                }
            }

1033
            switch (st->codec->codec_id) {
1034 1035
            case CODEC_ID_PCM_S8:
            case CODEC_ID_PCM_U8:
1036
                if (st->codec->bits_per_coded_sample == 16)
1037 1038
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
                break;
1039
            case CODEC_ID_PCM_S16LE:
1040
            case CODEC_ID_PCM_S16BE:
1041
                if (st->codec->bits_per_coded_sample == 8)
1042
                    st->codec->codec_id = CODEC_ID_PCM_S8;
1043
                else if (st->codec->bits_per_coded_sample == 24)
1044 1045 1046
                    st->codec->codec_id =
                        st->codec->codec_id == CODEC_ID_PCM_S16BE ?
                        CODEC_ID_PCM_S24BE : CODEC_ID_PCM_S24LE;
1047
                break;
1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060
            /* 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;
1061 1062 1063 1064
            case CODEC_ID_GSM:
                sc->samples_per_frame = 160;
                sc->bytes_per_frame = 33;
                break;
1065 1066
            default:
                break;
1067
            }
1068

1069 1070
            bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
            if (bits_per_sample) {
1071
                st->codec->bits_per_coded_sample = bits_per_sample;
1072 1073
                sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
            }
1074
        } else if(st->codec->codec_type==CODEC_TYPE_SUBTITLE){
1075 1076 1077
            // 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) };
1078
            if (format != AV_RL32("mp4s")) // mp4s contains a regular esds atom
R
Reimar Döffinger 已提交
1079
                mov_read_glbl(c, pb, fake_atom);
1080
            st->codec->codec_id= id;
1081 1082
            st->codec->width = sc->width;
            st->codec->height = sc->height;
1083 1084 1085
        } else {
            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
1086
        }
1087 1088
        /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
        a.size = size - (url_ftell(pb) - start_pos);
1089 1090 1091 1092
        if (a.size > 8) {
            if (mov_read_default(c, pb, a) < 0)
                return -1;
        } else if (a.size > 0)
1093
            url_fskip(pb, a.size);
1094
    }
1095

B
Baptiste Coudurier 已提交
1096
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
1097
        st->codec->sample_rate= sc->time_scale;
1098

1099
    /* special codec parameters handling */
1100
    switch (st->codec->codec_id) {
1101
#if CONFIG_DV_DEMUXER
1102
    case CODEC_ID_DVAUDIO:
1103
        c->dv_fctx = avformat_alloc_context();
1104 1105 1106 1107 1108 1109 1110 1111
        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;
1112
#endif
1113
    /* no ifdef since parameters are always those */
1114
    case CODEC_ID_QCELP:
1115 1116 1117
        // 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;
1118
        st->codec->frame_size= 160;
1119
        st->codec->channels= 1; /* really needed */
1120
        break;
1121
    case CODEC_ID_AMR_NB:
1122
    case CODEC_ID_AMR_WB:
B
Baptiste Coudurier 已提交
1123
        st->codec->frame_size= sc->samples_per_frame;
1124
        st->codec->channels= 1; /* really needed */
1125
        /* force sample rate for amr, stsd in 3gp does not store sample rate */
B
Baptiste Coudurier 已提交
1126
        if (st->codec->codec_id == CODEC_ID_AMR_NB)
1127
            st->codec->sample_rate = 8000;
B
Baptiste Coudurier 已提交
1128 1129
        else if (st->codec->codec_id == CODEC_ID_AMR_WB)
            st->codec->sample_rate = 16000;
1130
        break;
1131
    case CODEC_ID_MP2:
1132
    case CODEC_ID_MP3:
1133
        st->codec->codec_type = CODEC_TYPE_AUDIO; /* force type after stsd for m1a hdlr */
A
Aurelien Jacobs 已提交
1134
        st->need_parsing = AVSTREAM_PARSE_FULL;
1135
        break;
1136
    case CODEC_ID_GSM:
1137 1138 1139 1140
    case CODEC_ID_ADPCM_MS:
    case CODEC_ID_ADPCM_IMA_WAV:
        st->codec->block_align = sc->bytes_per_frame;
        break;
1141
    case CODEC_ID_ALAC:
1142
        if (st->codec->extradata_size == 36) {
1143 1144
            st->codec->frame_size = AV_RB32(st->codec->extradata+12);
            st->codec->channels   = AV_RB8 (st->codec->extradata+21);
1145
        }
1146
        break;
1147 1148 1149
    default:
        break;
    }
1150

1151 1152 1153
    return 0;
}

1154
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1155
{
1156 1157
    AVStream *st;
    MOVStreamContext *sc;
1158
    unsigned int i, entries;
1159

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

1165
    get_byte(pb); /* version */
1166
    get_be24(pb); /* flags */
1167 1168

    entries = get_be32(pb);
1169

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

1172 1173
    if(entries >= UINT_MAX / sizeof(*sc->stsc_data))
        return -1;
1174 1175
    sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data));
    if (!sc->stsc_data)
1176 1177 1178
        return AVERROR(ENOMEM);
    sc->stsc_count = entries;

1179
    for(i=0; i<entries; i++) {
1180 1181 1182
        sc->stsc_data[i].first = get_be32(pb);
        sc->stsc_data[i].count = get_be32(pb);
        sc->stsc_data[i].id = get_be32(pb);
1183 1184 1185 1186
    }
    return 0;
}

1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215
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;
}

1216
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1217
{
1218 1219
    AVStream *st;
    MOVStreamContext *sc;
1220
    unsigned int i, entries;
1221

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

1227
    get_byte(pb); /* version */
1228
    get_be24(pb); /* flags */
1229 1230

    entries = get_be32(pb);
1231

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

B
Baptiste Coudurier 已提交
1234
    if(entries >= UINT_MAX / sizeof(int))
1235
        return -1;
B
Baptiste Coudurier 已提交
1236
    sc->keyframes = av_malloc(entries * sizeof(int));
1237
    if (!sc->keyframes)
1238 1239 1240
        return AVERROR(ENOMEM);
    sc->keyframe_count = entries;

1241 1242
    for(i=0; i<entries; i++) {
        sc->keyframes[i] = get_be32(pb);
1243
        //dprintf(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
1244 1245 1246 1247
    }
    return 0;
}

1248
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1249
{
1250 1251
    AVStream *st;
    MOVStreamContext *sc;
1252 1253 1254
    unsigned int i, entries, sample_size, field_size, num_bytes;
    GetBitContext gb;
    unsigned char* buf;
1255

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

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

1264
    if (atom.type == MKTAG('s','t','s','z')) {
1265 1266 1267 1268
        sample_size = get_be32(pb);
        if (!sc->sample_size) /* do not overwrite value computed in stsd */
            sc->sample_size = sample_size;
        field_size = 32;
1269 1270 1271 1272 1273
    } else {
        sample_size = 0;
        get_be24(pb); /* reserved */
        field_size = get_byte(pb);
    }
1274
    entries = get_be32(pb);
1275 1276

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

1278
    sc->sample_count = entries;
1279 1280 1281
    if (sample_size)
        return 0;

1282 1283 1284 1285 1286
    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;
    }

1287
    if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size)
1288
        return -1;
B
Baptiste Coudurier 已提交
1289
    sc->sample_sizes = av_malloc(entries * sizeof(int));
1290
    if (!sc->sample_sizes)
1291 1292
        return AVERROR(ENOMEM);

1293 1294
    num_bytes = (entries*field_size+4)>>3;

1295
    buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE);
1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308
    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);

1309
    for(i=0; i<entries; i++)
1310 1311 1312
        sc->sample_sizes[i] = get_bits_long(&gb, field_size);

    av_free(buf);
1313 1314 1315
    return 0;
}

1316
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1317
{
1318 1319
    AVStream *st;
    MOVStreamContext *sc;
1320
    unsigned int i, entries;
1321 1322
    int64_t duration=0;
    int64_t total_sample_count=0;
1323

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

1329
    get_byte(pb); /* version */
1330
    get_be24(pb); /* flags */
1331
    entries = get_be32(pb);
1332 1333 1334

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

1335
    if(entries >= UINT_MAX / sizeof(*sc->stts_data))
1336
        return -1;
1337
    sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data));
1338
    if (!sc->stts_data)
1339 1340
        return AVERROR(ENOMEM);
    sc->stts_count = entries;
1341

1342
    for(i=0; i<entries; i++) {
M
cleanup  
Michael Niedermayer 已提交
1343 1344
        int sample_duration;
        int sample_count;
1345

1346
        sample_count=get_be32(pb);
1347
        sample_duration = get_be32(pb);
1348 1349 1350
        sc->stts_data[i].count= sample_count;
        sc->stts_data[i].duration= sample_duration;

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

B
Baptiste Coudurier 已提交
1353
        duration+=(int64_t)sample_duration*sample_count;
1354 1355 1356
        total_sample_count+=sample_count;
    }

1357 1358 1359
    st->nb_frames= total_sample_count;
    if(duration)
        st->duration= duration;
1360 1361 1362
    return 0;
}

1363
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
M
Michael Niedermayer 已提交
1364
{
1365 1366
    AVStream *st;
    MOVStreamContext *sc;
M
Michael Niedermayer 已提交
1367 1368
    unsigned int i, entries;

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

M
Michael Niedermayer 已提交
1374
    get_byte(pb); /* version */
1375
    get_be24(pb); /* flags */
M
Michael Niedermayer 已提交
1376
    entries = get_be32(pb);
1377 1378 1379

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

1380
    if(entries >= UINT_MAX / sizeof(*sc->ctts_data))
M
Michael Niedermayer 已提交
1381
        return -1;
1382
    sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
1383
    if (!sc->ctts_data)
1384 1385
        return AVERROR(ENOMEM);
    sc->ctts_count = entries;
1386

M
Michael Niedermayer 已提交
1387
    for(i=0; i<entries; i++) {
1388 1389 1390 1391 1392
        int count    =get_be32(pb);
        int duration =get_be32(pb);

        sc->ctts_data[i].count   = count;
        sc->ctts_data[i].duration= duration;
1393 1394
        if (duration < 0)
            sc->dts_shift = FFMAX(sc->dts_shift, -duration);
M
Michael Niedermayer 已提交
1395
    }
1396

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

M
Michael Niedermayer 已提交
1399 1400 1401
    return 0;
}

1402 1403 1404
static void mov_build_index(MOVContext *mov, AVStream *st)
{
    MOVStreamContext *sc = st->priv_data;
1405
    int64_t current_offset;
1406 1407 1408 1409
    int64_t current_dts = 0;
    unsigned int stts_index = 0;
    unsigned int stsc_index = 0;
    unsigned int stss_index = 0;
1410
    unsigned int stps_index = 0;
1411
    unsigned int i, j;
1412
    uint64_t stream_size = 0;
1413

1414 1415
    /* adjust first dts according to edit list */
    if (sc->time_offset) {
1416
        int rescaled = sc->time_offset < 0 ? av_rescale(sc->time_offset, sc->time_scale, mov->time_scale) : sc->time_offset;
1417
        current_dts = -rescaled;
1418 1419 1420 1421 1422 1423
        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;
        }
1424 1425
    }

1426 1427 1428
    /* 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)) {
1429 1430
        unsigned int current_sample = 0;
        unsigned int stts_sample = 0;
1431
        unsigned int sample_size;
1432 1433 1434
        unsigned int distance = 0;
        int key_off = sc->keyframes && sc->keyframes[0] == 1;

1435 1436
        current_dts -= sc->dts_shift;

1437 1438
        for (i = 0; i < sc->chunk_count; i++) {
            current_offset = sc->chunk_offsets[i];
1439 1440
            if (stsc_index + 1 < sc->stsc_count &&
                i + 1 == sc->stsc_data[stsc_index + 1].first)
1441
                stsc_index++;
1442
            for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
1443
                int keyframe = 0;
1444 1445
                if (current_sample >= sc->sample_count) {
                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
1446
                    return;
1447
                }
1448 1449 1450

                if (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index]) {
                    keyframe = 1;
1451 1452
                    if (stss_index + 1 < sc->keyframe_count)
                        stss_index++;
1453 1454 1455 1456
                } 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++;
1457
                }
1458 1459
                if (keyframe)
                    distance = 0;
1460
                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
1461
                if(sc->pseudo_stream_id == -1 ||
1462
                   sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
1463 1464
                    av_add_index_entry(st, current_offset, current_dts, sample_size, distance,
                                    keyframe ? AVINDEX_KEYFRAME : 0);
1465 1466 1467 1468
                    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);
                }
1469

1470
                current_offset += sample_size;
1471
                stream_size += sample_size;
1472
                current_dts += sc->stts_data[stts_index].duration;
1473 1474 1475 1476 1477 1478 1479 1480 1481
                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++;
                }
            }
        }
1482 1483
        if (st->duration > 0)
            st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;
1484
    } else {
1485
        for (i = 0; i < sc->chunk_count; i++) {
1486 1487
            unsigned chunk_samples;

1488
            current_offset = sc->chunk_offsets[i];
1489 1490
            if (stsc_index + 1 < sc->stsc_count &&
                i + 1 == sc->stsc_data[stsc_index + 1].first)
1491
                stsc_index++;
1492
            chunk_samples = sc->stsc_data[stsc_index].count;
1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509

            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;
1510
                    } else {
1511 1512
                        samples = FFMIN(1024, chunk_samples);
                        size = samples * sc->sample_size;
1513 1514
                    }
                }
1515 1516

                av_add_index_entry(st, current_offset, current_dts, size, 0, AVINDEX_KEYFRAME);
1517 1518
                dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "
                        "size %d, duration %d\n", st->index, i, current_offset, current_dts,
1519 1520 1521
                        size, samples);

                current_offset += size;
1522
                current_dts += samples;
1523
                chunk_samples -= samples;
1524 1525 1526 1527
            }
        }
    }
}
1528

1529
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1530 1531 1532
{
    AVStream *st;
    MOVStreamContext *sc;
1533
    int ret;
1534 1535

    st = av_new_stream(c->fc, c->fc->nb_streams);
B
Baptiste Coudurier 已提交
1536
    if (!st) return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
1537
    sc = av_mallocz(sizeof(MOVStreamContext));
1538
    if (!sc) return AVERROR(ENOMEM);
1539 1540

    st->priv_data = sc;
1541
    st->codec->codec_type = CODEC_TYPE_DATA;
1542
    sc->ffindex = st->index;
1543

1544 1545 1546 1547
    if ((ret = mov_read_default(c, pb, atom)) < 0)
        return ret;

    /* sanity checks */
1548 1549
    if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
                            (!sc->sample_size && !sc->sample_count))) {
1550 1551
        av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
               st->index);
1552 1553
        return 0;
    }
1554

1555 1556
    if (!sc->time_scale) {
        av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", st->index);
1557
        sc->time_scale = c->time_scale;
1558 1559 1560
        if (!sc->time_scale)
            sc->time_scale = 1;
    }
1561

1562
    av_set_pts_info(st, 64, 1, sc->time_scale);
1563

1564
    if (st->codec->codec_type == CODEC_TYPE_AUDIO &&
1565 1566 1567 1568 1569
        !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);
    }
1570 1571 1572 1573 1574

    mov_build_index(c, st);

    if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
        if (url_fopen(&sc->pb, sc->drefs[sc->dref_id-1].path, URL_RDONLY) < 0)
1575 1576
            av_log(c->fc, AV_LOG_ERROR, "stream %d, error opening file %s: %s\n",
                   st->index, sc->drefs[sc->dref_id-1].path, strerror(errno));
1577 1578 1579 1580
    } else
        sc->pb = c->fc->pb;

    switch (st->codec->codec_id) {
1581
#if CONFIG_H261_DECODER
1582 1583
    case CODEC_ID_H261:
#endif
1584
#if CONFIG_H263_DECODER
1585 1586
    case CODEC_ID_H263:
#endif
1587 1588 1589
#if CONFIG_H264_DECODER
    case CODEC_ID_H264:
#endif
1590
#if CONFIG_MPEG4_DECODER
1591 1592
    case CODEC_ID_MPEG4:
#endif
1593
        st->codec->width = 0; /* let decoder init width/height */
1594 1595 1596
        st->codec->height= 0;
        break;
    }
B
Baptiste Coudurier 已提交
1597 1598 1599

    /* Do not need those anymore. */
    av_freep(&sc->chunk_offsets);
1600
    av_freep(&sc->stsc_data);
B
Baptiste Coudurier 已提交
1601 1602 1603
    av_freep(&sc->sample_sizes);
    av_freep(&sc->keyframes);
    av_freep(&sc->stts_data);
1604
    av_freep(&sc->stps_data);
B
Baptiste Coudurier 已提交
1605

1606
    return 0;
1607 1608
}

1609
static int mov_read_ilst(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1610 1611 1612 1613 1614 1615 1616 1617
{
    int ret;
    c->itunes_metadata = 1;
    ret = mov_read_default(c, pb, atom);
    c->itunes_metadata = 0;
    return ret;
}

1618
static int mov_read_meta(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1619
{
1620 1621 1622 1623 1624 1625 1626 1627 1628 1629
    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;
1630 1631
}

1632
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1633
{
1634 1635 1636 1637 1638
    int i;
    int width;
    int height;
    int64_t disp_transform[2];
    int display_matrix[3][2];
1639 1640 1641 1642 1643 1644 1645 1646
    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;
1647

1648
    version = get_byte(pb);
1649
    get_be24(pb); /* flags */
1650 1651 1652 1653 1654 1655 1656
    /*
    MOV_TRACK_ENABLED 0x0001
    MOV_TRACK_IN_MOVIE 0x0002
    MOV_TRACK_IN_PREVIEW 0x0004
    MOV_TRACK_IN_POSTER 0x0008
    */

B
Baptiste Coudurier 已提交
1657 1658 1659 1660 1661 1662 1663
    if (version == 1) {
        get_be64(pb);
        get_be64(pb);
    } else {
        get_be32(pb); /* creation time */
        get_be32(pb); /* modification time */
    }
1664 1665
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
    get_be32(pb); /* reserved */
1666

1667 1668
    /* highlevel (considering edits) duration in movie timebase */
    (version == 1) ? get_be64(pb) : get_be32(pb);
1669 1670 1671 1672 1673 1674 1675 1676
    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 */

1677 1678 1679 1680 1681 1682 1683 1684
    //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)
    }
1685

1686 1687
    width = get_be32(pb);       // 16.16 fixed point track width
    height = get_be32(pb);      // 16.16 fixed point track height
1688 1689
    sc->width = width >> 16;
    sc->height = height >> 16;
1690

1691
    // transform the display width/height according to the matrix
1692
    // skip this if the display matrix is the default identity matrix
1693
    // or if it is rotating the picture, ex iPhone 3GS
1694 1695
    // to keep the same scale, use [width height 1<<16]
    if (width && height &&
1696 1697 1698 1699 1700
        ((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])) {
1701 1702 1703 1704 1705 1706 1707
        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
1708
        st->sample_aspect_ratio = av_d2q(
1709 1710 1711
            ((double) disp_transform[0] * height) /
            ((double) disp_transform[1] * width), INT_MAX);
    }
1712 1713 1714
    return 0;
}

1715
static int mov_read_tfhd(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1716 1717 1718 1719 1720 1721 1722 1723 1724
{
    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);
1725
    if (!track_id)
B
Baptiste Coudurier 已提交
1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749
        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;
}

1750
static int mov_read_trex(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1751 1752 1753 1754 1755
{
    MOVTrackExt *trex;

    if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
        return -1;
1756 1757
    trex = av_realloc(c->trex_data, (c->trex_count+1)*sizeof(*c->trex_data));
    if (!trex)
B
Baptiste Coudurier 已提交
1758
        return AVERROR(ENOMEM);
1759
    c->trex_data = trex;
B
Baptiste Coudurier 已提交
1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770
    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;
}

1771
static int mov_read_trun(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
1772 1773
{
    MOVFragment *frag = &c->fragment;
1774
    AVStream *st = NULL;
1775
    MOVStreamContext *sc;
B
Baptiste Coudurier 已提交
1776 1777 1778 1779 1780 1781
    uint64_t offset;
    int64_t dts;
    int data_offset = 0;
    unsigned entries, first_sample_flags = frag->flags;
    int flags, distance, i;

1782 1783 1784 1785 1786 1787 1788 1789
    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);
1790
        return -1;
1791
    }
1792
    sc = st->priv_data;
B
Baptiste Coudurier 已提交
1793 1794 1795 1796 1797 1798 1799 1800 1801
    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) {
1802
        MOVStts *ctts_data;
B
Baptiste Coudurier 已提交
1803 1804
        if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
            return -1;
1805 1806 1807
        ctts_data = av_realloc(sc->ctts_data,
                               (entries+sc->ctts_count)*sizeof(*sc->ctts_data));
        if (!ctts_data)
B
Baptiste Coudurier 已提交
1808
            return AVERROR(ENOMEM);
1809
        sc->ctts_data = ctts_data;
B
Baptiste Coudurier 已提交
1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837
    }
    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++;
1838
        dts += sample_duration;
B
Baptiste Coudurier 已提交
1839 1840 1841 1842 1843 1844 1845
        offset += sample_size;
    }
    frag->moof_offset = offset;
    st->duration = dts;
    return 0;
}

1846 1847 1848
/* 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/ */
1849
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1850 1851 1852 1853 1854 1855 1856 1857 1858 1859 1860 1861
{
    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;
1862
    if (atom.type != MKTAG('m','d','a','t')) {
1863 1864 1865 1866 1867 1868 1869
        url_fskip(pb, atom.size);
        return 0;
    }
    err = mov_read_mdat(c, pb, atom);
    return err;
}

1870
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
1871
{
1872
#if CONFIG_ZLIB
1873
    ByteIOContext ctx;
1874 1875
    uint8_t *cmov_data;
    uint8_t *moov_data; /* uncompressed data */
1876
    long cmov_len, moov_len;
1877
    int ret = -1;
1878

1879
    get_be32(pb); /* dcom atom */
1880
    if (get_le32(pb) != MKTAG('d','c','o','m'))
1881
        return -1;
1882
    if (get_le32(pb) != MKTAG('z','l','i','b')) {
B
Benoit Fouet 已提交
1883
        av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !");
1884 1885 1886
        return -1;
    }
    get_be32(pb); /* cmvd atom */
1887
    if (get_le32(pb) != MKTAG('c','m','v','d'))
1888 1889
        return -1;
    moov_len = get_be32(pb); /* uncompressed size */
1890
    cmov_len = atom.size - 6 * 4;
1891

B
Baptiste Coudurier 已提交
1892
    cmov_data = av_malloc(cmov_len);
1893
    if (!cmov_data)
1894
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
1895
    moov_data = av_malloc(moov_len);
1896 1897
    if (!moov_data) {
        av_free(cmov_data);
1898
        return AVERROR(ENOMEM);
1899 1900
    }
    get_buffer(pb, cmov_data, cmov_len);
1901
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1902
        goto free_and_return;
1903
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
1904
        goto free_and_return;
1905
    atom.type = MKTAG('m','o','o','v');
1906 1907
    atom.offset = 0;
    atom.size = moov_len;
1908
#ifdef DEBUG
M
Michael Niedermayer 已提交
1909
//    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1910
#endif
1911
    ret = mov_read_default(c, &ctx, atom);
1912
free_and_return:
1913 1914 1915
    av_free(moov_data);
    av_free(cmov_data);
    return ret;
1916 1917 1918
#else
    av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
    return -1;
1919
#endif
1920
}
1921

G
Gael Chardon 已提交
1922
/* edit list atom */
1923
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOVAtom atom)
G
Gael Chardon 已提交
1924
{
1925
    MOVStreamContext *sc;
B
Baptiste Coudurier 已提交
1926 1927
    int i, edit_count;

1928 1929 1930 1931
    if (c->fc->nb_streams < 1)
        return 0;
    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;

B
Baptiste Coudurier 已提交
1932
    get_byte(pb); /* version */
1933
    get_be24(pb); /* flags */
B
Baptiste Coudurier 已提交
1934
    edit_count = get_be32(pb); /* entries */
B
Baptiste Coudurier 已提交
1935

1936 1937 1938
    if((uint64_t)edit_count*12+8 > atom.size)
        return -1;

B
Baptiste Coudurier 已提交
1939
    for(i=0; i<edit_count; i++){
1940
        int time;
1941
        int duration = get_be32(pb); /* Track duration */
1942
        time = get_be32(pb); /* Media time */
B
Baptiste Coudurier 已提交
1943
        get_be32(pb); /* Media rate */
1944 1945
        if (i == 0 && time >= -1) {
            sc->time_offset = time != -1 ? time : -duration;
1946
        }
B
Baptiste Coudurier 已提交
1947
    }
1948 1949 1950 1951 1952

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

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

1957
static const MOVParseTableEntry mov_default_parse_table[] = {
1958
{ MKTAG('a','v','s','s'), mov_read_extradata },
1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969
{ 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 },
1970
{ MKTAG('i','l','s','t'), mov_read_ilst },
1971 1972 1973 1974
{ 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 },
1975
{ MKTAG('m','e','t','a'), mov_read_meta },
1976 1977 1978 1979 1980 1981 1982 1983
{ 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 },
1984
{ MKTAG('p','a','s','p'), mov_read_pasp },
1985 1986
{ MKTAG('s','t','b','l'), mov_read_default },
{ MKTAG('s','t','c','o'), mov_read_stco },
1987
{ MKTAG('s','t','p','s'), mov_read_stps },
1988 1989 1990 1991 1992
{ 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 },
1993
{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
1994 1995 1996 1997 1998 1999
{ 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 已提交
2000
{ MKTAG('u','d','t','a'), mov_read_default },
2001 2002 2003 2004
{ 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 已提交
2005
{ 0, NULL }
2006 2007
};

F
Fabrice Bellard 已提交
2008 2009
static int mov_probe(AVProbeData *p)
{
2010 2011
    unsigned int offset;
    uint32_t tag;
2012
    int score = 0;
2013

F
Fabrice Bellard 已提交
2014
    /* check file header */
2015 2016 2017 2018
    offset = 0;
    for(;;) {
        /* ignore invalid offset */
        if ((offset + 8) > (unsigned int)p->buf_size)
2019
            return score;
2020
        tag = AV_RL32(p->buf + offset + 4);
2021
        switch(tag) {
2022
        /* check for obvious tags */
2023 2024 2025 2026 2027
        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 */
2028
        case MKTAG('f','t','y','p'):
2029
            return AVPROBE_SCORE_MAX;
2030
        /* those are more common words, so rate then a bit less */
2031 2032 2033 2034 2035
        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'):
2036
            return AVPROBE_SCORE_MAX - 5;
B
Baptiste Coudurier 已提交
2037
        case MKTAG(0x82,0x82,0x7f,0x7d):
2038 2039 2040
        case MKTAG('s','k','i','p'):
        case MKTAG('u','u','i','d'):
        case MKTAG('p','r','f','l'):
2041
            offset = AV_RB32(p->buf+offset) + offset;
2042 2043
            /* if we only find those cause probedata is too small at least rate them */
            score = AVPROBE_SCORE_MAX - 50;
2044 2045 2046
            break;
        default:
            /* unrecognized tag */
2047
            return score;
2048
        }
2049
    }
2050
    return score;
F
Fabrice Bellard 已提交
2051 2052
}

Z
Zdenek Kabelac 已提交
2053
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
2054
{
2055
    MOVContext *mov = s->priv_data;
2056
    ByteIOContext *pb = s->pb;
B
Baptiste Coudurier 已提交
2057
    int err;
2058
    MOVAtom atom = { 0, 0, 0 };
2059 2060

    mov->fc = s;
2061 2062
    /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
    if(!url_is_streamed(pb))
2063
        atom.size = url_fsize(pb);
2064
    else
B
Baptiste Coudurier 已提交
2065
        atom.size = INT64_MAX;
2066 2067

    /* check MOV header */
B
Baptiste Coudurier 已提交
2068 2069 2070 2071 2072 2073
    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");
2074
        return -1;
2075
    }
B
Baptiste Coudurier 已提交
2076
    dprintf(mov->fc, "on_parse_exit_offset=%lld\n", url_ftell(pb));
2077

2078 2079 2080
    return 0;
}

2081
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
2082
{
2083
    AVIndexEntry *sample = NULL;
2084
    int64_t best_dts = INT64_MAX;
2085
    int i;
B
Baptiste Coudurier 已提交
2086
    for (i = 0; i < s->nb_streams; i++) {
2087 2088
        AVStream *avst = s->streams[i];
        MOVStreamContext *msc = avst->priv_data;
2089
        if (msc->pb && msc->current_sample < avst->nb_index_entries) {
2090
            AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
2091
            int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
B
Baptiste Coudurier 已提交
2092
            dprintf(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
B
Baptiste Coudurier 已提交
2093 2094
            if (!sample || (url_is_streamed(s->pb) && current_sample->pos < sample->pos) ||
                (!url_is_streamed(s->pb) &&
2095
                 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
B
Baptiste Coudurier 已提交
2096
                 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
2097
                  (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
2098 2099
                sample = current_sample;
                best_dts = dts;
2100
                *st = avst;
2101
            }
2102 2103
        }
    }
2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115
    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);
2116 2117 2118
    if (!sample) {
        mov->found_mdat = 0;
        if (!url_is_streamed(s->pb) ||
2119
            mov_read_default(mov, s->pb, (MOVAtom){ 0, 0, INT64_MAX }) < 0 ||
2120
            url_feof(s->pb))
B
Baptiste Coudurier 已提交
2121
            return AVERROR_EOF;
2122 2123 2124
        dprintf(s, "read fragments, offset 0x%llx\n", url_ftell(s->pb));
        goto retry;
    }
2125
    sc = st->priv_data;
2126 2127
    /* must be done just before reading, to avoid infinite loop on sample */
    sc->current_sample++;
2128 2129

    if (st->discard != AVDISCARD_ALL) {
R
Reimar Döffinger 已提交
2130 2131 2132 2133 2134 2135
        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);
2136 2137
        if (ret < 0)
            return ret;
R
Reimar Döffinger 已提交
2138 2139 2140 2141 2142 2143 2144 2145 2146
#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;
        }
2147
#endif
2148 2149
    }

2150 2151 2152
    pkt->stream_index = sc->ffindex;
    pkt->dts = sample->timestamp;
    if (sc->ctts_data) {
2153
        pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
2154
        /* update ctts context */
2155 2156 2157 2158 2159
        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;
2160
        }
2161 2162
        if (sc->wrong_dts)
            pkt->dts = AV_NOPTS_VALUE;
2163
    } else {
2164
        int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
2165 2166
            st->index_entries[sc->current_sample].timestamp : st->duration;
        pkt->duration = next_dts - pkt->dts;
2167
        pkt->pts = pkt->dts;
2168
    }
2169 2170
    if (st->discard == AVDISCARD_ALL)
        goto retry;
2171 2172
    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? PKT_FLAG_KEY : 0;
    pkt->pos = sample->pos;
2173 2174
    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);
2175 2176
    return 0;
}
2177

2178 2179 2180 2181 2182
static int mov_seek_stream(AVStream *st, int64_t timestamp, int flags)
{
    MOVStreamContext *sc = st->priv_data;
    int sample, time_sample;
    int i;
2183

2184
    sample = av_index_search_timestamp(st, timestamp, flags);
M
Michel Bardiaux 已提交
2185
    dprintf(st->codec, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
2186 2187 2188
    if (sample < 0) /* not sure what to do */
        return -1;
    sc->current_sample = sample;
B
Baptiste Coudurier 已提交
2189
    dprintf(st->codec, "stream %d, found sample %d\n", st->index, sc->current_sample);
2190 2191 2192 2193
    /* adjust ctts index */
    if (sc->ctts_data) {
        time_sample = 0;
        for (i = 0; i < sc->ctts_count; i++) {
2194 2195
            int next = time_sample + sc->ctts_data[i].count;
            if (next > sc->current_sample) {
2196 2197
                sc->ctts_index = i;
                sc->ctts_sample = sc->current_sample - time_sample;
2198
                break;
2199
            }
2200
            time_sample = next;
2201 2202
        }
    }
2203
    return sample;
2204 2205
}

2206
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
G
Gael Chardon 已提交
2207
{
2208 2209 2210 2211
    AVStream *st;
    int64_t seek_timestamp, timestamp;
    int sample;
    int i;
G
Gael Chardon 已提交
2212

2213
    if (stream_index >= s->nb_streams)
G
Gael Chardon 已提交
2214
        return -1;
2215 2216
    if (sample_time < 0)
        sample_time = 0;
G
Gael Chardon 已提交
2217

2218 2219 2220
    st = s->streams[stream_index];
    sample = mov_seek_stream(st, sample_time, flags);
    if (sample < 0)
G
Gael Chardon 已提交
2221 2222
        return -1;

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

2226 2227
    for (i = 0; i < s->nb_streams; i++) {
        st = s->streams[i];
2228
        if (stream_index == i)
2229
            continue;
G
Gael Chardon 已提交
2230

2231 2232
        timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
        mov_seek_stream(st, timestamp, flags);
2233
    }
G
Gael Chardon 已提交
2234 2235 2236
    return 0;
}

Z
Zdenek Kabelac 已提交
2237
static int mov_read_close(AVFormatContext *s)
2238
{
2239
    MOVContext *mov = s->priv_data;
2240 2241 2242
    int i, j;

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

2246
        av_freep(&sc->ctts_data);
2247
        for (j = 0; j < sc->drefs_count; j++)
2248 2249 2250 2251
            av_freep(&sc->drefs[j].path);
        av_freep(&sc->drefs);
        if (sc->pb && sc->pb != s->pb)
            url_fclose(sc->pb);
2252 2253

        av_freep(&st->codec->palctrl);
2254
    }
2255 2256 2257

    if (mov->dv_demux) {
        for(i = 0; i < mov->dv_fctx->nb_streams; i++) {
2258 2259 2260 2261 2262 2263
            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);
    }
2264

B
Baptiste Coudurier 已提交
2265
    av_freep(&mov->trex_data);
2266

2267 2268 2269
    return 0;
}

2270
AVInputFormat mov_demuxer = {
2271
    "mov,mp4,m4a,3gp,3g2,mj2",
2272
    NULL_IF_CONFIG_SMALL("QuickTime/MPEG-4/Motion JPEG 2000 format"),
F
Fabrice Bellard 已提交
2273 2274
    sizeof(MOVContext),
    mov_probe,
2275 2276 2277
    mov_read_header,
    mov_read_packet,
    mov_read_close,
G
Gael Chardon 已提交
2278
    mov_read_seek,
2279
};