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

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

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

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

56 57
#include "qtpalette.h"

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

65
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom);
66
static int mov_read_mfra(MOVContext *c, AVIOContext *f);
67

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

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

    return 0;
}

88 89
static int mov_metadata_int8_bypass_padding(MOVContext *c, AVIOContext *pb,
                                            unsigned len, const char *key)
90
{
91 92 93 94
    /* bypass padding bytes */
    avio_r8(pb);
    avio_r8(pb);
    avio_r8(pb);
95

96
    c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
97
    av_dict_set_int(&c->fc->metadata, key, avio_r8(pb), 0);
98

99
    return 0;
100 101
}

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

108
    return 0;
109 110
}

R
Raivo Hool 已提交
111
static int mov_metadata_gnre(MOVContext *c, AVIOContext *pb,
112 113
                             unsigned len, const char *key)
{
R
Raivo Hool 已提交
114
    short genre;
115

R
Raivo Hool 已提交
116
    avio_r8(pb); // unknown
117

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

    return 0;
125 126
}

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

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

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

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

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

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

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

    st->disposition              |= AV_DISPOSITION_ATTACHED_PIC;

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

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

    return 0;
}

206 207 208 209 210
static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len)
{
    char language[4] = { 0 };
    char buf[100];
    uint16_t langcode = 0;
211
    double longitude, latitude;
212 213
    const char *key = "location";

214 215
    if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) {
        av_log(c->fc, AV_LOG_ERROR, "loci too short\n");
216
        return AVERROR_INVALIDDATA;
217
    }
218 219 220 221 222 223 224

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

    len -= avio_get_str(pb, len, buf, sizeof(buf)); // place name
225 226
    if (len < 1) {
        av_log(c->fc, AV_LOG_ERROR, "place name too long\n");
227
        return AVERROR_INVALIDDATA;
228
    }
229 230 231
    avio_skip(pb, 1); // role
    len -= 1;

232
    if (len < 12) {
233
        av_log(c->fc, AV_LOG_ERROR, "no space for coordinates left (%d)\n", len);
234
        return AVERROR_INVALIDDATA;
235
    }
236 237 238 239 240 241 242 243 244 245
    longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);
    latitude  = ((int32_t) avio_rb32(pb)) / (float) (1 << 16);

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

250
static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom)
251 252
{
    char tmp_key[5];
253
    char key2[32], language[4] = {0};
254
    char *str = NULL;
255
    const char *key = NULL;
256
    uint16_t langcode = 0;
257
    uint32_t data_type = 0, str_size, str_size_alloc;
258
    int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL;
259
    int raw = 0;
260 261

    switch (atom.type) {
262 263
    case MKTAG( '@','P','R','M'): key = "premiere_version"; raw = 1; break;
    case MKTAG( '@','P','R','Q'): key = "quicktime_version"; raw = 1; break;
264 265
    case MKTAG( 'X','M','P','_'):
        if (c->export_xmp) { key = "xmp"; raw = 1; } break;
R
Raivo Hool 已提交
266
    case MKTAG( 'a','A','R','T'): key = "album_artist";    break;
267 268 269 270
    case MKTAG( 'a','k','I','D'): key = "account_type";
        parse = mov_metadata_int8_no_padding; break;
    case MKTAG( 'a','p','I','D'): key = "account_id"; break;
    case MKTAG( 'c','a','t','g'): key = "category"; break;
271 272
    case MKTAG( 'c','p','i','l'): key = "compilation";
        parse = mov_metadata_int8_no_padding; break;
273 274
    case MKTAG( 'c','p','r','t'): key = "copyright"; break;
    case MKTAG( 'd','e','s','c'): key = "description"; break;
275 276
    case MKTAG( 'd','i','s','k'): key = "disc";
        parse = mov_metadata_track_or_disc_number; break;
277 278
    case MKTAG( 'e','g','i','d'): key = "episode_uid";
        parse = mov_metadata_int8_no_padding; break;
R
Raivo Hool 已提交
279 280
    case MKTAG( 'g','n','r','e'): key = "genre";
        parse = mov_metadata_gnre; break;
281 282
    case MKTAG( 'h','d','v','d'): key = "hd_video";
        parse = mov_metadata_int8_no_padding; break;
283
    case MKTAG( 'k','e','y','w'): key = "keywords";  break;
284
    case MKTAG( 'l','d','e','s'): key = "synopsis";  break;
285 286
    case MKTAG( 'l','o','c','i'):
        return mov_metadata_loci(c, pb, atom.size);
287 288
    case MKTAG( 'p','c','s','t'): key = "podcast";
        parse = mov_metadata_int8_no_padding; break;
289 290
    case MKTAG( 'p','g','a','p'): key = "gapless_playback";
        parse = mov_metadata_int8_no_padding; break;
291 292 293 294 295 296 297 298 299
    case MKTAG( 'p','u','r','d'): key = "purchase_date"; break;
    case MKTAG( 'r','t','n','g'): key = "rating";
        parse = mov_metadata_int8_no_padding; break;
    case MKTAG( 's','o','a','a'): key = "sort_album_artist"; break;
    case MKTAG( 's','o','a','l'): key = "sort_album";   break;
    case MKTAG( 's','o','a','r'): key = "sort_artist";  break;
    case MKTAG( 's','o','c','o'): key = "sort_composer"; break;
    case MKTAG( 's','o','n','m'): key = "sort_name";    break;
    case MKTAG( 's','o','s','n'): key = "sort_show";    break;
300 301
    case MKTAG( 's','t','i','k'): key = "media_type";
        parse = mov_metadata_int8_no_padding; break;
B
Baptiste Coudurier 已提交
302
    case MKTAG( 't','r','k','n'): key = "track";
303
        parse = mov_metadata_track_or_disc_number; break;
304
    case MKTAG( 't','v','e','n'): key = "episode_id"; break;
305
    case MKTAG( 't','v','e','s'): key = "episode_sort";
306
        parse = mov_metadata_int8_bypass_padding; break;
307 308
    case MKTAG( 't','v','n','n'): key = "network";   break;
    case MKTAG( 't','v','s','h'): key = "show";      break;
309
    case MKTAG( 't','v','s','n'): key = "season_number";
310
        parse = mov_metadata_int8_bypass_padding; break;
311
    case MKTAG(0xa9,'A','R','T'): key = "artist";    break;
312
    case MKTAG(0xa9,'P','R','D'): key = "producer";  break;
313 314
    case MKTAG(0xa9,'a','l','b'): key = "album";     break;
    case MKTAG(0xa9,'a','u','t'): key = "artist";    break;
315
    case MKTAG(0xa9,'c','h','p'): key = "chapter";   break;
316
    case MKTAG(0xa9,'c','m','t'): key = "comment";   break;
317
    case MKTAG(0xa9,'c','o','m'): key = "composer";  break;
318 319
    case MKTAG(0xa9,'c','p','y'): key = "copyright"; break;
    case MKTAG(0xa9,'d','a','y'): key = "date";      break;
320 321 322
    case MKTAG(0xa9,'d','i','r'): key = "director";  break;
    case MKTAG(0xa9,'d','i','s'): key = "disclaimer"; break;
    case MKTAG(0xa9,'e','d','1'): key = "edit_date"; break;
323
    case MKTAG(0xa9,'e','n','c'): key = "encoder";   break;
324
    case MKTAG(0xa9,'f','m','t'): key = "original_format"; break;
325
    case MKTAG(0xa9,'g','e','n'): key = "genre";     break;
326
    case MKTAG(0xa9,'g','r','p'): key = "grouping";  break;
327
    case MKTAG(0xa9,'h','s','t'): key = "host_computer"; break;
328
    case MKTAG(0xa9,'i','n','f'): key = "comment";   break;
329 330 331
    case MKTAG(0xa9,'l','y','r'): key = "lyrics";    break;
    case MKTAG(0xa9,'m','a','k'): key = "make";      break;
    case MKTAG(0xa9,'m','o','d'): key = "model";     break;
332
    case MKTAG(0xa9,'n','a','m'): key = "title";     break;
333 334 335 336 337
    case MKTAG(0xa9,'o','p','e'): key = "original_artist"; break;
    case MKTAG(0xa9,'p','r','d'): key = "producer";  break;
    case MKTAG(0xa9,'p','r','f'): key = "performers"; break;
    case MKTAG(0xa9,'r','e','q'): key = "playback_requirements"; break;
    case MKTAG(0xa9,'s','r','c'): key = "original_source"; break;
338
    case MKTAG(0xa9,'s','t','3'): key = "subtitle";  break;
339 340
    case MKTAG(0xa9,'s','w','r'): key = "encoder";   break;
    case MKTAG(0xa9,'t','o','o'): key = "encoder";   break;
341 342 343
    case MKTAG(0xa9,'t','r','k'): key = "track";     break;
    case MKTAG(0xa9,'u','r','l'): key = "URL";       break;
    case MKTAG(0xa9,'w','r','n'): key = "warning";   break;
344 345
    case MKTAG(0xa9,'w','r','t'): key = "composer";  break;
    case MKTAG(0xa9,'x','y','z'): key = "location";  break;
346
    }
347
retry:
348
    if (c->itunes_metadata && atom.size > 8) {
349 350
        int data_size = avio_rb32(pb);
        int tag = avio_rl32(pb);
351
        if (tag == MKTAG('d','a','t','a') && data_size <= atom.size) {
352 353
            data_type = avio_rb32(pb); // type
            avio_rb32(pb); // unknown
354 355
            str_size = data_size - 16;
            atom.size -= 16;
A
Anton Khirnov 已提交
356 357 358 359 360 361

            if (atom.type == MKTAG('c', 'o', 'v', 'r')) {
                int ret = mov_read_covr(c, pb, data_type, str_size);
                if (ret < 0) {
                    av_log(c->fc, AV_LOG_ERROR, "Error parsing cover art.\n");
                }
362
                return ret;
A
Anton Khirnov 已提交
363
            }
364
        } else return 0;
365
    } else if (atom.size > 4 && key && !c->itunes_metadata && !raw) {
366
        str_size = avio_rb16(pb); // string length
367 368 369
        if (str_size > atom.size) {
            raw = 1;
            avio_seek(pb, -2, SEEK_CUR);
370
            av_log(c->fc, AV_LOG_WARNING, "UDTA parsing failed retrying raw\n");
371 372
            goto retry;
        }
373
        langcode = avio_rb16(pb);
374
        ff_mov_lang_to_iso639(langcode, language);
375 376 377 378
        atom.size -= 4;
    } else
        str_size = atom.size;

379
    if (c->export_all && !key) {
380 381 382 383 384 385
        snprintf(tmp_key, 5, "%.4s", (char*)&atom.type);
        key = tmp_key;
    }

    if (!key)
        return 0;
386
    if (atom.size < 0 || str_size >= INT_MAX/2)
387
        return AVERROR_INVALIDDATA;
388

389
    // worst-case requirement for output string in case of utf8 coded input
390
    str_size_alloc = (raw ? str_size : str_size * 2) + 1;
391
    str = av_mallocz(str_size_alloc);
392 393 394
    if (!str)
        return AVERROR(ENOMEM);

B
Baptiste Coudurier 已提交
395
    if (parse)
396
        parse(c, pb, str_size, key);
B
Baptiste Coudurier 已提交
397
    else {
398
        if (!raw && (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff)))) { // MAC Encoded
399
            mov_read_mac_string(c, pb, str_size, str, str_size_alloc);
400
        } else {
401
            int ret = avio_read(pb, str, str_size);
402 403
            if (ret != str_size) {
                av_freep(&str);
404
                return ret < 0 ? ret : AVERROR_INVALIDDATA;
405
            }
406 407
            str[str_size] = 0;
        }
408
        c->fc->event_flags |= AVFMT_EVENT_FLAG_METADATA_UPDATED;
409
        av_dict_set(&c->fc->metadata, key, str, 0);
B
Baptiste Coudurier 已提交
410 411
        if (*language && strcmp(language, "und")) {
            snprintf(key2, sizeof(key2), "%s-%s", key, language);
412
            av_dict_set(&c->fc->metadata, key2, str, 0);
B
Baptiste Coudurier 已提交
413
        }
B
Baptiste Coudurier 已提交
414
    }
415 416
    av_log(c->fc, AV_LOG_TRACE, "lang \"%3s\" ", language);
    av_log(c->fc, AV_LOG_TRACE, "tag \"%s\" value \"%s\" atom \"%.4s\" %d %"PRId64"\n",
417 418 419
            key, str, (char*)&atom.type, str_size_alloc, atom.size);

    av_freep(&str);
420 421
    return 0;
}
422

423
static int mov_read_chpl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
D
David Conrad 已提交
424 425
{
    int64_t start;
D
David Conrad 已提交
426
    int i, nb_chapters, str_len, version;
D
David Conrad 已提交
427 428 429 430 431
    char str[256+1];

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

432 433
    version = avio_r8(pb);
    avio_rb24(pb);
D
David Conrad 已提交
434
    if (version)
435 436
        avio_rb32(pb); // ???
    nb_chapters = avio_r8(pb);
D
David Conrad 已提交
437 438 439 440 441

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

442 443
        start = avio_rb64(pb);
        str_len = avio_r8(pb);
D
David Conrad 已提交
444 445 446 447

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

448
        avio_read(pb, str, str_len);
D
David Conrad 已提交
449
        str[str_len] = 0;
450
        avpriv_new_chapter(c->fc, i, (AVRational){1,10000000}, start, AV_NOPTS_VALUE, str);
D
David Conrad 已提交
451 452 453 454
    }
    return 0;
}

455
#define MIN_DATA_ENTRY_BOX_SIZE 12
456
static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
457
{
458 459
    AVStream *st;
    MOVStreamContext *sc;
460 461
    int entries, i, j;

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

467 468
    avio_rb32(pb); // version + flags
    entries = avio_rb32(pb);
469 470
    if (entries >  (atom.size - 1) / MIN_DATA_ENTRY_BOX_SIZE + 1 ||
        entries >= UINT_MAX / sizeof(*sc->drefs))
471
        return AVERROR_INVALIDDATA;
472
    av_free(sc->drefs);
473
    sc->drefs_count = 0;
474
    sc->drefs = av_mallocz(entries * sizeof(*sc->drefs));
475 476 477
    if (!sc->drefs)
        return AVERROR(ENOMEM);
    sc->drefs_count = entries;
478 479

    for (i = 0; i < sc->drefs_count; i++) {
480
        MOVDref *dref = &sc->drefs[i];
481
        uint32_t size = avio_rb32(pb);
482
        int64_t next = avio_tell(pb) + size - 4;
483

484
        if (size < 12)
485
            return AVERROR_INVALIDDATA;
486

487 488
        dref->type = avio_rl32(pb);
        avio_rb32(pb); // version + flags
489
        av_log(c->fc, AV_LOG_TRACE, "type %.4s size %d\n", (char*)&dref->type, size);
490 491 492 493 494 495

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

496
            avio_skip(pb, 10);
497

498
            volume_len = avio_r8(pb);
499
            volume_len = FFMIN(volume_len, 27);
500
            avio_read(pb, dref->volume, 27);
501 502
            dref->volume[volume_len] = 0;
            av_log(c->fc, AV_LOG_DEBUG, "volume %s, len %d\n", dref->volume, volume_len);
503

504
            avio_skip(pb, 12);
505

506
            len = avio_r8(pb);
507
            len = FFMIN(len, 63);
508
            avio_read(pb, dref->filename, 63);
509 510 511
            dref->filename[len] = 0;
            av_log(c->fc, AV_LOG_DEBUG, "filename %s, len %d\n", dref->filename, len);

512
            avio_skip(pb, 16);
513 514

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

520
            avio_skip(pb, 16);
521

522
            for (type = 0; type != -1 && avio_tell(pb) < next; ) {
523
                if(avio_feof(pb))
524
                    return AVERROR_EOF;
525 526
                type = avio_rb16(pb);
                len = avio_rb16(pb);
527 528 529
                av_log(c->fc, AV_LOG_DEBUG, "type %d, len %d\n", type, len);
                if (len&1)
                    len += 1;
530
                if (type == 2 || type == 18) { // absolute path
531
                    av_free(dref->path);
532
                    dref->path = av_mallocz(len+1);
533 534
                    if (!dref->path)
                        return AVERROR(ENOMEM);
535
                    avio_read(pb, dref->path, len);
536 537
                    if (type == 18) // no additional processing needed
                        continue;
538
                    if (len > volume_len && !strncmp(dref->path, dref->volume, volume_len)) {
539 540 541 542 543 544 545 546
                        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);
547 548 549 550 551
                } else if (type == 0) { // directory name
                    av_free(dref->dir);
                    dref->dir = av_malloc(len+1);
                    if (!dref->dir)
                        return AVERROR(ENOMEM);
552 553
                    if (avio_read(pb, dref->dir, len) != len)
                        return AVERROR_INVALIDDATA;
554 555 556 557 558
                    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);
559
                } else
560
                    avio_skip(pb, len);
561 562
            }
        }
A
Anton Khirnov 已提交
563
        avio_seek(pb, next, SEEK_SET);
564 565 566 567
    }
    return 0;
}

568
static int mov_read_hdlr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
569
{
570
    AVStream *st;
571
    uint32_t type;
572
    uint32_t av_unused ctype;
573
    int64_t title_size;
574
    char *title_str;
575

576 577 578 579 580
    if (c->fc->nb_streams < 1) // meta before first trak
        return 0;

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

581 582
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
583 584

    /* component type */
585 586
    ctype = avio_rl32(pb);
    type = avio_rl32(pb); /* component subtype */
587

588 589
    av_log(c->fc, AV_LOG_TRACE, "ctype= %.4s (0x%08x)\n", (char*)&ctype, ctype);
    av_log(c->fc, AV_LOG_TRACE, "stype= %.4s\n", (char*)&type);
590

591
    if     (type == MKTAG('v','i','d','e'))
592
        st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
593
    else if (type == MKTAG('s','o','u','n'))
594
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
595
    else if (type == MKTAG('m','1','a',' '))
596
        st->codec->codec_id = AV_CODEC_ID_MP2;
597
    else if ((type == MKTAG('s','u','b','p')) || (type == MKTAG('c','l','c','p')))
598
        st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
599

600 601 602
    avio_rb32(pb); /* component  manufacture */
    avio_rb32(pb); /* component flags */
    avio_rb32(pb); /* component flags mask */
603

604 605 606 607 608 609 610
    title_size = atom.size - 24;
    if (title_size > 0) {
        title_str = av_malloc(title_size + 1); /* Add null terminator */
        if (!title_str)
            return AVERROR(ENOMEM);
        avio_read(pb, title_str, title_size);
        title_str[title_size] = 0;
611 612 613 614
        if (title_str[0]) {
            int off = (!c->isom && title_str[0] == title_size - 1);
            av_dict_set(&st->metadata, "handler_name", title_str + off, 0);
        }
615 616 617
        av_freep(&title_str);
    }

618 619 620
    return 0;
}

621
int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb)
622
{
623
    AVStream *st;
624
    int tag;
625

626
    if (fc->nb_streams < 1)
627
        return 0;
628
    st = fc->streams[fc->nb_streams-1];
629

630
    avio_rb32(pb); /* version + flags */
631
    ff_mp4_read_descr(fc, pb, &tag);
632
    if (tag == MP4ESDescrTag) {
633
        ff_mp4_parse_es_descr(pb, NULL);
634
    } else
635
        avio_rb16(pb); /* ID */
636

637
    ff_mp4_read_descr(fc, pb, &tag);
638 639
    if (tag == MP4DecConfigDescrTag)
        ff_mp4_read_dec_config_descr(fc, st, pb);
640 641 642
    return 0;
}

643
static int mov_read_esds(MOVContext *c, AVIOContext *pb, MOVAtom atom)
644
{
645
    return ff_mov_read_esds(c->fc, pb);
646 647
}

648
static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
649 650
{
    AVStream *st;
651
    enum AVAudioServiceType *ast;
652
    int ac3info, acmod, lfeon, bsmod;
653

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

658 659 660 661 662
    ast = (enum AVAudioServiceType*)ff_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
                                                            sizeof(*ast));
    if (!ast)
        return AVERROR(ENOMEM);

663
    ac3info = avio_rb24(pb);
664
    bsmod = (ac3info >> 14) & 0x7;
665 666 667
    acmod = (ac3info >> 11) & 0x7;
    lfeon = (ac3info >> 10) & 0x1;
    st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon;
668 669 670
    st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
    if (lfeon)
        st->codec->channel_layout |= AV_CH_LOW_FREQUENCY;
671
    *ast = bsmod;
672
    if (st->codec->channels > 1 && bsmod == 0x7)
673 674 675
        *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;

    st->codec->audio_service_type = *ast;
676 677 678 679

    return 0;
}

680 681 682
static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
683
    enum AVAudioServiceType *ast;
684 685 686 687 688 689
    int eac3info, acmod, lfeon, bsmod;

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

690 691 692 693 694
    ast = (enum AVAudioServiceType*)ff_stream_new_side_data(st, AV_PKT_DATA_AUDIO_SERVICE_TYPE,
                                                            sizeof(*ast));
    if (!ast)
        return AVERROR(ENOMEM);

695 696 697 698 699 700 701 702 703 704 705 706
    /* No need to parse fields for additional independent substreams and its
     * associated dependent substreams since libavcodec's E-AC-3 decoder
     * does not support them yet. */
    avio_rb16(pb); /* data_rate and num_ind_sub */
    eac3info = avio_rb24(pb);
    bsmod = (eac3info >> 12) & 0x1f;
    acmod = (eac3info >>  9) & 0x7;
    lfeon = (eac3info >>  8) & 0x1;
    st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod];
    if (lfeon)
        st->codec->channel_layout |= AV_CH_LOW_FREQUENCY;
    st->codec->channels = av_get_channel_layout_nb_channels(st->codec->channel_layout);
707
    *ast = bsmod;
708
    if (st->codec->channels > 1 && bsmod == 0x7)
709 710 711
        *ast = AV_AUDIO_SERVICE_TYPE_KARAOKE;

    st->codec->audio_service_type = *ast;
712 713 714 715

    return 0;
}

716 717 718 719 720 721 722 723 724 725 726
static int mov_read_chan(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;

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

    if (atom.size < 16)
        return 0;

727 728 729
    /* skip version and flags */
    avio_skip(pb, 4);

730
    ff_mov_read_chan(c->fc, pb, st, atom.size - 4);
731 732 733 734

    return 0;
}

735 736 737
static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
738
    int ret;
739 740 741 742 743

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

T
Thomas Volkert 已提交
744
    if ((ret = ff_get_wav_header(pb, st->codec, atom.size, 0)) < 0)
745
        av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n");
746

747
    return ret;
748 749
}

750
static int mov_read_pasp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
751
{
752 753
    const int num = avio_rb32(pb);
    const int den = avio_rb32(pb);
754 755 756 757 758 759
    AVStream *st;

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

760 761 762 763 764 765 766
    if ((st->sample_aspect_ratio.den != 1 || st->sample_aspect_ratio.num) && // default
        (den != st->sample_aspect_ratio.den || num != st->sample_aspect_ratio.num)) {
        av_log(c->fc, AV_LOG_WARNING,
               "sample aspect ratio already set to %d:%d, ignoring 'pasp' atom (%d:%d)\n",
               st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
               num, den);
    } else if (den != 0) {
767 768
        av_reduce(&st->sample_aspect_ratio.num, &st->sample_aspect_ratio.den,
                  num, den, 32767);
769 770 771 772
    }
    return 0;
}

773
/* this atom contains actual media data */
774
static int mov_read_mdat(MOVContext *c, AVIOContext *pb, MOVAtom atom)
775
{
776
    if (atom.size == 0) /* wrong one (MP4) */
777 778 779 780 781
        return 0;
    c->found_mdat=1;
    return 0; /* now go for moov */
}

782
/* read major brand, minor version and compatible brands and store them as metadata */
783
static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
784
{
785 786 787 788 789
    uint32_t minor_ver;
    int comp_brand_size;
    char* comp_brands_str;
    uint8_t type[5] = {0};

790
    avio_read(pb, type, 4);
B
Baptiste Coudurier 已提交
791
    if (strcmp(type, "qt  "))
792
        c->isom = 1;
793
    av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
794
    av_dict_set(&c->fc->metadata, "major_brand", type, 0);
795
    minor_ver = avio_rb32(pb); /* minor version */
796
    av_dict_set_int(&c->fc->metadata, "minor_version", minor_ver, 0);
797 798 799

    comp_brand_size = atom.size - 8;
    if (comp_brand_size < 0)
800
        return AVERROR_INVALIDDATA;
801 802 803
    comp_brands_str = av_malloc(comp_brand_size + 1); /* Add null terminator */
    if (!comp_brands_str)
        return AVERROR(ENOMEM);
804
    avio_read(pb, comp_brands_str, comp_brand_size);
805
    comp_brands_str[comp_brand_size] = 0;
806
    av_dict_set(&c->fc->metadata, "compatible_brands", comp_brands_str, 0);
807 808
    av_freep(&comp_brands_str);

809 810 811
    return 0;
}

812
/* this atom should contain all header atoms */
813
static int mov_read_moov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
814
{
815 816
    int ret;

817 818 819 820 821 822
    if (c->found_moov) {
        av_log(c->fc, AV_LOG_WARNING, "Found duplicated MOOV Atom. Skipped it\n");
        avio_skip(pb, atom.size);
        return 0;
    }

823 824
    if ((ret = mov_read_default(c, pb, atom)) < 0)
        return ret;
825 826 827 828 829 830
    /* 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 */
}

831
static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
832
{
833 834 835
    if (!c->has_looked_for_mfra && c->use_mfra_for > 0) {
        c->has_looked_for_mfra = 1;
        if (pb->seekable) {
836
            int ret;
837 838 839 840 841 842 843 844 845 846 847
            av_log(c->fc, AV_LOG_VERBOSE, "stream has moof boxes, will look "
                    "for a mfra\n");
            if ((ret = mov_read_mfra(c, pb)) < 0) {
                av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but failed to "
                        "read the mfra (may be a live ismv)\n");
            }
        } else {
            av_log(c->fc, AV_LOG_VERBOSE, "found a moof box but stream is not "
                    "seekable, can not look for mfra\n");
        }
    }
848
    c->fragment.moof_offset = c->fragment.implicit_offset = avio_tell(pb) - 8;
849
    av_log(c->fc, AV_LOG_TRACE, "moof offset %"PRIx64"\n", c->fragment.moof_offset);
B
Baptiste Coudurier 已提交
850 851
    return mov_read_default(c, pb, atom);
}
852

853
static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time)
854 855 856
{
    char buffer[32];
    if (time) {
857
        struct tm *ptm, tmbuf;
858
        time_t timet;
859 860
        if(time >= 2082844800)
            time -= 2082844800;  /* seconds between 1904-01-01 and Epoch */
861
        timet = time;
862
        ptm = gmtime_r(&timet, &tmbuf);
863
        if (!ptm) return;
864 865
        if (strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", ptm))
            av_dict_set(metadata, "creation_time", buffer, 0);
866 867 868
    }
}

869
static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
870
{
871 872 873
    AVStream *st;
    MOVStreamContext *sc;
    int version;
874
    char language[4] = {0};
875
    unsigned lang;
876
    int64_t creation_time;
877

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

883 884 885 886 887
    if (sc->time_scale) {
        av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n");
        return AVERROR_INVALIDDATA;
    }

888
    version = avio_r8(pb);
889
    if (version > 1) {
890
        avpriv_request_sample(c->fc, "Version %d", version);
891 892
        return AVERROR_PATCHWELCOME;
    }
893
    avio_rb24(pb); /* flags */
B
clean  
Baptiste Coudurier 已提交
894
    if (version == 1) {
895 896
        creation_time = avio_rb64(pb);
        avio_rb64(pb);
B
clean  
Baptiste Coudurier 已提交
897
    } else {
898 899
        creation_time = avio_rb32(pb);
        avio_rb32(pb); /* modification time */
B
clean  
Baptiste Coudurier 已提交
900
    }
901
    mov_metadata_creation_time(&st->metadata, creation_time);
902

903 904
    sc->time_scale = avio_rb32(pb);
    st->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
905

906
    lang = avio_rb16(pb); /* language */
907
    if (ff_mov_lang_to_iso639(lang, language))
908
        av_dict_set(&st->metadata, "language", language, 0);
909
    avio_rb16(pb); /* quality */
910 911 912 913

    return 0;
}

914
static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
915
{
916
    int64_t creation_time;
917 918
    int version = avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
919

B
Baptiste Coudurier 已提交
920
    if (version == 1) {
921 922
        creation_time = avio_rb64(pb);
        avio_rb64(pb);
B
Baptiste Coudurier 已提交
923
    } else {
924 925
        creation_time = avio_rb32(pb);
        avio_rb32(pb); /* modification time */
B
Baptiste Coudurier 已提交
926
    }
927
    mov_metadata_creation_time(&c->fc->metadata, creation_time);
928
    c->time_scale = avio_rb32(pb); /* time scale */
929

930
    av_log(c->fc, AV_LOG_TRACE, "time scale = %i\n", c->time_scale);
931

932
    c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */
933 934
    // set the AVCodecContext duration because the duration of individual tracks
    // may be inaccurate
935
    if (c->time_scale > 0 && !c->trex_data)
936
        c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale);
937
    avio_rb32(pb); /* preferred scale */
938

939
    avio_rb16(pb); /* preferred volume */
940

941
    avio_skip(pb, 10); /* reserved */
942

943
    avio_skip(pb, 36); /* display matrix */
944

945 946 947 948 949 950 951
    avio_rb32(pb); /* preview time */
    avio_rb32(pb); /* preview duration */
    avio_rb32(pb); /* poster time */
    avio_rb32(pb); /* selection time */
    avio_rb32(pb); /* selection duration */
    avio_rb32(pb); /* current time */
    avio_rb32(pb); /* next track ID */
952 953 954
    return 0;
}

955
static int mov_read_enda(MOVContext *c, AVIOContext *pb, MOVAtom atom)
956
{
957 958 959 960 961 962
    AVStream *st;
    int little_endian;

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

964
    little_endian = avio_rb16(pb) & 0xFF;
965
    av_log(c->fc, AV_LOG_TRACE, "enda %d\n", little_endian);
966
    if (little_endian == 1) {
967
        switch (st->codec->codec_id) {
968 969
        case AV_CODEC_ID_PCM_S24BE:
            st->codec->codec_id = AV_CODEC_ID_PCM_S24LE;
970
            break;
971 972
        case AV_CODEC_ID_PCM_S32BE:
            st->codec->codec_id = AV_CODEC_ID_PCM_S32LE;
973
            break;
974 975
        case AV_CODEC_ID_PCM_F32BE:
            st->codec->codec_id = AV_CODEC_ID_PCM_F32LE;
976
            break;
977 978
        case AV_CODEC_ID_PCM_F64BE:
            st->codec->codec_id = AV_CODEC_ID_PCM_F64LE;
979
            break;
980 981 982 983 984 985 986
        default:
            break;
        }
    }
    return 0;
}

987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    char color_parameter_type[5] = { 0 };
    int color_primaries, color_trc, color_matrix;

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

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

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

1009
    av_log(c->fc, AV_LOG_TRACE,
1010
           "%s: pri %d trc %d matrix %d",
1011
           color_parameter_type, color_primaries, color_trc, color_matrix);
1012

1013
    if (!strncmp(color_parameter_type, "nclx", 4)) {
1014
        uint8_t color_range = avio_r8(pb) >> 7;
1015
        av_log(c->fc, AV_LOG_TRACE, " full %"PRIu8"", color_range);
1016 1017 1018 1019 1020 1021 1022 1023
        if (color_range)
            st->codec->color_range = AVCOL_RANGE_JPEG;
        else
            st->codec->color_range = AVCOL_RANGE_MPEG;
        /* 14496-12 references JPEG XR specs (rather than the more complete
         * 23001-8) so some adjusting is required */
        if (color_primaries >= AVCOL_PRI_FILM)
            color_primaries = AVCOL_PRI_UNSPECIFIED;
1024 1025
        if ((color_trc >= AVCOL_TRC_LINEAR &&
             color_trc <= AVCOL_TRC_LOG_SQRT) ||
1026 1027 1028 1029 1030 1031 1032
            color_trc >= AVCOL_TRC_BT2020_10)
            color_trc = AVCOL_TRC_UNSPECIFIED;
        if (color_matrix >= AVCOL_SPC_BT2020_NCL)
            color_matrix = AVCOL_SPC_UNSPECIFIED;
        st->codec->color_primaries = color_primaries;
        st->codec->color_trc = color_trc;
        st->codec->colorspace = color_matrix;
1033
    } else if (!strncmp(color_parameter_type, "nclc", 4)) {
1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051
        /* color primaries, Table 4-4 */
        switch (color_primaries) {
        case 1: st->codec->color_primaries = AVCOL_PRI_BT709; break;
        case 5: st->codec->color_primaries = AVCOL_PRI_SMPTE170M; break;
        case 6: st->codec->color_primaries = AVCOL_PRI_SMPTE240M; break;
        }
        /* color transfer, Table 4-5 */
        switch (color_trc) {
        case 1: st->codec->color_trc = AVCOL_TRC_BT709; break;
        case 7: st->codec->color_trc = AVCOL_TRC_SMPTE240M; break;
        }
        /* color matrix, Table 4-6 */
        switch (color_matrix) {
        case 1: st->codec->colorspace = AVCOL_SPC_BT709; break;
        case 6: st->codec->colorspace = AVCOL_SPC_BT470BG; break;
        case 7: st->codec->colorspace = AVCOL_SPC_SMPTE240M; break;
        }
    }
1052
    av_log(c->fc, AV_LOG_TRACE, "\n");
1053 1054 1055 1056

    return 0;
}

1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090
static int mov_read_fiel(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    unsigned mov_field_order;
    enum AVFieldOrder decoded_field_order = AV_FIELD_UNKNOWN;

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

    return 0;
}

1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
static int mov_realloc_extradata(AVCodecContext *codec, MOVAtom atom)
{
    int err = 0;
    uint64_t size = (uint64_t)codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
    if (size > INT_MAX || (uint64_t)atom.size > INT_MAX)
        return AVERROR_INVALIDDATA;
    if ((err = av_reallocp(&codec->extradata, size)) < 0) {
        codec->extradata_size = 0;
        return err;
    }
    codec->extradata_size = size - FF_INPUT_BUFFER_PADDING_SIZE;
    return 0;
}

/* Read a whole atom into the extradata return the size of the atom read, possibly truncated if != atom.size */
static int64_t mov_read_atom_into_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
                                        AVCodecContext *codec, uint8_t *buf)
{
    int64_t result = atom.size;
    int err;

    AV_WB32(buf    , atom.size + 8);
    AV_WL32(buf + 4, atom.type);
    err = avio_read(pb, buf + 8, atom.size);
    if (err < 0) {
        codec->extradata_size -= atom.size;
        return err;
    } else if (err < atom.size) {
        av_log(c->fc, AV_LOG_WARNING, "truncated extradata\n");
        codec->extradata_size -= atom.size - err;
        result = err;
    }
    memset(buf + 8 + err, 0, FF_INPUT_BUFFER_PADDING_SIZE);
    return result;
}

1127
/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
1128
static int mov_read_extradata(MOVContext *c, AVIOContext *pb, MOVAtom atom,
1129
                              enum AVCodecID codec_id)
1130
{
1131
    AVStream *st;
1132
    uint64_t original_size;
1133
    int err;
1134 1135 1136

    if (c->fc->nb_streams < 1) // will happen with jp2 files
        return 0;
1137
    st = c->fc->streams[c->fc->nb_streams-1];
1138 1139 1140 1141

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

1142 1143 1144
    original_size = st->codec->extradata_size;
    err = mov_realloc_extradata(st->codec, atom);
    if (err)
1145
        return err;
1146 1147 1148

    err =  mov_read_atom_into_extradata(c, pb, atom, st->codec,  st->codec->extradata + original_size);
    if (err < 0)
1149
        return err;
1150
    return 0; // Note: this is the original behavior to ignore truncation.
1151 1152
}

1153 1154 1155
/* wrapper functions for reading ALAC/AVS/MJPEG/MJPEG2000 extradata atoms only for those codecs */
static int mov_read_alac(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1156
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_ALAC);
1157 1158 1159 1160
}

static int mov_read_avss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1161
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVS);
1162 1163 1164 1165
}

static int mov_read_jp2h(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1166
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_JPEG2000);
1167 1168
}

1169 1170 1171 1172 1173
static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_R10K);
}

C
Carl Eugen Hoyos 已提交
1174
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1175
{
1176 1177 1178 1179
    int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
    if(ret == 0)
        ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
    return ret;
1180 1181
}

1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195
static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_TARGA_Y216);

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

1196 1197
static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1198 1199 1200 1201 1202 1203 1204 1205 1206 1207 1208
    if (c->fc->nb_streams >= 1) {
        AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec;
        if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') &&
            codec->codec_id == AV_CODEC_ID_H264 &&
            atom.size > 11) {
            avio_skip(pb, 10);
            /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */
            if (avio_rb16(pb) == 0xd4d)
                codec->width = 1440;
            return 0;
        }
1209 1210 1211 1212 1213
    }

    return mov_read_avid(c, pb, atom);
}

1214 1215 1216 1217 1218 1219 1220
static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int ret = 0;
    int length = 0;
    uint64_t original_size;
    if (c->fc->nb_streams >= 1) {
        AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec;
1221 1222
        if (codec->codec_id == AV_CODEC_ID_H264)
            return 0;
1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240
        if (atom.size == 16) {
            original_size = codec->extradata_size;
            ret = mov_realloc_extradata(codec, atom);
            if (!ret) {
                length =  mov_read_atom_into_extradata(c, pb, atom, codec, codec->extradata + original_size);
                if (length == atom.size) {
                    const uint8_t range_value = codec->extradata[original_size + 19];
                    switch (range_value) {
                    case 1:
                        codec->color_range = AVCOL_RANGE_MPEG;
                        break;
                    case 2:
                        codec->color_range = AVCOL_RANGE_JPEG;
                        break;
                    default:
                        av_log(c, AV_LOG_WARNING, "ignored unknown aclr value (%d)\n", range_value);
                        break;
                    }
1241
                    av_dlog(c, "color_range: %d\n", codec->color_range);
1242 1243 1244 1245 1246 1247 1248 1249
                } else {
                  /* For some reason the whole atom was not added to the extradata */
                  av_log(c, AV_LOG_ERROR, "aclr not decoded - incomplete atom\n");
                }
            } else {
                av_log(c, AV_LOG_ERROR, "aclr not decoded - unable to add atom to extradata\n");
            }
        } else {
1250
            av_log(c, AV_LOG_WARNING, "aclr not decoded - unexpected size %"PRId64"\n", atom.size);
1251 1252 1253 1254 1255 1256
        }
    }

    return ret;
}

P
Piotr Bandurski 已提交
1257 1258
static int mov_read_svq3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
1259
    return mov_read_extradata(c, pb, atom, AV_CODEC_ID_SVQ3);
P
Piotr Bandurski 已提交
1260 1261
}

1262
static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom)
R
Roberto Togni 已提交
1263
{
1264 1265 1266 1267 1268
    AVStream *st;

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

1270
    if ((uint64_t)atom.size > (1<<30))
1271
        return AVERROR_INVALIDDATA;
1272

1273 1274 1275
    if (st->codec->codec_id == AV_CODEC_ID_QDM2 ||
        st->codec->codec_id == AV_CODEC_ID_QDMC ||
        st->codec->codec_id == AV_CODEC_ID_SPEEX) {
1276
        // pass all frma atom to codec, needed at least for QDMC and QDM2
1277
        av_freep(&st->codec->extradata);
1278
        if (ff_get_extradata(st->codec, pb, atom.size) < 0)
1279
            return AVERROR(ENOMEM);
1280
    } else if (atom.size > 8) { /* to read frma, esds atoms */
1281 1282 1283
        int ret;
        if ((ret = mov_read_default(c, pb, atom)) < 0)
            return ret;
1284
    } else
1285
        avio_skip(pb, atom.size);
R
Roberto Togni 已提交
1286 1287 1288
    return 0;
}

1289 1290 1291 1292
/**
 * This function reads atom content and puts data in extradata without tag
 * nor size unlike mov_read_extradata.
 */
1293
static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1294
{
1295 1296 1297 1298 1299
    AVStream *st;

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

1301
    if ((uint64_t)atom.size > (1<<30))
1302
        return AVERROR_INVALIDDATA;
1303

1304
    if (atom.size >= 10) {
1305
        // Broken files created by legacy versions of libavformat will
1306 1307 1308 1309 1310 1311 1312
        // wrap a whole fiel atom inside of a glbl atom.
        unsigned size = avio_rb32(pb);
        unsigned type = avio_rl32(pb);
        avio_seek(pb, -8, SEEK_CUR);
        if (type == MKTAG('f','i','e','l') && size == atom.size)
            return mov_read_default(c, pb, atom);
    }
1313 1314 1315 1316
    if (st->codec->extradata_size > 1 && st->codec->extradata) {
        av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n");
        return 0;
    }
1317
    av_freep(&st->codec->extradata);
1318
    if (ff_get_extradata(st->codec, pb, atom.size) < 0)
1319
        return AVERROR(ENOMEM);
1320

1321 1322 1323
    return 0;
}

M
Martin Storsjö 已提交
1324 1325 1326 1327
static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    uint8_t profile_level;
1328
    int ret;
M
Martin Storsjö 已提交
1329 1330 1331 1332 1333 1334 1335 1336 1337

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

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

    profile_level = avio_r8(pb);
1338
    if ((profile_level & 0xf0) != 0xc0)
M
Martin Storsjö 已提交
1339 1340 1341
        return 0;

    avio_seek(pb, 6, SEEK_CUR);
1342
    av_freep(&st->codec->extradata);
1343 1344
    if ((ret = ff_get_extradata(st->codec, pb, atom.size - 7)) < 0)
        return ret;
1345

M
Martin Storsjö 已提交
1346 1347 1348
    return 0;
}

M
Martin Storsjö 已提交
1349 1350 1351 1352 1353
/**
 * An strf atom is a BITMAPINFOHEADER struct. This struct is 40 bytes itself,
 * but can have extradata appended at the end after the 40 bytes belonging
 * to the struct.
 */
1354
static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom)
M
Martin Storsjö 已提交
1355 1356 1357 1358 1359 1360 1361 1362 1363
{
    AVStream *st;

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

1364
    if ((uint64_t)atom.size > (1<<30))
1365
        return AVERROR_INVALIDDATA;
M
Martin Storsjö 已提交
1366

1367
    avio_skip(pb, 40);
1368
    av_freep(&st->codec->extradata);
1369
    if (ff_get_extradata(st->codec, pb, atom.size - 40) < 0)
M
Martin Storsjö 已提交
1370 1371 1372 1373
        return AVERROR(ENOMEM);
    return 0;
}

1374
static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1375
{
1376 1377
    AVStream *st;
    MOVStreamContext *sc;
1378
    unsigned int i, entries;
1379

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

1385 1386
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1387

1388
    entries = avio_rb32(pb);
1389

A
Alex Converse 已提交
1390 1391
    if (!entries)
        return 0;
1392

1393
    if (sc->chunk_offsets)
1394
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n");
1395 1396
    av_free(sc->chunk_offsets);
    sc->chunk_count = 0;
1397
    sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets));
1398
    if (!sc->chunk_offsets)
1399 1400 1401
        return AVERROR(ENOMEM);
    sc->chunk_count = entries;

1402
    if      (atom.type == MKTAG('s','t','c','o'))
1403
        for (i = 0; i < entries && !pb->eof_reached; i++)
1404
            sc->chunk_offsets[i] = avio_rb32(pb);
1405
    else if (atom.type == MKTAG('c','o','6','4'))
1406
        for (i = 0; i < entries && !pb->eof_reached; i++)
1407
            sc->chunk_offsets[i] = avio_rb64(pb);
1408
    else
1409
        return AVERROR_INVALIDDATA;
1410

1411 1412 1413 1414 1415
    sc->chunk_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

1416 1417 1418
    return 0;
}

1419 1420 1421 1422
/**
 * Compute codec id for 'lpcm' tag.
 * See CoreAudioTypes and AudioStreamBasicDescription at Apple.
 */
1423
enum AVCodecID ff_mov_get_lpcm_codec_id(int bps, int flags)
1424
{
1425 1426 1427 1428 1429 1430
    /* lpcm flags:
     * 0x1 = float
     * 0x2 = big-endian
     * 0x4 = signed
     */
    return ff_get_pcm_codec_id(bps, flags & 1, flags & 2, flags & 4 ? -1 : 0);
1431 1432
}

1433 1434 1435 1436 1437 1438 1439 1440 1441 1442 1443 1444 1445 1446 1447 1448 1449 1450 1451
static int mov_codec_id(AVStream *st, uint32_t format)
{
    int id = ff_codec_get_id(ff_codec_movaudio_tags, format);

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

    if (st->codec->codec_type != AVMEDIA_TYPE_VIDEO && id > 0) {
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
    } else if (st->codec->codec_type != AVMEDIA_TYPE_AUDIO &&
               /* skip old asf mpeg4 tag */
               format && format != MKTAG('m','p','4','s')) {
        id = ff_codec_get_id(ff_codec_movvideo_tags, format);
        if (id <= 0)
            id = ff_codec_get_id(ff_codec_bmp_tags, format);
        if (id > 0)
            st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
1452 1453 1454
        else if (st->codec->codec_type == AVMEDIA_TYPE_DATA ||
                    (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE &&
                    st->codec->codec_id == AV_CODEC_ID_NONE)) {
1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465
            id = ff_codec_get_id(ff_codec_movsubtitle_tags, format);
            if (id > 0)
                st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE;
        }
    }

    st->codec->codec_tag = format;

    return id;
}

1466 1467 1468
static void mov_parse_stsd_video(MOVContext *c, AVIOContext *pb,
                                 AVStream *st, MOVStreamContext *sc)
{
1469
    uint8_t codec_name[32];
1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490
    unsigned int color_depth, len, j;
    int color_greyscale;
    int color_table_id;

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

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

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

    len = avio_r8(pb); /* codec name, pascal string */
    if (len > 31)
        len = 31;
1491
    mov_read_mac_string(c, pb, len, codec_name, sizeof(codec_name));
1492 1493
    if (len < 31)
        avio_skip(pb, 31 - len);
1494 1495 1496 1497

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

1498
    /* codec_tag YV12 triggers an UV swap in rawdec.c */
1499
    if (!memcmp(codec_name, "Planar Y'CbCr 8-bit 4:2:0", 25)) {
1500
        st->codec->codec_tag = MKTAG('I', '4', '2', '0');
1501 1502 1503
        st->codec->width &= ~1;
        st->codec->height &= ~1;
    }
1504 1505
    /* Flash Media Server uses tag H263 with Sorenson Spark */
    if (st->codec->codec_tag == MKTAG('H','2','6','3') &&
1506
        !memcmp(codec_name, "Sorenson H263", 13))
1507 1508 1509 1510
        st->codec->codec_id = AV_CODEC_ID_FLV1;

    st->codec->bits_per_coded_sample = avio_rb16(pb); /* depth */
    color_table_id = avio_rb16(pb); /* colortable id */
1511
    av_log(c->fc, AV_LOG_TRACE, "depth %d, ctab id %d\n",
1512 1513 1514 1515
            st->codec->bits_per_coded_sample, color_table_id);
    /* figure out the palette situation */
    color_depth     = st->codec->bits_per_coded_sample & 0x1F;
    color_greyscale = st->codec->bits_per_coded_sample & 0x20;
1516 1517 1518
    /* Do not create a greyscale palette for cinepak */
    if (color_greyscale && st->codec->codec_id == AV_CODEC_ID_CINEPAK)
        return;
1519 1520 1521 1522 1523

    /* if the depth is 2, 4, or 8 bpp, file is palettized */
    if ((color_depth == 2) || (color_depth == 4) || (color_depth == 8)) {
        /* for palette traversal */
        unsigned int color_start, color_count, color_end;
1524
        unsigned char a, r, g, b;
1525 1526 1527 1528

        if (color_greyscale) {
            int color_index, color_dec;
            /* compute the greyscale palette */
1529
            st->codec->bits_per_coded_sample = color_depth;
1530 1531 1532 1533 1534
            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;
1535
                sc->palette[j] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554
                color_index -= color_dec;
                if (color_index < 0)
                    color_index = 0;
            }
        } else if (color_table_id) {
            const uint8_t *color_table;
            /* if flag bit 3 is set, use the default palette */
            color_count = 1 << color_depth;
            if (color_depth == 2)
                color_table = ff_qt_default_palette_4;
            else if (color_depth == 4)
                color_table = ff_qt_default_palette_16;
            else
                color_table = ff_qt_default_palette_256;

            for (j = 0; j < color_count; j++) {
                r = color_table[j * 3 + 0];
                g = color_table[j * 3 + 1];
                b = color_table[j * 3 + 2];
1555
                sc->palette[j] = (0xFFU << 24) | (r << 16) | (g << 8) | (b);
1556 1557 1558 1559 1560 1561 1562 1563
            }
        } else {
            /* load the palette from the file */
            color_start = avio_rb32(pb);
            color_count = avio_rb16(pb);
            color_end   = avio_rb16(pb);
            if ((color_start <= 255) && (color_end <= 255)) {
                for (j = color_start; j <= color_end; j++) {
1564 1565 1566
                    /* each A, R, G, or B component is 16 bits;
                        * only use the top 8 bits */
                    a = avio_r8(pb);
1567 1568 1569 1570 1571 1572 1573
                    avio_r8(pb);
                    r = avio_r8(pb);
                    avio_r8(pb);
                    g = avio_r8(pb);
                    avio_r8(pb);
                    b = avio_r8(pb);
                    avio_r8(pb);
1574
                    sc->palette[j] = (a << 24 ) | (r << 16) | (g << 8) | (b);
1575 1576 1577 1578 1579 1580 1581
                }
            }
        }
        sc->has_palette = 1;
    }
}

1582 1583 1584 1585 1586
static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb,
                                 AVStream *st, MOVStreamContext *sc)
{
    int bits_per_sample, flags;
    uint16_t version = avio_rb16(pb);
1587
    AVDictionaryEntry *compatible_brands = av_dict_get(c->fc->metadata, "compatible_brands", NULL, AV_DICT_MATCH_CASE);
1588 1589 1590 1591 1592 1593

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

    st->codec->channels              = avio_rb16(pb); /* channel count */
    st->codec->bits_per_coded_sample = avio_rb16(pb); /* sample size */
1594
    av_log(c->fc, AV_LOG_TRACE, "audio channels %d\n", st->codec->channels);
1595 1596 1597 1598 1599 1600 1601

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

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

    // Read QT version 1 fields. In version 0 these do not exist.
1602
    av_log(c->fc, AV_LOG_TRACE, "version =%d, isom =%d\n", version, c->isom);
1603 1604 1605
    if (!c->isom ||
        (compatible_brands && strstr(compatible_brands->value, "qt  "))) {

1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641
        if (version == 1) {
            sc->samples_per_frame = avio_rb32(pb);
            avio_rb32(pb); /* bytes per packet */
            sc->bytes_per_frame = avio_rb32(pb);
            avio_rb32(pb); /* bytes per sample */
        } else if (version == 2) {
            avio_rb32(pb); /* sizeof struct only */
            st->codec->sample_rate = av_int2double(avio_rb64(pb));
            st->codec->channels    = avio_rb32(pb);
            avio_rb32(pb); /* always 0x7F000000 */
            st->codec->bits_per_coded_sample = avio_rb32(pb);

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

    switch (st->codec->codec_id) {
    case AV_CODEC_ID_PCM_S8:
    case AV_CODEC_ID_PCM_U8:
        if (st->codec->bits_per_coded_sample == 16)
            st->codec->codec_id = AV_CODEC_ID_PCM_S16BE;
        break;
    case AV_CODEC_ID_PCM_S16LE:
    case AV_CODEC_ID_PCM_S16BE:
        if (st->codec->bits_per_coded_sample == 8)
            st->codec->codec_id = AV_CODEC_ID_PCM_S8;
        else if (st->codec->bits_per_coded_sample == 24)
            st->codec->codec_id =
                st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
                AV_CODEC_ID_PCM_S24BE : AV_CODEC_ID_PCM_S24LE;
1642 1643 1644 1645
        else if (st->codec->bits_per_coded_sample == 32)
             st->codec->codec_id =
                st->codec->codec_id == AV_CODEC_ID_PCM_S16BE ?
                AV_CODEC_ID_PCM_S32BE : AV_CODEC_ID_PCM_S32LE;
1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674
        break;
    /* set values for old format before stsd version 1 appeared */
    case AV_CODEC_ID_MACE3:
        sc->samples_per_frame = 6;
        sc->bytes_per_frame   = 2 * st->codec->channels;
        break;
    case AV_CODEC_ID_MACE6:
        sc->samples_per_frame = 6;
        sc->bytes_per_frame   = 1 * st->codec->channels;
        break;
    case AV_CODEC_ID_ADPCM_IMA_QT:
        sc->samples_per_frame = 64;
        sc->bytes_per_frame   = 34 * st->codec->channels;
        break;
    case AV_CODEC_ID_GSM:
        sc->samples_per_frame = 160;
        sc->bytes_per_frame   = 33;
        break;
    default:
        break;
    }

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

1675 1676
static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb,
                                    AVStream *st, MOVStreamContext *sc,
1677
                                    int64_t size)
1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688
{
    // ttxt stsd contains display flags, justification, background
    // color, fonts, and default styles, so fake an atom to read it
    MOVAtom fake_atom = { .size = size };
    // mp4s contains a regular esds atom
    if (st->codec->codec_tag != AV_RL32("mp4s"))
        mov_read_glbl(c, pb, fake_atom);
    st->codec->width  = sc->width;
    st->codec->height = sc->height;
}

1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722
static uint32_t yuv_to_rgba(uint32_t ycbcr)
{
    uint8_t r, g, b;
    int y, cb, cr;

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

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

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

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

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

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

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

1723
        av_strlcatf(buf, sizeof(buf), "%06"PRIx32"%s", rgba, i != 15 ? ", " : "");
1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739
    }

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

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

    return 0;
}

L
Luca Barbato 已提交
1740 1741
static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb,
                                AVStream *st, MOVStreamContext *sc,
1742
                                int64_t size)
L
Luca Barbato 已提交
1743 1744
{
    if (st->codec->codec_tag == MKTAG('t','m','c','d')) {
1745
        if ((int)size != size || ff_get_extradata(st->codec, pb, size) < 0)
L
Luca Barbato 已提交
1746
            return AVERROR(ENOMEM);
1747 1748 1749 1750 1751 1752 1753 1754 1755
        if (size > 16) {
            MOVStreamContext *tmcd_ctx = st->priv_data;
            int val;
            val = AV_RB32(st->codec->extradata + 4);
            tmcd_ctx->tmcd_flags = val;
            if (val & 1)
                st->codec->flags2 |= CODEC_FLAG2_DROP_FRAME_TIMECODE;
            st->codec->time_base.den = st->codec->extradata[16]; /* number of frame */
            st->codec->time_base.num = 1;
1756 1757 1758 1759 1760 1761 1762
            /* adjust for per frame dur in counter mode */
            if (tmcd_ctx->tmcd_flags & 0x0008) {
                int timescale = AV_RB32(st->codec->extradata + 8);
                int framedur = AV_RB32(st->codec->extradata + 12);
                st->codec->time_base.den *= timescale;
                st->codec->time_base.num *= framedur;
            }
1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782
            if (size > 30) {
                uint32_t len = AV_RB32(st->codec->extradata + 18); /* name atom length */
                uint32_t format = AV_RB32(st->codec->extradata + 22);
                if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
                    uint16_t str_size = AV_RB16(st->codec->extradata + 26); /* string length */
                    if (str_size > 0 && size >= (int)str_size + 26) {
                        char *reel_name = av_malloc(str_size + 1);
                        if (!reel_name)
                            return AVERROR(ENOMEM);
                        memcpy(reel_name, st->codec->extradata + 30, str_size);
                        reel_name[str_size] = 0; /* Add null terminator */
                        /* don't add reel_name if emtpy string */
                        if (*reel_name == 0) {
                            av_free(reel_name);
                        } else {
                            av_dict_set(&st->metadata, "reel_name", reel_name,  AV_DICT_DONT_STRDUP_VAL);
                        }
                    }
                }
            }
1783
        }
L
Luca Barbato 已提交
1784 1785 1786 1787 1788 1789 1790
    } else {
        /* other codec type, just skip (rtp, mp4s ...) */
        avio_skip(pb, size);
    }
    return 0;
}

1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817
static int mov_finalize_stsd_codec(MOVContext *c, AVIOContext *pb,
                                   AVStream *st, MOVStreamContext *sc)
{
    if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
        !st->codec->sample_rate && sc->time_scale > 1)
        st->codec->sample_rate = sc->time_scale;

    /* special codec parameters handling */
    switch (st->codec->codec_id) {
#if CONFIG_DV_DEMUXER
    case AV_CODEC_ID_DVAUDIO:
        c->dv_fctx  = avformat_alloc_context();
        c->dv_demux = avpriv_dv_init_demux(c->dv_fctx);
        if (!c->dv_demux) {
            av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
            return AVERROR(ENOMEM);
        }
        sc->dv_audio_container = 1;
        st->codec->codec_id    = AV_CODEC_ID_PCM_S16LE;
        break;
#endif
    /* no ifdef since parameters are always those */
    case AV_CODEC_ID_QCELP:
        st->codec->channels = 1;
        // force sample rate for qcelp when not stored in mov
        if (st->codec->codec_tag != MKTAG('Q','c','l','p'))
            st->codec->sample_rate = 8000;
1818 1819 1820 1821
        // FIXME: Why is the following needed for some files?
        sc->samples_per_frame = 160;
        if (!sc->bytes_per_frame)
            sc->bytes_per_frame = 35;
1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840 1841
        break;
    case AV_CODEC_ID_AMR_NB:
        st->codec->channels    = 1;
        /* force sample rate for amr, stsd in 3gp does not store sample rate */
        st->codec->sample_rate = 8000;
        break;
    case AV_CODEC_ID_AMR_WB:
        st->codec->channels    = 1;
        st->codec->sample_rate = 16000;
        break;
    case AV_CODEC_ID_MP2:
    case AV_CODEC_ID_MP3:
        /* force type after stsd for m1a hdlr */
        st->codec->codec_type = AVMEDIA_TYPE_AUDIO;
        st->need_parsing      = AVSTREAM_PARSE_FULL;
        break;
    case AV_CODEC_ID_GSM:
    case AV_CODEC_ID_ADPCM_MS:
    case AV_CODEC_ID_ADPCM_IMA_WAV:
    case AV_CODEC_ID_ILBC:
1842 1843 1844
    case AV_CODEC_ID_MACE3:
    case AV_CODEC_ID_MACE6:
    case AV_CODEC_ID_QDM2:
1845 1846 1847 1848 1849 1850 1851 1852
        st->codec->block_align = sc->bytes_per_frame;
        break;
    case AV_CODEC_ID_ALAC:
        if (st->codec->extradata_size == 36) {
            st->codec->channels    = AV_RB8 (st->codec->extradata + 21);
            st->codec->sample_rate = AV_RB32(st->codec->extradata + 32);
        }
        break;
1853
    case AV_CODEC_ID_AC3:
1854
    case AV_CODEC_ID_EAC3:
1855
    case AV_CODEC_ID_MPEG1VIDEO:
1856 1857 1858 1859 1860 1861 1862 1863 1864
    case AV_CODEC_ID_VC1:
        st->need_parsing = AVSTREAM_PARSE_FULL;
        break;
    default:
        break;
    }
    return 0;
}

1865 1866
static int mov_skip_multiple_stsd(MOVContext *c, AVIOContext *pb,
                                  int codec_tag, int format,
1867
                                  int64_t size)
1868 1869 1870 1871 1872 1873
{
    int video_codec_id = ff_codec_get_id(ff_codec_movvideo_tags, format);

    if (codec_tag &&
         (codec_tag != format &&
          (c->fc->video_codec_id ? video_codec_id != c->fc->video_codec_id
1874
                                 : codec_tag != MKTAG('j','p','e','g')))) {
1875 1876 1877 1878 1879 1880 1881 1882
        /* Multiple fourcc, we skip JPEG. This is not correct, we should
         * export it as a separate AVStream but this needs a few changes
         * in the MOV demuxer, patch welcome. */

        av_log(c->fc, AV_LOG_WARNING, "multiple fourcc not supported\n");
        avio_skip(pb, size);
        return 1;
    }
Y
Yusuke Nakamura 已提交
1883 1884 1885 1886
    if ( codec_tag == AV_RL32("avc1") ||
         codec_tag == AV_RL32("hvc1") ||
         codec_tag == AV_RL32("hev1")
    )
1887
        av_log(c->fc, AV_LOG_WARNING, "Concatenated H.264 or H.265 might not play correctly.\n");
1888 1889 1890 1891

    return 0;
}

1892
int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
1893
{
1894 1895
    AVStream *st;
    MOVStreamContext *sc;
1896
    int pseudo_stream_id;
1897

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

1903 1904 1905
    for (pseudo_stream_id = 0;
         pseudo_stream_id < entries && !pb->eof_reached;
         pseudo_stream_id++) {
1906
        //Parsing Sample description table
1907
        enum AVCodecID id;
L
Luca Barbato 已提交
1908
        int ret, dref_id = 1;
1909
        MOVAtom a = { AV_RL32("stsd") };
1910
        int64_t start_pos = avio_tell(pb);
1911
        int64_t size = avio_rb32(pb); /* size */
1912
        uint32_t format = avio_rl32(pb); /* data format */
1913

1914
        if (size >= 16) {
1915 1916 1917
            avio_rb32(pb); /* reserved */
            avio_rb16(pb); /* reserved */
            dref_id = avio_rb16(pb);
1918
        }else if (size <= 7){
M
Michael Niedermayer 已提交
1919
            av_log(c->fc, AV_LOG_ERROR, "invalid size %"PRId64" in stsd\n", size);
1920
            return AVERROR_INVALIDDATA;
1921
        }
1922

1923 1924
        if (mov_skip_multiple_stsd(c, pb, st->codec->codec_tag, format,
                                   size - (avio_tell(pb) - start_pos)))
1925
            continue;
1926

1927
        sc->pseudo_stream_id = st->codec->codec_tag ? -1 : pseudo_stream_id;
1928
        sc->dref_id= dref_id;
1929

1930
        id = mov_codec_id(st, format);
1931

1932
        av_log(c->fc, AV_LOG_TRACE, "size=%"PRId64" 4CC= %c%c%c%c codec_type=%d\n", size,
1933 1934
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
                (format >> 24) & 0xff, st->codec->codec_type);
1935

1936
        if (st->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
1937
            st->codec->codec_id = id;
1938
            mov_parse_stsd_video(c, pb, st, sc);
1939
        } else if (st->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
1940
            st->codec->codec_id = id;
1941
            mov_parse_stsd_audio(c, pb, st, sc);
1942
        } else if (st->codec->codec_type==AVMEDIA_TYPE_SUBTITLE){
1943 1944 1945
            st->codec->codec_id = id;
            mov_parse_stsd_subtitle(c, pb, st, sc,
                                    size - (avio_tell(pb) - start_pos));
1946
        } else {
L
Luca Barbato 已提交
1947 1948 1949 1950
            ret = mov_parse_stsd_data(c, pb, st, sc,
                                      size - (avio_tell(pb) - start_pos));
            if (ret < 0)
                return ret;
1951
        }
Y
Yusuke Nakamura 已提交
1952
        /* this will read extra atoms at the end (wave, alac, damr, avcC, hvcC, SMI ...) */
1953
        a.size = size - (avio_tell(pb) - start_pos);
1954
        if (a.size > 8) {
1955 1956
            if ((ret = mov_read_default(c, pb, a)) < 0)
                return ret;
1957
        } else if (a.size > 0)
1958
            avio_skip(pb, a.size);
1959
    }
1960

1961 1962 1963
    if (pb->eof_reached)
        return AVERROR_EOF;

1964
    return mov_finalize_stsd_codec(c, pb, st, sc);
1965 1966
}

1967
static int mov_read_stsd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1968 1969 1970
{
    int entries;

1971 1972 1973
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
1974 1975 1976 1977

    return ff_mov_read_stsd_entries(c, pb, entries);
}

1978
static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom)
1979
{
1980 1981
    AVStream *st;
    MOVStreamContext *sc;
1982
    unsigned int i, entries;
1983

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

1989 1990
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
1991

1992
    entries = avio_rb32(pb);
1993

1994
    av_log(c->fc, AV_LOG_TRACE, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1995

A
Alex Converse 已提交
1996 1997
    if (!entries)
        return 0;
1998
    if (sc->stsc_data)
1999
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n");
2000 2001
    av_free(sc->stsc_data);
    sc->stsc_count = 0;
2002
    sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data));
2003
    if (!sc->stsc_data)
2004 2005
        return AVERROR(ENOMEM);

2006
    for (i = 0; i < entries && !pb->eof_reached; i++) {
2007 2008 2009
        sc->stsc_data[i].first = avio_rb32(pb);
        sc->stsc_data[i].count = avio_rb32(pb);
        sc->stsc_data[i].id = avio_rb32(pb);
2010
    }
2011 2012 2013 2014 2015 2016

    sc->stsc_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

2017 2018 2019
    return 0;
}

2020
static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2021 2022 2023 2024 2025 2026 2027 2028 2029 2030
{
    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;

2031
    avio_rb32(pb); // version + flags
2032

2033
    entries = avio_rb32(pb);
2034
    if (sc->stps_data)
2035
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STPS atom\n");
2036 2037 2038
    av_free(sc->stps_data);
    sc->stps_count = 0;
    sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data));
2039 2040 2041
    if (!sc->stps_data)
        return AVERROR(ENOMEM);

2042
    for (i = 0; i < entries && !pb->eof_reached; i++) {
2043
        sc->stps_data[i] = avio_rb32(pb);
2044
        //av_log(c->fc, AV_LOG_TRACE, "stps %d\n", sc->stps_data[i]);
2045 2046
    }

2047 2048 2049 2050 2051
    sc->stps_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

2052 2053 2054
    return 0;
}

2055
static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2056
{
2057 2058
    AVStream *st;
    MOVStreamContext *sc;
2059
    unsigned int i, entries;
2060

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

2066 2067
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
2068

2069
    entries = avio_rb32(pb);
2070

2071
    av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %d\n", entries);
2072

2073
    if (!entries)
2074 2075
    {
        sc->keyframe_absent = 1;
2076
        if (!st->need_parsing && st->codec->codec_type == AVMEDIA_TYPE_VIDEO)
2077
            st->need_parsing = AVSTREAM_PARSE_HEADERS;
2078
        return 0;
2079
    }
2080
    if (sc->keyframes)
2081
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STSS atom\n");
2082
    if (entries >= UINT_MAX / sizeof(int))
2083
        return AVERROR_INVALIDDATA;
2084
    av_freep(&sc->keyframes);
2085 2086
    sc->keyframe_count = 0;
    sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes));
2087
    if (!sc->keyframes)
2088 2089
        return AVERROR(ENOMEM);

2090
    for (i = 0; i < entries && !pb->eof_reached; i++) {
2091
        sc->keyframes[i] = avio_rb32(pb);
2092
        //av_log(c->fc, AV_LOG_TRACE, "keyframes[]=%d\n", sc->keyframes[i]);
2093
    }
2094 2095 2096 2097 2098 2099

    sc->keyframe_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

2100 2101 2102
    return 0;
}

2103
static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2104
{
2105 2106
    AVStream *st;
    MOVStreamContext *sc;
2107 2108 2109
    unsigned int i, entries, sample_size, field_size, num_bytes;
    GetBitContext gb;
    unsigned char* buf;
2110

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

2116 2117
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
2118

2119
    if (atom.type == MKTAG('s','t','s','z')) {
2120
        sample_size = avio_rb32(pb);
2121 2122
        if (!sc->sample_size) /* do not overwrite value computed in stsd */
            sc->sample_size = sample_size;
2123
        sc->stsz_sample_size = sample_size;
2124
        field_size = 32;
2125 2126
    } else {
        sample_size = 0;
2127 2128
        avio_rb24(pb); /* reserved */
        field_size = avio_r8(pb);
2129
    }
2130
    entries = avio_rb32(pb);
2131

2132
    av_log(c->fc, AV_LOG_TRACE, "sample_size = %d sample_count = %d\n", sc->sample_size, entries);
2133

2134
    sc->sample_count = entries;
2135 2136 2137
    if (sample_size)
        return 0;

2138 2139
    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);
2140
        return AVERROR_INVALIDDATA;
2141 2142
    }

A
Alex Converse 已提交
2143 2144
    if (!entries)
        return 0;
2145
    if (entries >= (UINT_MAX - 4) / field_size)
2146
        return AVERROR_INVALIDDATA;
2147
    if (sc->sample_sizes)
2148
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STSZ atom\n");
2149 2150 2151
    av_free(sc->sample_sizes);
    sc->sample_count = 0;
    sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes));
2152
    if (!sc->sample_sizes)
2153 2154
        return AVERROR(ENOMEM);

2155 2156
    num_bytes = (entries*field_size+4)>>3;

2157
    buf = av_malloc(num_bytes+FF_INPUT_BUFFER_PADDING_SIZE);
2158 2159 2160 2161 2162
    if (!buf) {
        av_freep(&sc->sample_sizes);
        return AVERROR(ENOMEM);
    }

2163
    if (avio_read(pb, buf, num_bytes) < num_bytes) {
2164 2165
        av_freep(&sc->sample_sizes);
        av_free(buf);
2166
        return AVERROR_INVALIDDATA;
2167 2168 2169 2170
    }

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

2171
    for (i = 0; i < entries && !pb->eof_reached; i++) {
2172
        sc->sample_sizes[i] = get_bits_long(&gb, field_size);
2173 2174
        sc->data_size += sc->sample_sizes[i];
    }
2175

2176 2177 2178 2179 2180
    sc->sample_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

2181
    av_free(buf);
2182 2183 2184
    return 0;
}

2185
static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2186
{
2187 2188
    AVStream *st;
    MOVStreamContext *sc;
2189
    unsigned int i, entries;
2190 2191
    int64_t duration=0;
    int64_t total_sample_count=0;
2192

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

2198 2199 2200
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
2201

2202
    av_log(c->fc, AV_LOG_TRACE, "track[%i].stts.entries = %i\n",
2203
            c->fc->nb_streams-1, entries);
2204

2205
    if (sc->stts_data)
2206
        av_log(c->fc, AV_LOG_WARNING, "Duplicated STTS atom\n");
2207
    av_free(sc->stts_data);
2208 2209
    sc->stts_count = 0;
    sc->stts_data = av_malloc_array(entries, sizeof(*sc->stts_data));
2210
    if (!sc->stts_data)
2211
        return AVERROR(ENOMEM);
2212

2213
    for (i = 0; i < entries && !pb->eof_reached; i++) {
M
cleanup  
Michael Niedermayer 已提交
2214 2215
        int sample_duration;
        int sample_count;
2216

2217 2218
        sample_count=avio_rb32(pb);
        sample_duration = avio_rb32(pb);
2219

2220 2221
        /* sample_duration < 0 is invalid based on the spec */
        if (sample_duration < 0) {
2222 2223
            av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta %d in STTS, at %d st:%d\n",
                   sample_duration, i, c->fc->nb_streams-1);
2224 2225
            sample_duration = 1;
        }
2226 2227 2228 2229
        if (sample_count < 0) {
            av_log(c->fc, AV_LOG_ERROR, "Invalid sample_count=%d\n", sample_count);
            return AVERROR_INVALIDDATA;
        }
2230 2231 2232
        sc->stts_data[i].count= sample_count;
        sc->stts_data[i].duration= sample_duration;

2233
        av_log(c->fc, AV_LOG_TRACE, "sample_count=%d, sample_duration=%d\n",
2234
                sample_count, sample_duration);
2235

2236 2237 2238 2239 2240 2241
        if (   i+1 == entries
            && i
            && sample_count == 1
            && total_sample_count > 100
            && sample_duration/10 > duration / total_sample_count)
            sample_duration = duration / total_sample_count;
B
Baptiste Coudurier 已提交
2242
        duration+=(int64_t)sample_duration*sample_count;
2243 2244 2245
        total_sample_count+=sample_count;
    }

2246 2247
    sc->stts_count = i;

2248 2249 2250
    sc->duration_for_fps  += duration;
    sc->nb_frames_for_fps += total_sample_count;

2251 2252 2253
    if (pb->eof_reached)
        return AVERROR_EOF;

2254
    st->nb_frames= total_sample_count;
2255
    if (duration)
2256
        st->duration= duration;
2257
    sc->track_end = duration;
2258 2259 2260
    return 0;
}

2261 2262 2263 2264 2265 2266 2267
static void mov_update_dts_shift(MOVStreamContext *sc, int duration)
{
    if (duration < 0) {
        sc->dts_shift = FFMAX(sc->dts_shift, -duration);
    }
}

2268
static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
M
Michael Niedermayer 已提交
2269
{
2270 2271
    AVStream *st;
    MOVStreamContext *sc;
M
Michael Niedermayer 已提交
2272 2273
    unsigned int i, entries;

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

2279 2280 2281
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    entries = avio_rb32(pb);
2282

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

A
Alex Converse 已提交
2285 2286
    if (!entries)
        return 0;
2287
    if (entries >= UINT_MAX / sizeof(*sc->ctts_data))
2288
        return AVERROR_INVALIDDATA;
2289
    sc->ctts_data = av_malloc(entries * sizeof(*sc->ctts_data));
2290
    if (!sc->ctts_data)
2291
        return AVERROR(ENOMEM);
2292

2293
    for (i = 0; i < entries && !pb->eof_reached; i++) {
2294 2295
        int count    =avio_rb32(pb);
        int duration =avio_rb32(pb);
2296 2297 2298

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

2300
        av_log(c->fc, AV_LOG_TRACE, "count=%d, duration=%d\n",
2301 2302
                count, duration);

M
Michael Niedermayer 已提交
2303 2304 2305 2306 2307 2308 2309
        if (FFABS(duration) > (1<<28) && i+2<entries) {
            av_log(c->fc, AV_LOG_WARNING, "CTTS invalid\n");
            av_freep(&sc->ctts_data);
            sc->ctts_count = 0;
            return 0;
        }

2310 2311
        if (i+2<entries)
            mov_update_dts_shift(sc, duration);
M
Michael Niedermayer 已提交
2312
    }
2313

2314 2315 2316 2317 2318
    sc->ctts_count = i;

    if (pb->eof_reached)
        return AVERROR_EOF;

2319
    av_log(c->fc, AV_LOG_TRACE, "dts shift %d\n", sc->dts_shift);
2320

M
Michael Niedermayer 已提交
2321 2322 2323
    return 0;
}

2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336 2337 2338 2339 2340 2341 2342 2343 2344 2345 2346 2347
static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    AVStream *st;
    MOVStreamContext *sc;
    unsigned int i, entries;
    uint8_t version;
    uint32_t grouping_type;

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

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

    entries = avio_rb32(pb);
    if (!entries)
        return 0;
2348
    if (sc->rap_group)
2349
        av_log(c->fc, AV_LOG_WARNING, "Duplicated SBGP atom\n");
2350 2351 2352
    av_free(sc->rap_group);
    sc->rap_group_count = 0;
    sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group));
2353 2354 2355 2356 2357 2358 2359 2360 2361 2362 2363 2364 2365
    if (!sc->rap_group)
        return AVERROR(ENOMEM);

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

    sc->rap_group_count = i;

    return pb->eof_reached ? AVERROR_EOF : 0;
}

2366 2367 2368
static void mov_build_index(MOVContext *mov, AVStream *st)
{
    MOVStreamContext *sc = st->priv_data;
2369
    int64_t current_offset;
2370 2371 2372 2373
    int64_t current_dts = 0;
    unsigned int stts_index = 0;
    unsigned int stsc_index = 0;
    unsigned int stss_index = 0;
2374
    unsigned int stps_index = 0;
2375
    unsigned int i, j;
2376
    uint64_t stream_size = 0;
2377

2378 2379 2380 2381 2382 2383 2384 2385 2386 2387 2388 2389 2390 2391 2392 2393 2394 2395 2396 2397 2398
    if (sc->elst_count) {
        int i, edit_start_index = 0, unsupported = 0;
        int64_t empty_duration = 0; // empty duration of the first edit list entry
        int64_t start_time = 0; // start time of the media

        for (i = 0; i < sc->elst_count; i++) {
            const MOVElst *e = &sc->elst_data[i];
            if (i == 0 && e->time == -1) {
                /* if empty, the first entry is the start time of the stream
                 * relative to the presentation itself */
                empty_duration = e->duration;
                edit_start_index = 1;
            } else if (i == edit_start_index && e->time >= 0) {
                start_time = e->time;
            } else
                unsupported = 1;
        }
        if (unsupported)
            av_log(mov->fc, AV_LOG_WARNING, "multiple edit list entries, "
                   "a/v desync might occur, patch welcome\n");

2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411
        /* adjust first dts according to edit list */
        if ((empty_duration || start_time) && mov->time_scale > 0) {
            if (empty_duration)
                empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale);
            sc->time_offset = start_time - empty_duration;
            current_dts = -sc->time_offset;
            if (sc->ctts_count>0 && sc->stts_count>0 &&
                sc->ctts_data[0].duration / FFMAX(sc->stts_data[0].duration, 1) > 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;
            }
2412
        }
2413 2414
    }

2415
    /* only use old uncompressed audio chunk demuxing when stts specifies it */
2416
    if (!(st->codec->codec_type == AVMEDIA_TYPE_AUDIO &&
2417
          sc->stts_count == 1 && sc->stts_data[0].duration == 1)) {
2418 2419
        unsigned int current_sample = 0;
        unsigned int stts_sample = 0;
2420
        unsigned int sample_size;
2421
        unsigned int distance = 0;
2422 2423 2424
        unsigned int rap_group_index = 0;
        unsigned int rap_group_sample = 0;
        int rap_group_present = sc->rap_group_count && sc->rap_group;
2425
        int key_off = (sc->keyframe_count && sc->keyframes[0] > 0) || (sc->stps_count && sc->stps_data[0] > 0);
2426

2427 2428
        current_dts -= sc->dts_shift;

2429
        if (!sc->sample_count || st->nb_index_entries)
A
Alex Converse 已提交
2430
            return;
2431
        if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
2432
            return;
2433 2434 2435 2436
        if (av_reallocp_array(&st->index_entries,
                              st->nb_index_entries + sc->sample_count,
                              sizeof(*st->index_entries)) < 0) {
            st->nb_index_entries = 0;
2437
            return;
2438
        }
2439
        st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries);
2440

2441
        for (i = 0; i < sc->chunk_count; i++) {
2442
            int64_t next_offset = i+1 < sc->chunk_count ? sc->chunk_offsets[i+1] : INT64_MAX;
2443
            current_offset = sc->chunk_offsets[i];
2444
            while (stsc_index + 1 < sc->stsc_count &&
2445
                i + 1 == sc->stsc_data[stsc_index + 1].first)
2446
                stsc_index++;
2447 2448 2449 2450 2451 2452 2453 2454 2455 2456 2457

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

2458
            for (j = 0; j < sc->stsc_data[stsc_index].count; j++) {
2459
                int keyframe = 0;
2460 2461
                if (current_sample >= sc->sample_count) {
                    av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
2462
                    return;
2463
                }
2464

2465
                if (!sc->keyframe_absent && (!sc->keyframe_count || current_sample+key_off == sc->keyframes[stss_index])) {
2466
                    keyframe = 1;
2467 2468
                    if (stss_index + 1 < sc->keyframe_count)
                        stss_index++;
2469 2470 2471 2472
                } 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++;
2473
                }
2474 2475 2476 2477 2478 2479 2480 2481
                if (rap_group_present && rap_group_index < sc->rap_group_count) {
                    if (sc->rap_group[rap_group_index].index > 0)
                        keyframe = 1;
                    if (++rap_group_sample == sc->rap_group[rap_group_index].count) {
                        rap_group_sample = 0;
                        rap_group_index++;
                    }
                }
2482 2483 2484
                if (sc->keyframe_absent
                    && !sc->stps_count
                    && !rap_group_present
2485
                    && (st->codec->codec_type == AVMEDIA_TYPE_AUDIO || (i==0 && j==0)))
2486
                     keyframe = 1;
2487 2488
                if (keyframe)
                    distance = 0;
2489
                sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample];
2490
                if (sc->pseudo_stream_id == -1 ||
2491
                   sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) {
2492 2493
                    AVIndexEntry *e = &st->index_entries[st->nb_index_entries++];
                    e->pos = current_offset;
2494
                    e->timestamp = current_dts;
2495 2496 2497
                    e->size = sample_size;
                    e->min_distance = distance;
                    e->flags = keyframe ? AVINDEX_KEYFRAME : 0;
2498
                    av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
2499
                            "size %d, distance %d, keyframe %d\n", st->index, current_sample,
2500
                            current_offset, current_dts, sample_size, distance, keyframe);
2501
                    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100)
2502
                        ff_rfps_add_frame(mov->fc, st, current_dts);
2503
                }
2504

2505
                current_offset += sample_size;
2506
                stream_size += sample_size;
2507
                current_dts += sc->stts_data[stts_index].duration;
2508 2509 2510 2511 2512 2513 2514 2515 2516
                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++;
                }
            }
        }
2517 2518
        if (st->duration > 0)
            st->codec->bit_rate = stream_size*8*sc->time_scale/st->duration;
2519
    } else {
2520
        unsigned chunk_samples, total = 0;
2521

2522 2523 2524
        // compute total chunk count
        for (i = 0; i < sc->stsc_count; i++) {
            unsigned count, chunk_count;
2525

2526
            chunk_samples = sc->stsc_data[i].count;
2527 2528
            if (i != sc->stsc_count - 1 &&
                sc->samples_per_frame && chunk_samples % sc->samples_per_frame) {
2529 2530 2531 2532
                av_log(mov->fc, AV_LOG_ERROR, "error unaligned chunk\n");
                return;
            }

2533 2534 2535 2536 2537 2538 2539 2540 2541 2542 2543 2544 2545 2546 2547 2548
            if (sc->samples_per_frame >= 160) { // gsm
                count = chunk_samples / sc->samples_per_frame;
            } else if (sc->samples_per_frame > 1) {
                unsigned samples = (1024/sc->samples_per_frame)*sc->samples_per_frame;
                count = (chunk_samples+samples-1) / samples;
            } else {
                count = (chunk_samples+1023) / 1024;
            }

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

2549
        av_log(mov->fc, AV_LOG_TRACE, "chunk count %d\n", total);
2550
        if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries)
2551
            return;
2552 2553 2554 2555
        if (av_reallocp_array(&st->index_entries,
                              st->nb_index_entries + total,
                              sizeof(*st->index_entries)) < 0) {
            st->nb_index_entries = 0;
2556
            return;
2557
        }
2558
        st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries);
2559 2560 2561 2562 2563 2564 2565 2566 2567

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

2568
            while (chunk_samples > 0) {
2569
                AVIndexEntry *e;
2570 2571 2572 2573 2574 2575 2576 2577 2578 2579
                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;
2580
                    } else {
2581 2582
                        samples = FFMIN(1024, chunk_samples);
                        size = samples * sc->sample_size;
2583 2584
                    }
                }
2585

2586 2587 2588 2589 2590 2591 2592 2593 2594 2595
                if (st->nb_index_entries >= total) {
                    av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %d\n", total);
                    return;
                }
                e = &st->index_entries[st->nb_index_entries++];
                e->pos = current_offset;
                e->timestamp = current_dts;
                e->size = size;
                e->min_distance = 0;
                e->flags = AVINDEX_KEYFRAME;
2596
                av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", "
2597
                        "size %d, duration %d\n", st->index, i, current_offset, current_dts,
2598 2599 2600
                        size, samples);

                current_offset += size;
2601
                current_dts += samples;
2602
                chunk_samples -= samples;
2603 2604 2605 2606
            }
        }
    }
}
2607

2608 2609
static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDref *ref,
                         AVIOInterruptCB *int_cb)
2610
{
2611 2612 2613 2614 2615
    AVOpenCallback open_func = c->fc->open_cb;

    if (!open_func)
        open_func = ffio_open2_wrapper;

2616 2617
    /* try relative path, we do not try the absolute because it can leak information about our
       system to an attacker */
2618
    if (ref->nlvl_to > 0 && ref->nlvl_from > 0 && ref->path[0] != '/') {
2619
        char filename[1025];
2620
        const char *src_path;
2621 2622 2623 2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639
        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 */
2640
        if (i == ref->nlvl_to - 1 && src_path - src  < sizeof(filename)) {
2641 2642 2643 2644
            memcpy(filename, src, src_path - src);
            filename[src_path - src] = 0;

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

2647
            av_strlcat(filename, ref->path + l + 1, sizeof(filename));
2648
            if (!c->use_absolute_path && !c->fc->open_cb)
2649 2650
                if(strstr(ref->path + l + 1, "..") || ref->nlvl_from > 1)
                    return AVERROR(ENOENT);
2651

2652 2653
            if (strlen(filename) + 1 == sizeof(filename))
                return AVERROR(ENOENT);
2654
            if (!open_func(c->fc, pb, filename, AVIO_FLAG_READ, int_cb, NULL))
2655 2656
                return 0;
        }
2657 2658
    } else if (c->use_absolute_path) {
        av_log(c->fc, AV_LOG_WARNING, "Using absolute path on user request, "
2659
               "this is a possible security issue\n");
2660 2661 2662 2663
        if (!open_func(c->fc, pb, ref->path, AVIO_FLAG_READ, int_cb, NULL))
            return 0;
    } else if (c->fc->open_cb) {
        if (!open_func(c->fc, pb, ref->path, AVIO_FLAG_READ, int_cb, NULL))
2664
            return 0;
2665 2666 2667 2668 2669
    } else {
        av_log(c->fc, AV_LOG_ERROR,
               "Absolute path %s not tried for security reasons, "
               "set demuxer option use_absolute_path to allow absolute paths\n",
               ref->path);
2670 2671 2672
    }

    return AVERROR(ENOENT);
M
Mans Rullgard 已提交
2673
}
2674

2675 2676 2677 2678 2679 2680 2681 2682 2683 2684
static void fix_timescale(MOVContext *c, MOVStreamContext *sc)
{
    if (sc->time_scale <= 0) {
        av_log(c->fc, AV_LOG_WARNING, "stream %d, timescale not set\n", sc->ffindex);
        sc->time_scale = c->time_scale;
        if (sc->time_scale <= 0)
            sc->time_scale = 1;
    }
}

2685
static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2686 2687 2688
{
    AVStream *st;
    MOVStreamContext *sc;
2689
    int ret;
2690

2691
    st = avformat_new_stream(c->fc, NULL);
B
Baptiste Coudurier 已提交
2692
    if (!st) return AVERROR(ENOMEM);
2693
    st->id = c->fc->nb_streams;
B
Baptiste Coudurier 已提交
2694
    sc = av_mallocz(sizeof(MOVStreamContext));
2695
    if (!sc) return AVERROR(ENOMEM);
2696 2697

    st->priv_data = sc;
2698
    st->codec->codec_type = AVMEDIA_TYPE_DATA;
2699
    sc->ffindex = st->index;
2700

2701 2702 2703 2704
    if ((ret = mov_read_default(c, pb, atom)) < 0)
        return ret;

    /* sanity checks */
2705 2706
    if (sc->chunk_count && (!sc->stts_count || !sc->stsc_count ||
                            (!sc->sample_size && !sc->sample_count))) {
2707 2708
        av_log(c->fc, AV_LOG_ERROR, "stream %d, missing mandatory atoms, broken header\n",
               st->index);
2709 2710
        return 0;
    }
2711

2712
    fix_timescale(c, sc);
2713

2714
    avpriv_set_pts_info(st, 64, 1, sc->time_scale);
2715 2716 2717 2718

    mov_build_index(c, st);

    if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) {
2719
        MOVDref *dref = &sc->drefs[sc->dref_id - 1];
2720 2721
        if (mov_open_dref(c, &sc->pb, c->fc->filename, dref,
                          &c->fc->interrupt_callback) < 0)
2722 2723 2724 2725 2726
            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);
2727
    } else {
2728
        sc->pb = c->fc->pb;
2729 2730
        sc->pb_is_copied = 1;
    }
2731

2732
    if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
2733 2734
        if (!st->sample_aspect_ratio.num && st->codec->width && st->codec->height &&
            sc->height && sc->width &&
2735 2736 2737
            (st->codec->width != sc->width || st->codec->height != sc->height)) {
            st->sample_aspect_ratio = av_d2q(((double)st->codec->height * sc->width) /
                                             ((double)st->codec->width * sc->height), INT_MAX);
2738 2739
        }

A
Anton Khirnov 已提交
2740
#if FF_API_R_FRAME_RATE
2741 2742 2743
        if (sc->stts_count == 1 || (sc->stts_count == 2 && sc->stts_data[1].count == 1))
            av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den,
                      sc->time_scale, sc->stts_data[0].duration, INT_MAX);
A
Anton Khirnov 已提交
2744
#endif
2745 2746
    }

R
Reimar Döffinger 已提交
2747 2748
    // done for ai5q, ai52, ai55, ai1q, ai12 and ai15.
    if (!st->codec->extradata_size && st->codec->codec_id == AV_CODEC_ID_H264 &&
2749 2750 2751 2752
        TAG_IS_AVCI(st->codec->codec_tag)) {
        ret = ff_generate_avci_extradata(st);
        if (ret < 0)
            return ret;
R
Reimar Döffinger 已提交
2753 2754
    }

2755
    switch (st->codec->codec_id) {
2756
#if CONFIG_H261_DECODER
2757
    case AV_CODEC_ID_H261:
2758
#endif
2759
#if CONFIG_H263_DECODER
2760
    case AV_CODEC_ID_H263:
2761
#endif
2762
#if CONFIG_MPEG4_DECODER
2763
    case AV_CODEC_ID_MPEG4:
2764
#endif
2765
        st->codec->width = 0; /* let decoder init width/height */
2766 2767 2768
        st->codec->height= 0;
        break;
    }
B
Baptiste Coudurier 已提交
2769 2770 2771

    /* Do not need those anymore. */
    av_freep(&sc->chunk_offsets);
2772
    av_freep(&sc->stsc_data);
B
Baptiste Coudurier 已提交
2773 2774 2775
    av_freep(&sc->sample_sizes);
    av_freep(&sc->keyframes);
    av_freep(&sc->stts_data);
2776
    av_freep(&sc->stps_data);
2777
    av_freep(&sc->elst_data);
2778
    av_freep(&sc->rap_group);
B
Baptiste Coudurier 已提交
2779

2780
    return 0;
2781 2782
}

2783
static int mov_read_ilst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2784 2785 2786 2787 2788 2789 2790 2791
{
    int ret;
    c->itunes_metadata = 1;
    ret = mov_read_default(c, pb, atom);
    c->itunes_metadata = 0;
    return ret;
}

2792
static int mov_read_custom_2plus(MOVContext *c, AVIOContext *pb, int size)
2793 2794 2795 2796
{
    int64_t end = avio_tell(pb) + size;
    uint8_t *key = NULL, *val = NULL;
    int i;
2797 2798 2799 2800 2801 2802 2803
    AVStream *st;
    MOVStreamContext *sc;

    if (c->fc->nb_streams < 1)
        return 0;
    st = c->fc->streams[c->fc->nb_streams-1];
    sc = st->priv_data;
2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 2825 2826 2827 2828 2829 2830 2831 2832 2833 2834 2835 2836

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

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

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

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

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

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

    if (key && val) {
2837 2838 2839 2840 2841 2842
        if (strcmp(key, "iTunSMPB") == 0) {
            int priming, remainder, samples;
            if(sscanf(val, "%*X %X %X %X", &priming, &remainder, &samples) == 3){
                if(priming>0 && priming<16384)
                    sc->start_pad = priming;
            }
2843 2844
        }
        if (strcmp(key, "cdec") != 0) {
2845 2846 2847 2848
            av_dict_set(&c->fc->metadata, key, val,
                        AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL);
            key = val = NULL;
        }
2849 2850 2851 2852 2853 2854 2855 2856 2857 2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 2873 2874 2875 2876 2877 2878 2879
    }

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

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

    if (atom.size < 8)
        goto fail;

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

    if (len > atom.size)
        goto fail;

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

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

        domain_len = avio_get_str(pb, len, domain, sizeof(domain));
        avio_skip(pb, len - domain_len);
2880
        return mov_read_custom_2plus(c, pb, end - avio_tell(pb));
2881 2882 2883 2884 2885 2886 2887 2888
    }

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

2889
static int mov_read_meta(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2890
{
2891
    while (atom.size > 8) {
2892
        uint32_t tag = avio_rl32(pb);
2893 2894
        atom.size -= 4;
        if (tag == MKTAG('h','d','l','r')) {
A
Anton Khirnov 已提交
2895
            avio_seek(pb, -8, SEEK_CUR);
2896 2897 2898 2899 2900
            atom.size += 8;
            return mov_read_default(c, pb, atom);
        }
    }
    return 0;
2901 2902
}

2903
static int mov_read_tkhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
2904
{
2905 2906 2907
    int i;
    int width;
    int height;
2908
    int display_matrix[3][3];
2909 2910 2911
    AVStream *st;
    MOVStreamContext *sc;
    int version;
2912
    int flags;
2913 2914 2915 2916 2917

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

2919
    version = avio_r8(pb);
2920 2921
    flags = avio_rb24(pb);
    st->disposition |= (flags & MOV_TKHD_FLAG_ENABLED) ? AV_DISPOSITION_DEFAULT : 0;
2922

B
Baptiste Coudurier 已提交
2923
    if (version == 1) {
2924 2925
        avio_rb64(pb);
        avio_rb64(pb);
B
Baptiste Coudurier 已提交
2926
    } else {
2927 2928
        avio_rb32(pb); /* creation time */
        avio_rb32(pb); /* modification time */
B
Baptiste Coudurier 已提交
2929
    }
2930 2931
    st->id = (int)avio_rb32(pb); /* track id (NOT 0 !)*/
    avio_rb32(pb); /* reserved */
2932

2933
    /* highlevel (considering edits) duration in movie timebase */
2934 2935 2936
    (version == 1) ? avio_rb64(pb) : avio_rb32(pb);
    avio_rb32(pb); /* reserved */
    avio_rb32(pb); /* reserved */
2937

2938 2939 2940 2941
    avio_rb16(pb); /* layer */
    avio_rb16(pb); /* alternate group */
    avio_rb16(pb); /* volume */
    avio_rb16(pb); /* reserved */
2942

2943 2944
    //read in the display matrix (outlined in ISO 14496-12, Section 6.2.2)
    // they're kept in fixed point format through all calculations
2945 2946
    // save u,v,z to store the whole matrix in the AV_PKT_DATA_DISPLAYMATRIX
    // side data, but the scale factor is not needed to calculate aspect ratio
2947
    for (i = 0; i < 3; i++) {
2948 2949
        display_matrix[i][0] = avio_rb32(pb);   // 16.16 fixed point
        display_matrix[i][1] = avio_rb32(pb);   // 16.16 fixed point
2950
        display_matrix[i][2] = avio_rb32(pb);   //  2.30 fixed point
2951
    }
2952

2953 2954
    width = avio_rb32(pb);       // 16.16 fixed point track width
    height = avio_rb32(pb);      // 16.16 fixed point track height
2955 2956
    sc->width = width >> 16;
    sc->height = height >> 16;
2957

2958 2959
    // save the matrix and add rotate metadata when it is not the default
    // identity
2960 2961 2962 2963 2964 2965 2966
    if (display_matrix[0][0] != (1 << 16) ||
        display_matrix[1][1] != (1 << 16) ||
        display_matrix[2][2] != (1 << 30) ||
        display_matrix[0][1] || display_matrix[0][2] ||
        display_matrix[1][0] || display_matrix[1][2] ||
        display_matrix[2][0] || display_matrix[2][1]) {
        int i, j;
2967
        double rotate;
2968 2969 2970 2971 2972 2973 2974 2975

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

        for (i = 0; i < 3; i++)
            for (j = 0; j < 3; j++)
2976
                sc->display_matrix[i * 3 + j] = display_matrix[i][j];
2977 2978 2979 2980 2981 2982 2983 2984 2985 2986

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

2989
    // transform the display width/height according to the matrix
2990
    // to keep the same scale, use [width height 1<<16]
2991 2992 2993 2994
    if (width && height && sc->display_matrix) {
        double disp_transform[2];

#define SQR(a) ((a)*(double)(a))
2995
        for (i = 0; i < 2; i++)
2996 2997
            disp_transform[i] = sqrt(SQR(display_matrix[i][0]) + SQR(display_matrix[i][1]));

2998 2999
        if (disp_transform[0] > 0       && disp_transform[1] > 0 &&
            disp_transform[0] < (1<<24) && disp_transform[1] < (1<<24) &&
3000
            fabs((disp_transform[0] / disp_transform[1]) - 1.0) > 0.01)
3001 3002 3003
            st->sample_aspect_ratio = av_d2q(
                disp_transform[0] / disp_transform[1],
                INT_MAX);
3004
    }
3005 3006 3007
    return 0;
}

3008
static int mov_read_tfhd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
3009 3010 3011
{
    MOVFragment *frag = &c->fragment;
    MOVTrackExt *trex = NULL;
3012
    MOVFragmentIndex* index = NULL;
B
Baptiste Coudurier 已提交
3013 3014
    int flags, track_id, i;

3015 3016
    avio_r8(pb); /* version */
    flags = avio_rb24(pb);
B
Baptiste Coudurier 已提交
3017

3018
    track_id = avio_rb32(pb);
3019
    if (!track_id)
3020
        return AVERROR_INVALIDDATA;
B
Baptiste Coudurier 已提交
3021 3022 3023 3024 3025 3026 3027 3028
    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");
3029
        return AVERROR_INVALIDDATA;
B
Baptiste Coudurier 已提交
3030
    }
3031 3032 3033 3034 3035 3036 3037 3038 3039
    for (i = 0; i < c->fragment_index_count; i++) {
        MOVFragmentIndex* candidate = c->fragment_index_data[i];
        if (candidate->track_id == frag->track_id) {
            av_log(c->fc, AV_LOG_DEBUG,
                   "found fragment index for track %u\n", frag->track_id);
            index = candidate;
            break;
        }
    }
B
Baptiste Coudurier 已提交
3040

3041
    frag->base_data_offset = flags & MOV_TFHD_BASE_DATA_OFFSET ?
3042 3043
                             avio_rb64(pb) : flags & MOV_TFHD_DEFAULT_BASE_IS_MOOF ?
                             frag->moof_offset : frag->implicit_offset;
3044 3045 3046 3047 3048 3049 3050 3051
    frag->stsd_id  = flags & MOV_TFHD_STSD_ID ? avio_rb32(pb) : trex->stsd_id;

    frag->duration = flags & MOV_TFHD_DEFAULT_DURATION ?
                     avio_rb32(pb) : trex->duration;
    frag->size     = flags & MOV_TFHD_DEFAULT_SIZE ?
                     avio_rb32(pb) : trex->size;
    frag->flags    = flags & MOV_TFHD_DEFAULT_FLAGS ?
                     avio_rb32(pb) : trex->flags;
3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070
    frag->time     = AV_NOPTS_VALUE;
    if (index) {
        int i, found = 0;
        for (i = index->current_item; i < index->item_count; i++) {
            if (frag->implicit_offset == index->items[i].moof_offset) {
                av_log(c->fc, AV_LOG_DEBUG, "found fragment index entry "
                        "for track %u and moof_offset %"PRId64"\n",
                        frag->track_id, index->items[i].moof_offset);
                frag->time = index->items[i].time;
                index->current_item = i + 1;
                found = 1;
            }
        }
        if (!found) {
            av_log(c->fc, AV_LOG_WARNING, "track %u has a fragment index "
                   "but it doesn't have an (in-order) entry for moof_offset "
                   "%"PRId64"\n", frag->track_id, frag->implicit_offset);
        }
    }
3071
    av_log(c->fc, AV_LOG_TRACE, "frag flags 0x%x\n", frag->flags);
B
Baptiste Coudurier 已提交
3072 3073 3074
    return 0;
}

3075
static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom)
D
David Conrad 已提交
3076
{
3077
    c->chapter_track = avio_rb32(pb);
D
David Conrad 已提交
3078 3079 3080
    return 0;
}

3081
static int mov_read_trex(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
3082 3083
{
    MOVTrackExt *trex;
3084
    int err;
B
Baptiste Coudurier 已提交
3085 3086

    if ((uint64_t)c->trex_count+1 >= UINT_MAX / sizeof(*c->trex_data))
3087
        return AVERROR_INVALIDDATA;
3088 3089 3090 3091 3092
    if ((err = av_reallocp_array(&c->trex_data, c->trex_count + 1,
                                 sizeof(*c->trex_data))) < 0) {
        c->trex_count = 0;
        return err;
    }
3093 3094 3095

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

B
Baptiste Coudurier 已提交
3096
    trex = &c->trex_data[c->trex_count++];
3097 3098 3099 3100 3101 3102 3103
    avio_r8(pb); /* version */
    avio_rb24(pb); /* flags */
    trex->track_id = avio_rb32(pb);
    trex->stsd_id  = avio_rb32(pb);
    trex->duration = avio_rb32(pb);
    trex->size     = avio_rb32(pb);
    trex->flags    = avio_rb32(pb);
B
Baptiste Coudurier 已提交
3104 3105 3106
    return 0;
}

M
Martin Storsjö 已提交
3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136
static int mov_read_tfdt(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    MOVFragment *frag = &c->fragment;
    AVStream *st = NULL;
    MOVStreamContext *sc;
    int version, i;

    for (i = 0; i < c->fc->nb_streams; i++) {
        if (c->fc->streams[i]->id == frag->track_id) {
            st = c->fc->streams[i];
            break;
        }
    }
    if (!st) {
        av_log(c->fc, AV_LOG_ERROR, "could not find corresponding track id %d\n", frag->track_id);
        return AVERROR_INVALIDDATA;
    }
    sc = st->priv_data;
    if (sc->pseudo_stream_id + 1 != frag->stsd_id)
        return 0;
    version = avio_r8(pb);
    avio_rb24(pb); /* flags */
    if (version) {
        sc->track_end = avio_rb64(pb);
    } else {
        sc->track_end = avio_rb32(pb);
    }
    return 0;
}

3137
static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
B
Baptiste Coudurier 已提交
3138 3139
{
    MOVFragment *frag = &c->fragment;
3140
    AVStream *st = NULL;
3141
    MOVStreamContext *sc;
3142
    MOVStts *ctts_data;
B
Baptiste Coudurier 已提交
3143 3144 3145 3146
    uint64_t offset;
    int64_t dts;
    int data_offset = 0;
    unsigned entries, first_sample_flags = frag->flags;
3147
    int flags, distance, i, found_keyframe = 0, err;
B
Baptiste Coudurier 已提交
3148

3149 3150 3151 3152 3153 3154 3155 3156
    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);
3157
        return AVERROR_INVALIDDATA;
3158
    }
3159
    sc = st->priv_data;
3160
    if (sc->pseudo_stream_id+1 != frag->stsd_id && sc->pseudo_stream_id != -1)
B
Baptiste Coudurier 已提交
3161
        return 0;
3162 3163 3164
    avio_r8(pb); /* version */
    flags = avio_rb24(pb);
    entries = avio_rb32(pb);
3165
    av_log(c->fc, AV_LOG_TRACE, "flags 0x%x entries %d\n", flags, entries);
3166 3167 3168 3169 3170 3171 3172 3173 3174

    /* Always assume the presence of composition time offsets.
     * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following.
     *  1) in the initial movie, there are no samples.
     *  2) in the first movie fragment, there is only one sample without composition time offset.
     *  3) in the subsequent movie fragments, there are samples with composition time offset. */
    if (!sc->ctts_count && sc->sample_count)
    {
        /* Complement ctts table if moov atom doesn't have ctts atom. */
3175
        ctts_data = av_realloc(NULL, sizeof(*sc->ctts_data));
3176
        if (!ctts_data)
B
Baptiste Coudurier 已提交
3177
            return AVERROR(ENOMEM);
3178
        sc->ctts_data = ctts_data;
3179 3180 3181
        sc->ctts_data[sc->ctts_count].count = sc->sample_count;
        sc->ctts_data[sc->ctts_count].duration = 0;
        sc->ctts_count++;
B
Baptiste Coudurier 已提交
3182
    }
3183
    if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data))
3184
        return AVERROR_INVALIDDATA;
3185 3186 3187 3188 3189
    if ((err = av_reallocp_array(&sc->ctts_data, entries + sc->ctts_count,
                                 sizeof(*sc->ctts_data))) < 0) {
        sc->ctts_count = 0;
        return err;
    }
3190 3191
    if (flags & MOV_TRUN_DATA_OFFSET)        data_offset        = avio_rb32(pb);
    if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
3192
    dts    = sc->track_end - sc->time_offset;
B
Baptiste Coudurier 已提交
3193 3194
    offset = frag->base_data_offset + data_offset;
    distance = 0;
3195
    av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags);
3196
    for (i = 0; i < entries && !pb->eof_reached; i++) {
B
Baptiste Coudurier 已提交
3197 3198 3199
        unsigned sample_size = frag->size;
        int sample_flags = i ? frag->flags : first_sample_flags;
        unsigned sample_duration = frag->duration;
3200
        int keyframe = 0;
B
Baptiste Coudurier 已提交
3201

3202 3203 3204
        if (flags & MOV_TRUN_SAMPLE_DURATION) sample_duration = avio_rb32(pb);
        if (flags & MOV_TRUN_SAMPLE_SIZE)     sample_size     = avio_rb32(pb);
        if (flags & MOV_TRUN_SAMPLE_FLAGS)    sample_flags    = avio_rb32(pb);
3205 3206 3207
        sc->ctts_data[sc->ctts_count].count = 1;
        sc->ctts_data[sc->ctts_count].duration = (flags & MOV_TRUN_SAMPLE_CTS) ?
                                                  avio_rb32(pb) : 0;
3208
        mov_update_dts_shift(sc, sc->ctts_data[sc->ctts_count].duration);
3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230
        if (frag->time != AV_NOPTS_VALUE) {
            if (c->use_mfra_for == FF_MOV_FLAG_MFRA_PTS) {
                int64_t pts = frag->time;
                av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64
                        " sc->dts_shift %d ctts.duration %d"
                        " sc->time_offset %"PRId64" flags & MOV_TRUN_SAMPLE_CTS %d\n", pts,
                        sc->dts_shift, sc->ctts_data[sc->ctts_count].duration,
                        sc->time_offset, flags & MOV_TRUN_SAMPLE_CTS);
                dts = pts - sc->dts_shift;
                if (flags & MOV_TRUN_SAMPLE_CTS) {
                    dts -= sc->ctts_data[sc->ctts_count].duration;
                } else {
                    dts -= sc->time_offset;
                }
                av_log(c->fc, AV_LOG_DEBUG, "calculated into dts %"PRId64"\n", dts);
            } else {
                dts = frag->time;
                av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64
                        ", using it for dts\n", dts);
            }
            frag->time = AV_NOPTS_VALUE;
        }
3231
        sc->ctts_count++;
3232 3233 3234 3235 3236 3237 3238
        if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO)
            keyframe = 1;
        else if (!found_keyframe)
            keyframe = found_keyframe =
                !(sample_flags & (MOV_FRAG_SAMPLE_FLAG_IS_NON_SYNC |
                                  MOV_FRAG_SAMPLE_FLAG_DEPENDS_YES));
        if (keyframe)
B
Baptiste Coudurier 已提交
3239
            distance = 0;
3240
        err = av_add_index_entry(st, offset, dts, sample_size, distance,
3241 3242 3243
                                 keyframe ? AVINDEX_KEYFRAME : 0);
        if (err < 0) {
            av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n");
3244
        }
3245
        av_log(c->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
B
Baptiste Coudurier 已提交
3246
                "size %d, distance %d, keyframe %d\n", st->index, sc->sample_count+i,
3247
                offset, dts, sample_size, distance, keyframe);
B
Baptiste Coudurier 已提交
3248
        distance++;
3249
        dts += sample_duration;
B
Baptiste Coudurier 已提交
3250
        offset += sample_size;
3251
        sc->data_size += sample_size;
3252 3253
        sc->duration_for_fps += sample_duration;
        sc->nb_frames_for_fps ++;
B
Baptiste Coudurier 已提交
3254
    }
3255 3256 3257 3258

    if (pb->eof_reached)
        return AVERROR_EOF;

3259
    frag->implicit_offset = offset;
3260
    st->duration = sc->track_end = dts + sc->time_offset;
B
Baptiste Coudurier 已提交
3261 3262 3263
    return 0;
}

3264 3265 3266
/* 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/ */
3267
static int mov_read_wide(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3268 3269 3270 3271 3272
{
    int err;

    if (atom.size < 8)
        return 0; /* continue */
3273
    if (avio_rb32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
3274
        avio_skip(pb, atom.size - 4);
3275 3276
        return 0;
    }
3277
    atom.type = avio_rl32(pb);
3278
    atom.size -= 8;
3279
    if (atom.type != MKTAG('m','d','a','t')) {
3280
        avio_skip(pb, atom.size);
3281 3282 3283 3284 3285 3286
        return 0;
    }
    err = mov_read_mdat(c, pb, atom);
    return err;
}

3287
static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom)
3288
{
3289
#if CONFIG_ZLIB
3290
    AVIOContext ctx;
3291 3292
    uint8_t *cmov_data;
    uint8_t *moov_data; /* uncompressed data */
3293
    long cmov_len, moov_len;
3294
    int ret = -1;
3295

3296 3297
    avio_rb32(pb); /* dcom atom */
    if (avio_rl32(pb) != MKTAG('d','c','o','m'))
3298
        return AVERROR_INVALIDDATA;
3299
    if (avio_rl32(pb) != MKTAG('z','l','i','b')) {
3300
        av_log(c->fc, AV_LOG_ERROR, "unknown compression for cmov atom !\n");
3301
        return AVERROR_INVALIDDATA;
3302
    }
3303 3304
    avio_rb32(pb); /* cmvd atom */
    if (avio_rl32(pb) != MKTAG('c','m','v','d'))
3305
        return AVERROR_INVALIDDATA;
3306
    moov_len = avio_rb32(pb); /* uncompressed size */
3307
    cmov_len = atom.size - 6 * 4;
3308

B
Baptiste Coudurier 已提交
3309
    cmov_data = av_malloc(cmov_len);
3310
    if (!cmov_data)
3311
        return AVERROR(ENOMEM);
B
Baptiste Coudurier 已提交
3312
    moov_data = av_malloc(moov_len);
3313 3314
    if (!moov_data) {
        av_free(cmov_data);
3315
        return AVERROR(ENOMEM);
3316
    }
3317
    avio_read(pb, cmov_data, cmov_len);
3318
    if (uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
3319
        goto free_and_return;
3320
    if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
3321
        goto free_and_return;
3322
    atom.type = MKTAG('m','o','o','v');
3323 3324
    atom.size = moov_len;
    ret = mov_read_default(c, &ctx, atom);
3325
free_and_return:
3326 3327 3328
    av_free(moov_data);
    av_free(cmov_data);
    return ret;
3329 3330
#else
    av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
3331
    return AVERROR(ENOSYS);
3332
#endif
3333
}
3334

G
Gael Chardon 已提交
3335
/* edit list atom */
3336
static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom)
G
Gael Chardon 已提交
3337
{
3338
    MOVStreamContext *sc;
3339
    int i, edit_count, version;
B
Baptiste Coudurier 已提交
3340

3341
    if (c->fc->nb_streams < 1 || c->ignore_editlist)
3342 3343 3344
        return 0;
    sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;

3345
    version = avio_r8(pb); /* version */
3346 3347
    avio_rb24(pb); /* flags */
    edit_count = avio_rb32(pb); /* entries */
B
Baptiste Coudurier 已提交
3348

3349 3350 3351 3352 3353 3354 3355 3356 3357
    if (!edit_count)
        return 0;
    if (sc->elst_data)
        av_log(c->fc, AV_LOG_WARNING, "Duplicated ELST atom\n");
    av_free(sc->elst_data);
    sc->elst_count = 0;
    sc->elst_data = av_malloc_array(edit_count, sizeof(*sc->elst_data));
    if (!sc->elst_data)
        return AVERROR(ENOMEM);
3358

3359
    av_log(c->fc, AV_LOG_TRACE, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, edit_count);
3360 3361 3362
    for (i = 0; i < edit_count && !pb->eof_reached; i++) {
        MOVElst *e = &sc->elst_data[i];

3363
        if (version == 1) {
3364 3365
            e->duration = avio_rb64(pb);
            e->time     = avio_rb64(pb);
3366
        } else {
3367 3368
            e->duration = avio_rb32(pb); /* segment duration */
            e->time     = (int32_t)avio_rb32(pb); /* media time */
3369
        }
3370
        e->rate = avio_rb32(pb) / 65536.0;
3371
        av_log(c->fc, AV_LOG_TRACE, "duration=%"PRId64" time=%"PRId64" rate=%f\n",
3372
                e->duration, e->time, e->rate);
B
Baptiste Coudurier 已提交
3373
    }
3374
    sc->elst_count = i;
3375

B
Baptiste Coudurier 已提交
3376
    return 0;
G
Gael Chardon 已提交
3377 3378
}

3379
static int mov_read_tmcd(MOVContext *c, AVIOContext *pb, MOVAtom atom)
C
Clément Bœsch 已提交
3380 3381 3382 3383 3384 3385
{
    MOVStreamContext *sc;

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

3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432
static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int ret;
    uint8_t uuid[16];
    static const uint8_t uuid_isml_manifest[] = {
        0xa5, 0xd4, 0x0b, 0x30, 0xe8, 0x14, 0x11, 0xdd,
        0xba, 0x2f, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66
    };

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

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

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

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

        ptr = buffer;
3433
        while ((ptr = av_stristr(ptr, "systemBitrate=\""))) {
3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455
            ptr += sizeof("systemBitrate=\"") - 1;
            c->bitrates_count++;
            c->bitrates = av_realloc_f(c->bitrates, c->bitrates_count, sizeof(*c->bitrates));
            if (!c->bitrates) {
                c->bitrates_count = 0;
                av_free(buffer);
                return AVERROR(ENOMEM);
            }
            errno = 0;
            ret = strtol(ptr, &endptr, 10);
            if (ret < 0 || errno || *endptr != '"') {
                c->bitrates[c->bitrates_count - 1] = 0;
            } else {
                c->bitrates[c->bitrates_count - 1] = ret;
            }
        }

        av_free(buffer);
    }
    return 0;
}

3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477
static int mov_read_free(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int ret;
    uint8_t content[16];

    if (atom.size < 8)
        return 0;

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

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

    return 0;
}

3478
static const MOVParseTableEntry mov_default_parse_table[] = {
3479
{ MKTAG('A','C','L','R'), mov_read_aclr },
C
Carl Eugen Hoyos 已提交
3480
{ MKTAG('A','P','R','G'), mov_read_avid },
P
Piotr Bandurski 已提交
3481
{ MKTAG('A','A','L','P'), mov_read_avid },
3482
{ MKTAG('A','R','E','S'), mov_read_ares },
3483
{ MKTAG('a','v','s','s'), mov_read_avss },
D
David Conrad 已提交
3484
{ MKTAG('c','h','p','l'), mov_read_chpl },
3485
{ MKTAG('c','o','6','4'), mov_read_stco },
3486
{ MKTAG('c','o','l','r'), mov_read_colr },
3487 3488
{ MKTAG('c','t','t','s'), mov_read_ctts }, /* composition time to sample */
{ MKTAG('d','i','n','f'), mov_read_default },
3489
{ MKTAG('D','p','x','E'), mov_read_dpxe },
3490 3491 3492 3493
{ 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 },
3494
{ MKTAG('f','i','e','l'), mov_read_fiel },
3495 3496 3497
{ MKTAG('f','t','y','p'), mov_read_ftyp },
{ MKTAG('g','l','b','l'), mov_read_glbl },
{ MKTAG('h','d','l','r'), mov_read_hdlr },
3498
{ MKTAG('i','l','s','t'), mov_read_ilst },
3499
{ MKTAG('j','p','2','h'), mov_read_jp2h },
3500 3501 3502
{ MKTAG('m','d','a','t'), mov_read_mdat },
{ MKTAG('m','d','h','d'), mov_read_mdhd },
{ MKTAG('m','d','i','a'), mov_read_default },
3503
{ MKTAG('m','e','t','a'), mov_read_meta },
3504 3505 3506 3507 3508
{ MKTAG('m','i','n','f'), mov_read_default },
{ MKTAG('m','o','o','f'), mov_read_moof },
{ MKTAG('m','o','o','v'), mov_read_moov },
{ MKTAG('m','v','e','x'), mov_read_default },
{ MKTAG('m','v','h','d'), mov_read_mvhd },
P
Piotr Bandurski 已提交
3509
{ MKTAG('S','M','I',' '), mov_read_svq3 },
3510
{ MKTAG('a','l','a','c'), mov_read_alac }, /* alac specific atom */
3511
{ MKTAG('a','v','c','C'), mov_read_glbl },
3512
{ MKTAG('p','a','s','p'), mov_read_pasp },
3513 3514
{ MKTAG('s','t','b','l'), mov_read_default },
{ MKTAG('s','t','c','o'), mov_read_stco },
3515
{ MKTAG('s','t','p','s'), mov_read_stps },
M
Martin Storsjö 已提交
3516
{ MKTAG('s','t','r','f'), mov_read_strf },
3517 3518 3519 3520 3521
{ 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 },
3522
{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */
3523
{ MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */
M
Martin Storsjö 已提交
3524
{ MKTAG('t','f','d','t'), mov_read_tfdt },
3525 3526 3527
{ 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 },
3528 3529
{ MKTAG('t','r','e','f'), mov_read_default },
{ MKTAG('t','m','c','d'), mov_read_tmcd },
D
David Conrad 已提交
3530
{ MKTAG('c','h','a','p'), mov_read_chap },
3531 3532
{ MKTAG('t','r','e','x'), mov_read_trex },
{ MKTAG('t','r','u','n'), mov_read_trun },
B
Baptiste Coudurier 已提交
3533
{ MKTAG('u','d','t','a'), mov_read_default },
3534 3535
{ MKTAG('w','a','v','e'), mov_read_wave },
{ MKTAG('e','s','d','s'), mov_read_esds },
3536
{ MKTAG('d','a','c','3'), mov_read_dac3 }, /* AC-3 info */
3537
{ MKTAG('d','e','c','3'), mov_read_dec3 }, /* EAC-3 info */
3538
{ MKTAG('w','i','d','e'), mov_read_wide }, /* place holder */
3539
{ MKTAG('w','f','e','x'), mov_read_wfex },
3540
{ MKTAG('c','m','o','v'), mov_read_cmov },
3541
{ MKTAG('c','h','a','n'), mov_read_chan }, /* channel layout */
M
Martin Storsjö 已提交
3542
{ MKTAG('d','v','c','1'), mov_read_dvc1 },
3543
{ MKTAG('s','b','g','p'), mov_read_sbgp },
Y
Yusuke Nakamura 已提交
3544
{ MKTAG('h','v','c','C'), mov_read_glbl },
3545
{ MKTAG('u','u','i','d'), mov_read_uuid },
3546
{ MKTAG('C','i','n', 0x8e), mov_read_targa_y216 },
3547
{ MKTAG('f','r','e','e'), mov_read_free },
3548
{ MKTAG('-','-','-','-'), mov_read_custom },
B
Baptiste Coudurier 已提交
3549
{ 0, NULL }
3550 3551
};

3552 3553 3554 3555 3556 3557
static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
{
    int64_t total_size = 0;
    MOVAtom a;
    int i;

3558 3559 3560 3561 3562 3563
    if (c->atom_depth > 10) {
        av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n");
        return AVERROR_INVALIDDATA;
    }
    c->atom_depth ++;

3564 3565
    if (atom.size < 0)
        atom.size = INT64_MAX;
3566
    while (total_size + 8 <= atom.size && !avio_feof(pb)) {
3567 3568 3569 3570 3571 3572
        int (*parse)(MOVContext*, AVIOContext*, MOVAtom) = NULL;
        a.size = atom.size;
        a.type=0;
        if (atom.size >= 8) {
            a.size = avio_rb32(pb);
            a.type = avio_rl32(pb);
3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585
            if (a.type == MKTAG('f','r','e','e') &&
                a.size >= 8 &&
                c->moov_retry) {
                uint8_t buf[8];
                uint32_t *type = (uint32_t *)buf + 1;
                avio_read(pb, buf, 8);
                avio_seek(pb, -8, SEEK_CUR);
                if (*type == MKTAG('m','v','h','d') ||
                    *type == MKTAG('c','m','o','v')) {
                    av_log(c->fc, AV_LOG_ERROR, "Detected moov in a free atom.\n");
                    a.type = MKTAG('m','o','o','v');
                }
            }
3586 3587 3588 3589 3590 3591 3592
            if (atom.type != MKTAG('r','o','o','t') &&
                atom.type != MKTAG('m','o','o','v'))
            {
                if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
                {
                    av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
                    avio_skip(pb, -8);
3593
                    c->atom_depth --;
3594 3595 3596 3597
                    return 0;
                }
            }
            total_size += 8;
3598
            if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */
3599 3600 3601
                a.size = avio_rb64(pb) - 8;
                total_size += 8;
            }
3602
        }
3603
        av_log(c->fc, AV_LOG_TRACE, "type: %08x '%.4s' parent:'%.4s' sz: %"PRId64" %"PRId64" %"PRId64"\n",
3604 3605
                a.type, (char*)&a.type, (char*)&atom.type, a.size, total_size, atom.size);
        if (a.size == 0) {
3606
            a.size = atom.size - total_size + 8;
3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629
        }
        a.size -= 8;
        if (a.size < 0)
            break;
        a.size = FFMIN(a.size, atom.size - total_size);

        for (i = 0; mov_default_parse_table[i].type; i++)
            if (mov_default_parse_table[i].type == a.type) {
                parse = mov_default_parse_table[i].parse;
                break;
            }

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

        if (!parse) { /* skip leaf atoms data */
            avio_skip(pb, a.size);
        } else {
            int64_t start_pos = avio_tell(pb);
            int64_t left;
            int err = parse(c, pb, a);
3630 3631
            if (err < 0) {
                c->atom_depth --;
3632
                return err;
3633
            }
3634 3635 3636 3637 3638
            if (c->found_moov && c->found_mdat &&
                ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) ||
                 start_pos + a.size == avio_size(pb))) {
                if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX)
                    c->next_root_atom = start_pos + a.size;
3639
                c->atom_depth --;
3640 3641 3642 3643 3644
                return 0;
            }
            left = a.size - avio_tell(pb) + start_pos;
            if (left > 0) /* skip garbage at atom end */
                avio_skip(pb, left);
3645 3646 3647 3648
            else if (left < 0) {
                av_log(c->fc, AV_LOG_WARNING,
                       "overread end of atom '%.4s' by %"PRId64" bytes\n",
                       (char*)&a.type, -left);
3649 3650
                avio_seek(pb, left, SEEK_CUR);
            }
3651 3652 3653 3654 3655 3656 3657 3658
        }

        total_size += a.size;
    }

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

3659
    c->atom_depth --;
3660 3661 3662
    return 0;
}

F
Fabrice Bellard 已提交
3663 3664
static int mov_probe(AVProbeData *p)
{
3665
    int64_t offset;
3666
    uint32_t tag;
3667
    int score = 0;
3668
    int moov_offset = -1;
3669

F
Fabrice Bellard 已提交
3670
    /* check file header */
3671
    offset = 0;
3672
    for (;;) {
3673 3674
        /* ignore invalid offset */
        if ((offset + 8) > (unsigned int)p->buf_size)
3675
            break;
3676
        tag = AV_RL32(p->buf + offset + 4);
3677
        switch(tag) {
3678
        /* check for obvious tags */
3679
        case MKTAG('m','o','o','v'):
3680
            moov_offset = offset + 4;
3681 3682 3683
        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 */
3684
        case MKTAG('f','t','y','p'):
3685 3686 3687 3688
            if (AV_RB32(p->buf+offset) < 8 &&
                (AV_RB32(p->buf+offset) != 1 ||
                 offset + 12 > (unsigned int)p->buf_size ||
                 AV_RB64(p->buf+offset + 8) == 0)) {
3689
                score = FFMAX(score, AVPROBE_SCORE_EXTENSION);
3690
            } else if (tag == MKTAG('f','t','y','p') &&
3691 3692 3693
                       (   AV_RL32(p->buf + offset + 8) == MKTAG('j','p','2',' ')
                        || AV_RL32(p->buf + offset + 8) == MKTAG('j','p','x',' ')
                    )) {
3694
                score = FFMAX(score, 5);
3695 3696 3697
            } else {
                score = AVPROBE_SCORE_MAX;
            }
3698 3699
            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
            break;
3700
        /* those are more common words, so rate then a bit less */
3701 3702 3703 3704 3705
        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'):
3706 3707 3708
            score  = FFMAX(score, AVPROBE_SCORE_MAX - 5);
            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
            break;
B
Baptiste Coudurier 已提交
3709
        case MKTAG(0x82,0x82,0x7f,0x7d):
3710 3711 3712
        case MKTAG('s','k','i','p'):
        case MKTAG('u','u','i','d'):
        case MKTAG('p','r','f','l'):
3713
            /* if we only find those cause probedata is too small at least rate them */
3714
            score  = FFMAX(score, AVPROBE_SCORE_EXTENSION);
3715
            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
3716 3717
            break;
        default:
3718 3719 3720
            offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
        }
    }
3721
    if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
3722 3723 3724 3725
        /* moov atom in the header - we should make sure that this is not a
         * MOV-packed MPEG-PS */
        offset = moov_offset;

3726 3727 3728 3729 3730 3731 3732 3733
        while(offset < (p->buf_size - 16)){ /* Sufficient space */
               /* We found an actual hdlr atom */
            if(AV_RL32(p->buf + offset     ) == MKTAG('h','d','l','r') &&
               AV_RL32(p->buf + offset +  8) == MKTAG('m','h','l','r') &&
               AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
                av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
                /* We found a media handler reference atom describing an
                 * MPEG-PS-in-MOV, return a
3734 3735 3736 3737 3738 3739
                 * low score to force expanding the probe window until
                 * mpegps_probe finds what it needs */
                return 5;
            }else
                /* Keep looking */
                offset+=2;
3740
        }
3741
    }
3742 3743

    return score;
F
Fabrice Bellard 已提交
3744 3745
}

D
David Conrad 已提交
3746 3747 3748 3749 3750 3751 3752
// must be done after parsing all trak because there's no order requirement
static void mov_read_chapters(AVFormatContext *s)
{
    MOVContext *mov = s->priv_data;
    AVStream *st = NULL;
    MOVStreamContext *sc;
    int64_t cur_pos;
3753
    int i;
D
David Conrad 已提交
3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766

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

    st->discard = AVDISCARD_ALL;
    sc = st->priv_data;
3767
    cur_pos = avio_tell(sc->pb);
D
David Conrad 已提交
3768 3769 3770 3771

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

3776 3777 3778 3779 3780
        if (end < sample->timestamp) {
            av_log(s, AV_LOG_WARNING, "ignoring stream duration which is shorter than chapters\n");
            end = AV_NOPTS_VALUE;
        }

A
Anton Khirnov 已提交
3781
        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
D
David Conrad 已提交
3782 3783 3784 3785 3786
            av_log(s, AV_LOG_ERROR, "Chapter %d not found in file\n", i);
            goto finish;
        }

        // the first two bytes are the length of the title
3787
        len = avio_rb16(sc->pb);
D
David Conrad 已提交
3788 3789
        if (len > sample->size-2)
            continue;
3790 3791 3792
        title_len = 2*len + 1;
        if (!(title = av_mallocz(title_len)))
            goto finish;
D
David Conrad 已提交
3793 3794 3795 3796

        // The samples could theoretically be in any encoding if there's an encd
        // atom following, but in practice are only utf-8 or utf-16, distinguished
        // instead by the presence of a BOM
3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807
        if (!len) {
            title[0] = 0;
        } else {
            ch = avio_rb16(sc->pb);
            if (ch == 0xfeff)
                avio_get_str16be(sc->pb, len, title, title_len);
            else if (ch == 0xfffe)
                avio_get_str16le(sc->pb, len, title, title_len);
            else {
                AV_WB16(title, ch);
                if (len == 1 || len == 2)
3808
                    title[len] = 0;
3809
                else
3810
                    avio_get_str(sc->pb, INT_MAX, title + 2, len - 1);
3811
            }
D
David Conrad 已提交
3812 3813
        }

3814
        avpriv_new_chapter(s, i, st->time_base, sample->timestamp, end, title);
3815
        av_freep(&title);
D
David Conrad 已提交
3816 3817
    }
finish:
A
Anton Khirnov 已提交
3818
    avio_seek(sc->pb, cur_pos, SEEK_SET);
D
David Conrad 已提交
3819 3820
}

3821
static int parse_timecode_in_framenum_format(AVFormatContext *s, AVStream *st,
3822
                                             uint32_t value, int flags)
3823
{
3824 3825 3826 3827 3828 3829 3830
    AVTimecode tc;
    char buf[AV_TIMECODE_STR_SIZE];
    AVRational rate = {st->codec->time_base.den,
                       st->codec->time_base.num};
    int ret = av_timecode_init(&tc, rate, flags, 0, s);
    if (ret < 0)
        return ret;
3831
    av_dict_set(&st->metadata, "timecode",
3832
                av_timecode_make_string(&tc, buf, value), 0);
3833 3834 3835 3836 3837 3838
    return 0;
}

static int mov_read_timecode_track(AVFormatContext *s, AVStream *st)
{
    MOVStreamContext *sc = st->priv_data;
3839
    int flags = 0;
3840 3841 3842 3843 3844 3845 3846 3847 3848
    int64_t cur_pos = avio_tell(sc->pb);
    uint32_t value;

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

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

3849 3850 3851 3852
    if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME;
    if (sc->tmcd_flags & 0x0002) flags |= AV_TIMECODE_FLAG_24HOURSMAX;
    if (sc->tmcd_flags & 0x0004) flags |= AV_TIMECODE_FLAG_ALLOWNEGATIVE;

3853 3854 3855 3856 3857
    /* Assume Counter flag is set to 1 in tmcd track (even though it is likely
     * not the case) and thus assume "frame number format" instead of QT one.
     * No sample with tmcd track can be found with a QT timecode at the moment,
     * despite what the tmcd track "suggests" (Counter flag set to 0 means QT
     * format). */
3858
    parse_timecode_in_framenum_format(s, st, value, flags);
3859 3860 3861 3862 3863

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

3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878
static int mov_read_close(AVFormatContext *s)
{
    MOVContext *mov = s->priv_data;
    int i, j;

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

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

        sc->drefs_count = 0;

3882
        if (!sc->pb_is_copied)
3883
            avio_closep(&sc->pb);
3884

3885
        sc->pb = NULL;
3886 3887
        av_freep(&sc->chunk_offsets);
        av_freep(&sc->stsc_data);
3888 3889
        av_freep(&sc->sample_sizes);
        av_freep(&sc->keyframes);
3890
        av_freep(&sc->stts_data);
3891
        av_freep(&sc->stps_data);
3892
        av_freep(&sc->elst_data);
3893
        av_freep(&sc->rap_group);
3894
        av_freep(&sc->display_matrix);
3895 3896 3897
    }

    if (mov->dv_demux) {
3898 3899
        avformat_free_context(mov->dv_fctx);
        mov->dv_fctx = NULL;
3900 3901 3902
    }

    av_freep(&mov->trex_data);
3903
    av_freep(&mov->bitrates);
3904

3905 3906 3907 3908 3909 3910 3911
    for (i = 0; i < mov->fragment_index_count; i++) {
        MOVFragmentIndex* index = mov->fragment_index_data[i];
        av_freep(&index->items);
        av_freep(&mov->fragment_index_data[i]);
    }
    av_freep(&mov->fragment_index_data);

3912 3913 3914
    return 0;
}

3915 3916
static int tmcd_is_referenced(AVFormatContext *s, int tmcd_id)
{
3917
    int i;
3918 3919 3920 3921 3922

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

3923 3924 3925
        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO &&
            sc->timecode_track == tmcd_id)
            return 1;
3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948
    }
    return 0;
}

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

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

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

3949 3950 3951
static int read_tfra(MOVContext *mov, AVIOContext *f)
{
    MOVFragmentIndex* index = NULL;
3952
    int version, fieldlength, i, j;
3953 3954
    int64_t pos = avio_tell(f);
    uint32_t size = avio_rb32(f);
3955 3956
    void *tmp;

3957
    if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) {
3958
        return 1;
3959 3960 3961 3962 3963 3964
    }
    av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n");
    index = av_mallocz(sizeof(MOVFragmentIndex));
    if (!index) {
        return AVERROR(ENOMEM);
    }
3965 3966 3967 3968 3969

    tmp = av_realloc_array(mov->fragment_index_data,
                           mov->fragment_index_count + 1,
                           sizeof(MOVFragmentIndex*));
    if (!tmp) {
3970
        av_freep(&index);
3971
        return AVERROR(ENOMEM);
3972
    }
3973 3974
    mov->fragment_index_data = tmp;
    mov->fragment_index_data[mov->fragment_index_count++] = index;
3975 3976 3977 3978 3979 3980

    version = avio_r8(f);
    avio_rb24(f);
    index->track_id = avio_rb32(f);
    fieldlength = avio_rb32(f);
    index->item_count = avio_rb32(f);
3981 3982
    index->items = av_mallocz_array(
            index->item_count, sizeof(MOVFragmentIndexItem));
3983
    if (!index->items) {
3984
        index->item_count = 0;
3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013
        return AVERROR(ENOMEM);
    }
    for (i = 0; i < index->item_count; i++) {
        int64_t time, offset;
        if (version == 1) {
            time   = avio_rb64(f);
            offset = avio_rb64(f);
        } else {
            time   = avio_rb32(f);
            offset = avio_rb32(f);
        }
        index->items[i].time = time;
        index->items[i].moof_offset = offset;
        for (j = 0; j < ((fieldlength >> 4) & 3) + 1; j++)
            avio_r8(f);
        for (j = 0; j < ((fieldlength >> 2) & 3) + 1; j++)
            avio_r8(f);
        for (j = 0; j < ((fieldlength >> 0) & 3) + 1; j++)
            avio_r8(f);
    }

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

static int mov_read_mfra(MOVContext *c, AVIOContext *f)
{
    int64_t stream_size = avio_size(f);
    int64_t original_pos = avio_tell(f);
4014
    int64_t seek_ret;
4015 4016
    int32_t mfra_size;
    int ret = -1;
4017 4018 4019 4020
    if ((seek_ret = avio_seek(f, stream_size - 4, SEEK_SET)) < 0) {
        ret = seek_ret;
        goto fail;
    }
4021 4022 4023 4024 4025
    mfra_size = avio_rb32(f);
    if (mfra_size < 0 || mfra_size > stream_size) {
        av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (unreasonable size)\n");
        goto fail;
    }
4026 4027 4028 4029
    if ((seek_ret = avio_seek(f, -mfra_size, SEEK_CUR)) < 0) {
        ret = seek_ret;
        goto fail;
    }
4030 4031 4032 4033 4034 4035 4036 4037 4038
    if (avio_rb32(f) != mfra_size) {
        av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (size mismatch)\n");
        goto fail;
    }
    if (avio_rb32(f) != MKBETAG('m', 'f', 'r', 'a')) {
        av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n");
        goto fail;
    }
    av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n");
4039 4040 4041 4042 4043 4044
    do {
        ret = read_tfra(c, f);
        if (ret < 0)
            goto fail;
    } while (!ret);
    ret = 0;
4045
fail:
4046 4047
    seek_ret = avio_seek(f, original_pos, SEEK_SET);
    if (seek_ret < 0) {
4048 4049
        av_log(c->fc, AV_LOG_ERROR,
               "failed to seek back after looking for mfra\n");
4050 4051
        ret = seek_ret;
    }
4052 4053 4054
    return ret;
}

4055
static int mov_read_header(AVFormatContext *s)
4056
{
4057
    MOVContext *mov = s->priv_data;
4058
    AVIOContext *pb = s->pb;
4059
    int j, err;
4060
    MOVAtom atom = { AV_RL32("root") };
4061
    int i;
4062 4063

    mov->fc = s;
4064
    /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
4065
    if (pb->seekable)
A
Anton Khirnov 已提交
4066
        atom.size = avio_size(pb);
4067
    else
B
Baptiste Coudurier 已提交
4068
        atom.size = INT64_MAX;
4069 4070

    /* check MOV header */
4071 4072 4073
    do {
    if (mov->moov_retry)
        avio_seek(pb, 0, SEEK_SET);
B
Baptiste Coudurier 已提交
4074
    if ((err = mov_read_default(mov, pb, atom)) < 0) {
4075
        av_log(s, AV_LOG_ERROR, "error reading header\n");
4076
        mov_read_close(s);
B
Baptiste Coudurier 已提交
4077 4078
        return err;
    }
4079
    } while (pb->seekable && !mov->found_moov && !mov->moov_retry++);
B
Baptiste Coudurier 已提交
4080 4081
    if (!mov->found_moov) {
        av_log(s, AV_LOG_ERROR, "moov atom not found\n");
4082
        mov_read_close(s);
4083
        return AVERROR_INVALIDDATA;
4084
    }
4085
    av_log(mov->fc, AV_LOG_TRACE, "on_parse_exit_offset=%"PRId64"\n", avio_tell(pb));
4086

4087 4088 4089 4090 4091 4092 4093
    if (pb->seekable) {
        if (mov->chapter_track > 0)
            mov_read_chapters(s);
        for (i = 0; i < s->nb_streams; i++)
            if (s->streams[i]->codec->codec_tag == AV_RL32("tmcd"))
                mov_read_timecode_track(s, s->streams[i]);
    }
D
David Conrad 已提交
4094

4095 4096 4097 4098
    /* copy timecode metadata from tmcd tracks to the related video streams */
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
        MOVStreamContext *sc = st->priv_data;
4099
        if (sc->timecode_track > 0) {
4100
            AVDictionaryEntry *tcr;
4101
            int tmcd_st_id = -1;
4102

4103 4104 4105 4106
            for (j = 0; j < s->nb_streams; j++)
                if (s->streams[j]->id == sc->timecode_track)
                    tmcd_st_id = j;

4107
            if (tmcd_st_id < 0 || tmcd_st_id == i)
4108 4109 4110 4111 4112 4113
                continue;
            tcr = av_dict_get(s->streams[tmcd_st_id]->metadata, "timecode", NULL, 0);
            if (tcr)
                av_dict_set(&st->metadata, "timecode", tcr->value, 0);
        }
    }
4114
    export_orphan_timecode(s);
4115

4116 4117 4118
    for (i = 0; i < s->nb_streams; i++) {
        AVStream *st = s->streams[i];
        MOVStreamContext *sc = st->priv_data;
4119
        fix_timescale(mov, sc);
4120
        if(st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->codec->codec_id == AV_CODEC_ID_AAC) {
4121 4122
            st->skip_samples = sc->start_pad;
        }
4123 4124
        if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
            av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den,
4125
                      sc->time_scale*(int64_t)sc->nb_frames_for_fps, sc->duration_for_fps, INT_MAX);
4126
        if (st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) {
V
Vittorio Giovara 已提交
4127
            if (st->codec->width <= 0 || st->codec->height <= 0) {
4128 4129 4130
                st->codec->width  = sc->width;
                st->codec->height = sc->height;
            }
4131 4132 4133 4134
            if (st->codec->codec_id == AV_CODEC_ID_DVD_SUBTITLE) {
                if ((err = mov_rewrite_dvd_sub_extradata(st)) < 0)
                    return err;
            }
4135
        }
4136 4137
    }

4138 4139 4140 4141
    if (mov->trex_data) {
        for (i = 0; i < s->nb_streams; i++) {
            AVStream *st = s->streams[i];
            MOVStreamContext *sc = st->priv_data;
4142
            if (st->duration > 0)
4143 4144 4145 4146
                st->codec->bit_rate = sc->data_size * 8 * sc->time_scale / st->duration;
        }
    }

4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157
    if (mov->use_mfra_for > 0) {
        for (i = 0; i < s->nb_streams; i++) {
            AVStream *st = s->streams[i];
            MOVStreamContext *sc = st->priv_data;
            if (sc->duration_for_fps > 0) {
                st->codec->bit_rate = sc->data_size * 8 * sc->time_scale /
                    sc->duration_for_fps;
            }
        }
    }

4158 4159 4160 4161 4162 4163
    for (i = 0; i < mov->bitrates_count && i < s->nb_streams; i++) {
        if (mov->bitrates[i]) {
            s->streams[i]->codec->bit_rate = mov->bitrates[i];
        }
    }

4164 4165
    ff_rfps_calculate(s);

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

4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196
        switch (st->codec->codec_type) {
        case AVMEDIA_TYPE_AUDIO:
            err = ff_replaygain_export(st, s->metadata);
            if (err < 0) {
                mov_read_close(s);
                return err;
            }
            break;
        case AVMEDIA_TYPE_VIDEO:
            if (sc->display_matrix) {
                AVPacketSideData *sd, *tmp;

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

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

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

4200 4201 4202
    return 0;
}

4203
static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st)
4204
{
4205
    AVIndexEntry *sample = NULL;
4206
    int64_t best_dts = INT64_MAX;
4207
    int i;
B
Baptiste Coudurier 已提交
4208
    for (i = 0; i < s->nb_streams; i++) {
4209 4210
        AVStream *avst = s->streams[i];
        MOVStreamContext *msc = avst->priv_data;
4211
        if (msc->pb && msc->current_sample < avst->nb_index_entries) {
4212
            AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample];
4213
            int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale);
4214
            av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
4215 4216
            if (!sample || (!s->pb->seekable && current_sample->pos < sample->pos) ||
                (s->pb->seekable &&
4217
                 ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb &&
B
Baptiste Coudurier 已提交
4218
                 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
4219
                  (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) {
4220 4221
                sample = current_sample;
                best_dts = dts;
4222
                *st = avst;
4223
            }
4224 4225
        }
    }
4226 4227 4228 4229 4230 4231 4232 4233 4234 4235
    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;
4236
    mov->fc = s;
4237 4238
 retry:
    sample = mov_find_next_sample(s, &st);
4239 4240
    if (!sample) {
        mov->found_mdat = 0;
4241 4242 4243 4244 4245
        if (!mov->next_root_atom)
            return AVERROR_EOF;
        avio_seek(s->pb, mov->next_root_atom, SEEK_SET);
        mov->next_root_atom = 0;
        if (mov_read_default(mov, s->pb, (MOVAtom){ AV_RL32("root"), INT64_MAX }) < 0 ||
4246
            avio_feof(s->pb))
B
Baptiste Coudurier 已提交
4247
            return AVERROR_EOF;
4248
        av_log(s, AV_LOG_TRACE, "read fragments, offset 0x%"PRIx64"\n", avio_tell(s->pb));
4249 4250
        goto retry;
    }
4251
    sc = st->priv_data;
4252 4253
    /* must be done just before reading, to avoid infinite loop on sample */
    sc->current_sample++;
4254

4255 4256 4257 4258 4259
    if (mov->next_root_atom) {
        sample->pos = FFMIN(sample->pos, mov->next_root_atom);
        sample->size = FFMIN(sample->size, (mov->next_root_atom - sample->pos));
    }

4260
    if (st->discard != AVDISCARD_ALL) {
A
Anton Khirnov 已提交
4261
        if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
R
Reimar Döffinger 已提交
4262 4263
            av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
                   sc->ffindex, sample->pos);
4264
            return AVERROR_INVALIDDATA;
R
Reimar Döffinger 已提交
4265 4266
        }
        ret = av_get_packet(sc->pb, pkt, sample->size);
4267 4268
        if (ret < 0)
            return ret;
4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279
        if (sc->has_palette) {
            uint8_t *pal;

            pal = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE);
            if (!pal) {
                av_log(mov->fc, AV_LOG_ERROR, "Cannot append palette to packet\n");
            } else {
                memcpy(pal, sc->palette, AVPALETTE_SIZE);
                sc->has_palette = 0;
            }
        }
R
Reimar Döffinger 已提交
4280 4281
#if CONFIG_DV_DEMUXER
        if (mov->dv_demux && sc->dv_audio_container) {
4282
            avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos);
4283
            av_freep(&pkt->data);
R
Reimar Döffinger 已提交
4284
            pkt->size = 0;
4285
            ret = avpriv_dv_get_packet(mov->dv_demux, pkt);
R
Reimar Döffinger 已提交
4286 4287 4288
            if (ret < 0)
                return ret;
        }
4289
#endif
4290 4291
    }

4292
    pkt->stream_index = sc->ffindex;
4293
    pkt->dts = sample->timestamp;
4294
    if (sc->ctts_data && sc->ctts_index < sc->ctts_count) {
4295
        pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration;
4296
        /* update ctts context */
4297 4298 4299 4300 4301
        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;
4302
        }
4303 4304
        if (sc->wrong_dts)
            pkt->dts = AV_NOPTS_VALUE;
4305
    } else {
4306
        int64_t next_dts = (sc->current_sample < st->nb_index_entries) ?
4307 4308
            st->index_entries[sc->current_sample].timestamp : st->duration;
        pkt->duration = next_dts - pkt->dts;
4309
        pkt->pts = pkt->dts;
4310
    }
4311 4312
    if (st->discard == AVDISCARD_ALL)
        goto retry;
4313
    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? AV_PKT_FLAG_KEY : 0;
4314
    pkt->pos = sample->pos;
4315

4316 4317
    return 0;
}
4318

4319
static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, int flags)
4320 4321 4322 4323
{
    MOVStreamContext *sc = st->priv_data;
    int sample, time_sample;
    int i;
4324

4325
    sample = av_index_search_timestamp(st, timestamp, flags);
4326
    av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
4327 4328
    if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp)
        sample = 0;
4329
    if (sample < 0) /* not sure what to do */
4330
        return AVERROR_INVALIDDATA;
4331
    sc->current_sample = sample;
4332
    av_log(s, AV_LOG_TRACE, "stream %d, found sample %d\n", st->index, sc->current_sample);
4333 4334 4335 4336
    /* adjust ctts index */
    if (sc->ctts_data) {
        time_sample = 0;
        for (i = 0; i < sc->ctts_count; i++) {
4337 4338
            int next = time_sample + sc->ctts_data[i].count;
            if (next > sc->current_sample) {
4339 4340
                sc->ctts_index = i;
                sc->ctts_sample = sc->current_sample - time_sample;
4341
                break;
4342
            }
4343
            time_sample = next;
4344 4345
        }
    }
4346
    return sample;
4347 4348
}

4349
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
G
Gael Chardon 已提交
4350
{
4351
    MOVContext *mc = s->priv_data;
4352 4353 4354
    AVStream *st;
    int sample;
    int i;
G
Gael Chardon 已提交
4355

4356
    if (stream_index >= s->nb_streams)
4357
        return AVERROR_INVALIDDATA;
G
Gael Chardon 已提交
4358

4359
    st = s->streams[stream_index];
4360
    sample = mov_seek_stream(s, st, sample_time, flags);
4361
    if (sample < 0)
4362
        return sample;
G
Gael Chardon 已提交
4363

4364 4365 4366
    if (mc->seek_individually) {
        /* adjust seek timestamp to found sample timestamp */
        int64_t seek_timestamp = st->index_entries[sample].timestamp;
G
Gael Chardon 已提交
4367

4368 4369 4370 4371 4372
        for (i = 0; i < s->nb_streams; i++) {
            int64_t timestamp;
            MOVStreamContext *sc = s->streams[i]->priv_data;
            st = s->streams[i];
            st->skip_samples = (sample_time <= 0) ? sc->start_pad : 0;
4373

4374 4375
            if (stream_index == i)
                continue;
G
Gael Chardon 已提交
4376

4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396
            timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
            mov_seek_stream(s, st, timestamp, flags);
        }
    } else {
        for (i = 0; i < s->nb_streams; i++) {
            MOVStreamContext *sc;
            st = s->streams[i];
            sc = st->priv_data;
            sc->current_sample = 0;
        }
        while (1) {
            MOVStreamContext *sc;
            AVIndexEntry *entry = mov_find_next_sample(s, &st);
            if (!entry)
                return AVERROR_INVALIDDATA;
            sc = st->priv_data;
            if (sc->ffindex == stream_index && sc->current_sample == sample)
                break;
            sc->current_sample++;
        }
4397
    }
G
Gael Chardon 已提交
4398 4399 4400
    return 0;
}

4401 4402 4403
#define OFFSET(x) offsetof(MOVContext, x)
#define FLAGS AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM
static const AVOption mov_options[] = {
4404 4405
    {"use_absolute_path",
        "allow using absolute path when opening alias, this is a possible security issue",
4406 4407
        OFFSET(use_absolute_path), FF_OPT_TYPE_INT, {.i64 = 0},
        0, 1, FLAGS},
4408 4409 4410 4411
    {"seek_streams_individually",
        "Seek each stream individually to the to the closest point",
        OFFSET(seek_individually), AV_OPT_TYPE_INT, { .i64 = 1 },
        0, 1, FLAGS},
4412 4413
    {"ignore_editlist", "", OFFSET(ignore_editlist), FF_OPT_TYPE_INT, {.i64 = 0},
        0, 1, FLAGS},
4414 4415
    {"use_mfra_for",
        "use mfra for fragment timestamps",
4416 4417
        OFFSET(use_mfra_for), FF_OPT_TYPE_INT, {.i64 = FF_MOV_FLAG_MFRA_AUTO},
        -1, FF_MOV_FLAG_MFRA_PTS, FLAGS,
4418
        "use_mfra_for"},
4419
    {"auto", "auto", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_AUTO}, 0, 0,
4420
        FLAGS, "use_mfra_for" },
4421
    {"dts", "dts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_DTS}, 0, 0,
4422
        FLAGS, "use_mfra_for" },
4423
    {"pts", "pts", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_MFRA_PTS}, 0, 0,
4424
        FLAGS, "use_mfra_for" },
4425 4426
    { "export_all", "Export unrecognized metadata entries", OFFSET(export_all),
        AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS },
4427
    { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp),
4428
        AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS },
4429
    { NULL },
4430 4431
};

4432
static const AVClass mov_class = {
4433 4434
    .class_name = "mov,mp4,m4a,3gp,3g2,mj2",
    .item_name  = av_default_item_name,
4435
    .option     = mov_options,
4436 4437
    .version    = LIBAVUTIL_VERSION_INT,
};
4438

4439
AVInputFormat ff_mov_demuxer = {
4440
    .name           = "mov,mp4,m4a,3gp,3g2,mj2",
4441
    .long_name      = NULL_IF_CONFIG_SMALL("QuickTime / MOV"),
4442
    .priv_class     = &mov_class,
4443
    .priv_data_size = sizeof(MOVContext),
4444
    .extensions     = "mov,mp4,m4a,3gp,3g2,mj2",
4445 4446 4447 4448 4449
    .read_probe     = mov_probe,
    .read_header    = mov_read_header,
    .read_packet    = mov_read_packet,
    .read_close     = mov_read_close,
    .read_seek      = mov_read_seek,
4450
    .flags          = AVFMT_NO_BYTE_SEEK,
4451
};