Statistics
| Branch: | Revision:

ffmpeg / libavformat / mov.c @ ec04d244

History | View | Annotate | Download (76.2 KB)

1
/*
2
 * MOV decoder.
3
 * Copyright (c) 2001 Fabrice Bellard.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
 */
19

    
20
#include <limits.h>
21

    
22
//#define DEBUG
23

    
24
#include "avformat.h"
25
#include "avi.h"
26
#include "mov.h"
27

    
28
#ifdef CONFIG_ZLIB
29
#include <zlib.h>
30
#endif
31

    
32
/*
33
 * First version by Francois Revol revol@free.fr
34
 * Seek function by Gael Chardon gael.dev@4now.net
35
 *
36
 * Features and limitations:
37
 * - reads most of the QT files I have (at least the structure),
38
 *   the exceptions are .mov with zlib compressed headers ('cmov' section). It shouldn't be hard to implement.
39
 *   FIXED, Francois Revol, 07/17/2002
40
 * - ffmpeg has nearly none of the usual QuickTime codecs,
41
 *   although I succesfully dumped raw and mp3 audio tracks off .mov files.
42
 *   Sample QuickTime files with mp3 audio can be found at: http://www.3ivx.com/showcase.html
43
 * - .mp4 parsing is still hazardous, although the format really is QuickTime with some minor changes
44
 *   (to make .mov parser crash maybe ?), despite what they say in the MPEG FAQ at
45
 *   http://mpeg.telecomitalialab.com/faq.htm
46
 * - the code is quite ugly... maybe I won't do it recursive next time :-)
47
 * - seek is not supported with files that contain edit list
48
 *
49
 * Funny I didn't know about http://sourceforge.net/projects/qt-ffmpeg/
50
 * when coding this :) (it's a writer anyway)
51
 *
52
 * Reference documents:
53
 * http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
54
 * Apple:
55
 *  http://developer.apple.com/documentation/QuickTime/QTFF/
56
 *  http://developer.apple.com/documentation/QuickTime/QTFF/qtff.pdf
57
 * QuickTime is a trademark of Apple (AFAIK :))
58
 */
59

    
60
#include "qtpalette.h"
61

    
62

    
63
#undef NDEBUG
64
#include <assert.h>
65

    
66
/* Allows seeking */
67
#define MOV_SEEK
68

    
69
/* Special handling for movies created with Minolta Dimaxe Xi*/
70
/* this fix should not interfere with other .mov files, but just in case*/
71
#define MOV_MINOLTA_FIX
72

    
73
/* some streams in QT (and in MP4 mostly) aren't either video nor audio */
74
/* so we first list them as this, then clean up the list of streams we give back, */
75
/* getting rid of these */
76
#define CODEC_TYPE_MOV_OTHER    (enum CodecType) 2
77

    
78
/* http://gpac.sourceforge.net/tutorial/mediatypes.htm */
79
const CodecTag ff_mov_obj_type[] = {
80
    { CODEC_ID_MPEG4     ,  32 },
81
    { CODEC_ID_H264      ,  33 },
82
    { CODEC_ID_AAC       ,  64 },
83
    { CODEC_ID_MPEG2VIDEO,  96 }, /* MPEG2 Simple */
84
    { CODEC_ID_MPEG2VIDEO,  97 }, /* MPEG2 Main */
85
    { CODEC_ID_MPEG2VIDEO,  98 }, /* MPEG2 SNR */
86
    { CODEC_ID_MPEG2VIDEO,  99 }, /* MPEG2 Spatial */
87
    { CODEC_ID_MPEG2VIDEO, 100 }, /* MPEG2 High */
88
    { CODEC_ID_MPEG2VIDEO, 101 }, /* MPEG2 422 */
89
    { CODEC_ID_AAC       , 102 }, /* MPEG2 AAC Main */
90
    { CODEC_ID_AAC       , 103 }, /* MPEG2 AAC Low */
91
    { CODEC_ID_AAC       , 104 }, /* MPEG2 AAC SSR */
92
    { CODEC_ID_MP3       , 105 },
93
    { CODEC_ID_MPEG1VIDEO, 106 },
94
    { CODEC_ID_MP2       , 107 },
95
    { CODEC_ID_MJPEG     , 108 },
96
    { CODEC_ID_PCM_S16LE , 224 },
97
    { CODEC_ID_VORBIS    , 221 },
98
    { CODEC_ID_AC3       , 226 },
99
    { CODEC_ID_PCM_ALAW  , 227 },
100
    { CODEC_ID_PCM_MULAW , 228 },
101
    { CODEC_ID_PCM_S16BE , 230 },
102
    { CODEC_ID_H263      , 242 },
103
    { CODEC_ID_H261      , 243 },
104
    { 0, 0 },
105
};
106

    
107
static const CodecTag mov_video_tags[] = {
108
/*  { CODEC_ID_, MKTAG('c', 'v', 'i', 'd') }, *//* Cinepak */
109
/*  { CODEC_ID_H263, MKTAG('r', 'a', 'w', ' ') }, *//* Uncompressed RGB */
110
/*  { CODEC_ID_H263, MKTAG('Y', 'u', 'v', '2') }, *//* Uncompressed YUV422 */
111
/*    { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'U', 'I') }, *//* YUV with alpha-channel (AVID Uncompressed) */
112
/* Graphics */
113
/* Animation */
114
/* Apple video */
115
/* Kodak Photo CD */
116
    { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */
117
    { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
118
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */
119
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */
120
    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */
121
/*    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */
122
/*    { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, *//* embedded gif files as frames (usually one "click to play movie" frame) */
123
/* Sorenson video */
124
    { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */
125
    { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */
126
    { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/
127
    { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */
128
    { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
129
    { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
130
    { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
131
    { CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, /* experimental: 3IVX files before ivx D4 4.5.1 */
132
/*    { CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */
133
    { CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H263 */
134
    { CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H263 ?? works */
135
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */
136
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */
137
/*    { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, *//* AVID dv */
138
    { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */
139
    { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */
140
    { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */
141
    { CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */
142
    { CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */
143
    { CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */
144
    { CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */
145
    { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */
146
    { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 produced by Sony HD camera */
147
    { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* HDV produced by FCP */
148
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG2 IMX NTSC 525/60 50mb/s produced by FCP */
149
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX PAL 625/50 50mb/s produced by FCP */
150
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG2 IMX NTSC 525/60 30mb/s produced by FCP */
151
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') }, /* MPEG2 IMX PAL 625/50 30mb/s produced by FCP */
152
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') }, /* DVCPRO PAL produced by FCP */
153
    //{ CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') }, /* DVCPRO HD 50i produced by FCP */
154
    //{ CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') }, /* DVCPRO HD 60i produced by FCP */
155
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 PAL produced by FCP */
156
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') }, /* DVCPRO50 NTSC produced by FCP */
157
    //{ CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */
158
    { CODEC_ID_NONE, 0 },
159
};
160

    
161
static const CodecTag mov_audio_tags[] = {
162
    { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') },
163
    { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
164
/*    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */
165
    { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
166
    /* { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') },*/ /* 8 bits */
167
    { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
168
    { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /*  */
169
    { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /*  */
170
    { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /*  */
171
    { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */
172
    { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */
173
    { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */
174

    
175
    { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */
176
    { CODEC_ID_MP2, 0x6D730055 }, /* MPEG layer 3 */
177
    { CODEC_ID_MP2, 0x5500736D }, /* MPEG layer 3 *//* XXX: check endianness */
178
/*    { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
179
/* MP4 tags */
180
    { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, /* MPEG-4 AAC */
181
    /* The standard for mpeg4 audio is still not normalised AFAIK anyway */
182
    { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */
183
    { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */
184
    { CODEC_ID_AC3, MKTAG('m', 's', 0x20, 0x00) }, /* Dolby AC-3 */
185
    { CODEC_ID_ALAC,MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */
186
    { CODEC_ID_QDM2,MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */
187
    { CODEC_ID_NONE, 0 },
188
};
189

    
190
/* map numeric codes from mdhd atom to ISO 639 */
191
/* cf. QTFileFormat.pdf p253, qtff.pdf p205 */
192
/* http://developer.apple.com/documentation/mac/Text/Text-368.html */
193
/* deprecated by putting the code as 3*5bit ascii */
194
static const char *mov_mdhd_language_map[] = {
195
/* 0-9 */
196
"eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
197
"heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/,
198
"urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav",  NULL,
199
"fo ",  NULL, "rus", "chi",  NULL, "iri", "alb", "ron", "ces", "slk",
200
"slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
201
/*?*/
202
"aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon",  NULL, "pus",
203
"kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
204
"pa ", "ori", "mal", "kan", "tam", "tel",  NULL, "bur", "khm", "lao",
205
/*                   roman? arabic? */
206
"vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
207
/*==rundi?*/
208
 NULL, "run",  NULL, "mlg", "epo",  NULL,  NULL,  NULL,  NULL,  NULL,
209
/* 100 */
210
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
211
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
212
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, "wel", "baq",
213
"cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
214
};
215

    
216
/* the QuickTime file format is quite convoluted...
217
 * it has lots of index tables, each indexing something in another one...
218
 * Here we just use what is needed to read the chunks
219
 */
220

    
221
typedef struct MOV_sample_to_chunk_tbl {
222
    long first;
223
    long count;
224
    long id;
225
} MOV_sample_to_chunk_tbl;
226

    
227
typedef struct {
228
    uint32_t type;
229
    int64_t offset;
230
    int64_t size; /* total size (excluding the size and type fields) */
231
} MOV_atom_t;
232

    
233
typedef struct {
234
    int seed;
235
    int flags;
236
    int size;
237
    void* clrs;
238
} MOV_ctab_t;
239

    
240
typedef struct {
241
    uint8_t  version;
242
    uint32_t flags; // 24bit
243

    
244
    /* 0x03 ESDescrTag */
245
    uint16_t es_id;
246
#define MP4ODescrTag                    0x01
247
#define MP4IODescrTag                   0x02
248
#define MP4ESDescrTag                   0x03
249
#define MP4DecConfigDescrTag            0x04
250
#define MP4DecSpecificDescrTag          0x05
251
#define MP4SLConfigDescrTag             0x06
252
#define MP4ContentIdDescrTag            0x07
253
#define MP4SupplContentIdDescrTag       0x08
254
#define MP4IPIPtrDescrTag               0x09
255
#define MP4IPMPPtrDescrTag              0x0A
256
#define MP4IPMPDescrTag                 0x0B
257
#define MP4RegistrationDescrTag         0x0D
258
#define MP4ESIDIncDescrTag              0x0E
259
#define MP4ESIDRefDescrTag              0x0F
260
#define MP4FileIODescrTag               0x10
261
#define MP4FileODescrTag                0x11
262
#define MP4ExtProfileLevelDescrTag      0x13
263
#define MP4ExtDescrTagsStart            0x80
264
#define MP4ExtDescrTagsEnd              0xFE
265
    uint8_t  stream_priority;
266

    
267
    /* 0x04 DecConfigDescrTag */
268
    uint8_t  object_type_id;
269
    uint8_t  stream_type;
270
    /* XXX: really streamType is
271
     * only 6bit, followed by:
272
     * 1bit  upStream
273
     * 1bit  reserved
274
     */
275
    uint32_t buffer_size_db; // 24
276
    uint32_t max_bitrate;
277
    uint32_t avg_bitrate;
278

    
279
    /* 0x05 DecSpecificDescrTag */
280
    uint8_t  decoder_cfg_len;
281
    uint8_t *decoder_cfg;
282

    
283
    /* 0x06 SLConfigDescrTag */
284
    uint8_t  sl_config_len;
285
    uint8_t *sl_config;
286
} MOV_esds_t;
287

    
288
struct MOVParseTableEntry;
289

    
290
typedef struct MOVStreamContext {
291
    int ffindex; /* the ffmpeg stream id */
292
    int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */
293
    long next_chunk;
294
    long chunk_count;
295
    int64_t *chunk_offsets;
296
    int stts_count;
297
    Time2Sample *stts_data;
298
    int ctts_count;
299
    Time2Sample *ctts_data;
300
    int edit_count;             /* number of 'edit' (elst atom) */
301
    long sample_to_chunk_sz;
302
    MOV_sample_to_chunk_tbl *sample_to_chunk;
303
    long sample_to_chunk_index;
304
    int sample_to_time_index;
305
    long sample_to_time_sample;
306
    uint64_t sample_to_time_time;
307
    int sample_to_ctime_index;
308
    int sample_to_ctime_sample;
309
    long sample_size;
310
    long sample_count;
311
    long *sample_sizes;
312
    long keyframe_count;
313
    long *keyframes;
314
    int time_scale;
315
    int time_rate;
316
    long current_sample;
317
    long left_in_chunk; /* how many samples before next chunk */
318
    MOV_esds_t esds;
319
} MOVStreamContext;
320

    
321
typedef struct MOVContext {
322
    int mp4; /* set to 1 as soon as we are sure that the file is an .mp4 file (even some header parsing depends on this) */
323
    AVFormatContext *fc;
324
    int time_scale;
325
    int64_t duration; /* duration of the longest track */
326
    int found_moov; /* when both 'moov' and 'mdat' sections has been found */
327
    int found_mdat; /* we suppose we have enough data to read the file */
328
    int64_t mdat_size;
329
    int64_t mdat_offset;
330
    int ni;                                         ///< non interleaved mode
331
    int total_streams;
332
    /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio
333
     * but we need the info to be able to skip data from those streams in the 'mdat' section
334
     */
335
    MOVStreamContext *streams[MAX_STREAMS];
336

    
337
    int64_t next_chunk_offset;
338
    MOVStreamContext *partial; /* != 0 : there is still to read in the current chunk */
339
    int ctab_size;
340
    MOV_ctab_t **ctab;           /* color tables */
341
    const struct MOVParseTableEntry *parse_table; /* could be eventually used to change the table */
342
    /* NOTE: for recursion save to/ restore from local variable! */
343

    
344
    AVPaletteControl palette_control;
345
} MOVContext;
346

    
347

    
348
/* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */
349

    
350
/* those functions parse an atom */
351
/* return code:
352
 1: found what I wanted, exit
353
 0: continue to parse next atom
354
 -1: error occured, exit
355
 */
356
typedef int (*mov_parse_function)(MOVContext *ctx, ByteIOContext *pb, MOV_atom_t atom);
357

    
358
/* links atom IDs to parse functions */
359
typedef struct MOVParseTableEntry {
360
    uint32_t type;
361
    mov_parse_function func;
362
} MOVParseTableEntry;
363

    
364
static int ff_mov_lang_to_iso639(int code, char *to)
365
{
366
    int i;
367
    /* is it the mangled iso code? */
368
    /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */
369
    if (code > 138) {
370
        for (i = 2; i >= 0; i--) {
371
            to[i] = 0x60 + (code & 0x1f);
372
            code >>= 5;
373
        }
374
        return 1;
375
    }
376
    /* old fashion apple lang code */
377
    if (code >= (sizeof(mov_mdhd_language_map)/sizeof(char *)))
378
        return 0;
379
    if (!mov_mdhd_language_map[code])
380
        return 0;
381
    strncpy(to, mov_mdhd_language_map[code], 4);
382
    return 1;
383
}
384

    
385
extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */
386
int ff_mov_iso639_to_lang(const char *lang, int mp4)
387
{
388
    int i, code = 0;
389

    
390
    /* old way, only for QT? */
391
    for (i = 0; !mp4 && (i < (sizeof(mov_mdhd_language_map)/sizeof(char *))); i++) {
392
        if (mov_mdhd_language_map[i] && !strcmp(lang, mov_mdhd_language_map[i]))
393
            return i;
394
    }
395
    /* XXX:can we do that in mov too? */
396
    if (!mp4)
397
        return 0;
398
    /* handle undefined as such */
399
    if (lang[0] == '\0')
400
        lang = "und";
401
    /* 5bit ascii */
402
    for (i = 0; i < 3; i++) {
403
        unsigned char c = (unsigned char)lang[i];
404
        if (c < 0x60)
405
            return 0;
406
        if (c > 0x60 + 0x1f)
407
            return 0;
408
        code <<= 5;
409
        code |= (c - 0x60);
410
    }
411
    return code;
412
}
413

    
414
static int mov_read_leaf(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
415
{
416
    if (atom.size>1)
417
        url_fskip(pb, atom.size);
418
/*        url_seek(pb, atom_offset+atom.size, SEEK_SET); */
419
    return 0;
420
}
421

    
422
static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
423
{
424
    int64_t total_size = 0;
425
    MOV_atom_t a;
426
    int i;
427
    int err = 0;
428

    
429
    a.offset = atom.offset;
430

    
431
    if (atom.size < 0)
432
        atom.size = 0x7fffffffffffffffLL;
433
    while(((total_size + 8) < atom.size) && !url_feof(pb) && !err) {
434
        a.size = atom.size;
435
        a.type=0L;
436
        if(atom.size >= 8) {
437
            a.size = get_be32(pb);
438
            a.type = get_le32(pb);
439
        }
440
        total_size += 8;
441
        a.offset += 8;
442
        dprintf("type: %08x  %.4s  sz: %"PRIx64"  %"PRIx64"   %"PRIx64"\n", a.type, (char*)&a.type, a.size, atom.size, total_size);
443
        if (a.size == 1) { /* 64 bit extended size */
444
            a.size = get_be64(pb) - 8;
445
            a.offset += 8;
446
            total_size += 8;
447
        }
448
        if (a.size == 0) {
449
            a.size = atom.size - total_size;
450
            if (a.size <= 8)
451
                break;
452
        }
453
        for (i = 0; c->parse_table[i].type != 0L
454
             && c->parse_table[i].type != a.type; i++)
455
            /* empty */;
456

    
457
        a.size -= 8;
458

    
459
        if(a.size < 0)
460
            break;
461

    
462
        if (c->parse_table[i].type == 0) { /* skip leaf atoms data */
463
            url_fskip(pb, a.size);
464
        } else {
465
            err = (c->parse_table[i].func)(c, pb, a);
466
        }
467

    
468
        a.offset += a.size;
469
        total_size += a.size;
470
    }
471

    
472
    if (!err && total_size < atom.size && atom.size < 0x7ffff) {
473
        url_fskip(pb, atom.size - total_size);
474
    }
475

    
476
    return err;
477
}
478

    
479
static int mov_read_ctab(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
480
{
481
#if 1
482
    url_fskip(pb, atom.size); // for now
483
#else
484
    VERY VERY BROKEN, NEVER execute this, needs rewrite
485
    unsigned int len;
486
    MOV_ctab_t *t;
487
    c->ctab = av_realloc(c->ctab, ++c->ctab_size);
488
    t = c->ctab[c->ctab_size];
489
    t->seed = get_be32(pb);
490
    t->flags = get_be16(pb);
491
    t->size = get_be16(pb) + 1;
492
    len = 2 * t->size * 4;
493
    if (len > 0) {
494
        t->clrs = av_malloc(len); // 16bit A R G B
495
        if (t->clrs)
496
            get_buffer(pb, t->clrs, len);
497
    }
498
#endif
499

    
500
    return 0;
501
}
502

    
503
static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
504
{
505
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
506
    int len = 0;
507
    uint32_t type;
508
    uint32_t ctype;
509

    
510
    get_byte(pb); /* version */
511
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
512

    
513
    /* component type */
514
    ctype = get_le32(pb);
515
    type = get_le32(pb); /* component subtype */
516

    
517
    dprintf("ctype= %c%c%c%c (0x%08lx)\n", *((char *)&ctype), ((char *)&ctype)[1], ((char *)&ctype)[2], ((char *)&ctype)[3], (long) ctype);
518
    dprintf("stype= %c%c%c%c\n", *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]);
519
    if(ctype == MKTAG('m', 'h', 'l', 'r')) /* MOV */
520
        c->mp4 = 0;
521
    else if(ctype == 0)
522
        c->mp4 = 1;
523
    if(type == MKTAG('v', 'i', 'd', 'e'))
524
        st->codec->codec_type = CODEC_TYPE_VIDEO;
525
    else if(type == MKTAG('s', 'o', 'u', 'n'))
526
        st->codec->codec_type = CODEC_TYPE_AUDIO;
527
    get_be32(pb); /* component  manufacture */
528
    get_be32(pb); /* component flags */
529
    get_be32(pb); /* component flags mask */
530

    
531
    if(atom.size <= 24)
532
        return 0; /* nothing left to read */
533
    /* XXX: MP4 uses a C string, not a pascal one */
534
    /* component name */
535

    
536
    if(c->mp4) {
537
        /* .mp4: C string */
538
        while(get_byte(pb) && (++len < (atom.size - 24)));
539
    } else {
540
        /* .mov: PASCAL string */
541
        len = get_byte(pb);
542
        url_fskip(pb, len);
543
    }
544

    
545
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
546
    return 0;
547
}
548

    
549
static int mov_mp4_read_descr_len(ByteIOContext *pb)
550
{
551
    int len = 0;
552
    int count = 4;
553
    while (count--) {
554
        int c = get_byte(pb);
555
        len = (len << 7) | (c & 0x7f);
556
        if (!(c & 0x80))
557
            break;
558
    }
559
    return len;
560
}
561

    
562
static int mov_mp4_read_descr(ByteIOContext *pb, int *tag)
563
{
564
    int len;
565
    *tag = get_byte(pb);
566
    len = mov_mp4_read_descr_len(pb);
567
    dprintf("MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
568
    return len;
569
}
570

    
571
static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
572
{
573
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
574
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
575
    int64_t start_pos = url_ftell(pb);
576
    int tag, len;
577

    
578
    /* Well, broken but suffisant for some MP4 streams */
579
    get_be32(pb); /* version + flags */
580
    len = mov_mp4_read_descr(pb, &tag);
581
    if (tag == MP4ESDescrTag) {
582
        get_be16(pb); /* ID */
583
        get_byte(pb); /* priority */
584
    } else
585
        get_be16(pb); /* ID */
586

    
587
    len = mov_mp4_read_descr(pb, &tag);
588
    if (tag == MP4DecConfigDescrTag) {
589
        sc->esds.object_type_id = get_byte(pb);
590
        sc->esds.stream_type = get_byte(pb);
591
        sc->esds.buffer_size_db = get_be24(pb);
592
        sc->esds.max_bitrate = get_be32(pb);
593
        sc->esds.avg_bitrate = get_be32(pb);
594

    
595
        st->codec->codec_id= codec_get_id(ff_mov_obj_type, sc->esds.object_type_id);
596
        len = mov_mp4_read_descr(pb, &tag);
597
        if (tag == MP4DecSpecificDescrTag) {
598
            dprintf("Specific MPEG4 header len=%d\n", len);
599
            st->codec->extradata = (uint8_t*) av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
600
            if (st->codec->extradata) {
601
                get_buffer(pb, st->codec->extradata, len);
602
                st->codec->extradata_size = len;
603
            }
604
        }
605
    }
606
    /* in any case, skip garbage */
607
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
608
    return 0;
609
}
610

    
611
/* this atom contains actual media data */
612
static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
613
{
614
    if(atom.size == 0) /* wrong one (MP4) */
615
        return 0;
616
    c->found_mdat=1;
617
    c->mdat_offset = atom.offset;
618
    c->mdat_size = atom.size;
619
    if(c->found_moov)
620
        return 1; /* found both, just go */
621
    url_fskip(pb, atom.size);
622
    return 0; /* now go for moov */
623
}
624

    
625
static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
626
{
627
    uint32_t type = get_le32(pb);
628

    
629
    /* from mplayer */
630
    switch (type) {
631
    case MKTAG('i', 's', 'o', 'm'):
632
    case MKTAG('m', 'p', '4', '1'):
633
    case MKTAG('m', 'p', '4', '2'):
634
    case MKTAG('3', 'g', 'p', '1'):
635
    case MKTAG('3', 'g', 'p', '2'):
636
    case MKTAG('3', 'g', '2', 'a'):
637
    case MKTAG('3', 'g', 'p', '3'):
638
    case MKTAG('3', 'g', 'p', '4'):
639
    case MKTAG('3', 'g', 'p', '5'):
640
    case MKTAG('m', 'm', 'p', '4'): /* Mobile MP4 */
641
    case MKTAG('M', '4', 'A', ' '): /* Apple iTunes AAC-LC Audio */
642
    case MKTAG('M', '4', 'P', ' '): /* Apple iTunes AAC-LC Protected Audio */
643
    case MKTAG('m', 'j', 'p', '2'): /* Motion Jpeg 2000 */
644
        c->mp4 = 1;
645
    case MKTAG('q', 't', ' ', ' '):
646
    default:
647
        av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
648
    }
649
    get_be32(pb); /* minor version */
650
    url_fskip(pb, atom.size - 8);
651
    return 0;
652
}
653

    
654
/* this atom should contain all header atoms */
655
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
656
{
657
    int err;
658

    
659
    err = mov_read_default(c, pb, atom);
660
    /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
661
    /* so we don't parse the whole file if over a network */
662
    c->found_moov=1;
663
    if(c->found_mdat)
664
        return 1; /* found both, just go */
665
    return 0; /* now go for mdat */
666
}
667

    
668

    
669
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
670
{
671
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
672
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
673
    int version = get_byte(pb);
674
    int lang;
675

    
676
    if (version > 1)
677
        return 1; /* unsupported */
678

    
679
    get_byte(pb); get_byte(pb);
680
    get_byte(pb); /* flags */
681

    
682
    if (version == 1) {
683
        get_be64(pb);
684
        get_be64(pb);
685
    } else {
686
        get_be32(pb); /* creation time */
687
        get_be32(pb); /* modification time */
688
    }
689

    
690
    sc->time_scale = get_be32(pb);
691
    st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
692

    
693
    lang = get_be16(pb); /* language */
694
    ff_mov_lang_to_iso639(lang, st->language);
695
    get_be16(pb); /* quality */
696

    
697
    return 0;
698
}
699

    
700
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
701
{
702
    int version = get_byte(pb); /* version */
703
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
704

    
705
    if (version == 1) {
706
        get_be64(pb);
707
        get_be64(pb);
708
    } else {
709
        get_be32(pb); /* creation time */
710
        get_be32(pb); /* modification time */
711
    }
712
    c->time_scale = get_be32(pb); /* time scale */
713
#ifdef DEBUG
714
    av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);
715
#endif
716
    c->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
717
    get_be32(pb); /* preferred scale */
718

    
719
    get_be16(pb); /* preferred volume */
720

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

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

    
725
    get_be32(pb); /* preview time */
726
    get_be32(pb); /* preview duration */
727
    get_be32(pb); /* poster time */
728
    get_be32(pb); /* selection time */
729
    get_be32(pb); /* selection duration */
730
    get_be32(pb); /* current time */
731
    get_be32(pb); /* next track ID */
732

    
733
    return 0;
734
}
735

    
736
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
737
{
738
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
739

    
740
    if((uint64_t)atom.size > (1<<30))
741
        return -1;
742

    
743
    // currently SVQ3 decoder expect full STSD header - so let's fake it
744
    // this should be fixed and just SMI header should be passed
745
    av_free(st->codec->extradata);
746
    st->codec->extradata_size = 0x5a + atom.size;
747
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
748

    
749
    if (st->codec->extradata) {
750
        strcpy(st->codec->extradata, "SVQ3"); // fake
751
        get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
752
        dprintf("Reading SMI %"PRId64"  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
753
    } else
754
        url_fskip(pb, atom.size);
755

    
756
    return 0;
757
}
758

    
759
static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
760
{
761
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
762
    int little_endian = get_be16(pb);
763

    
764
    if (little_endian) {
765
        switch (st->codec->codec_id) {
766
        case CODEC_ID_PCM_S24BE:
767
            st->codec->codec_id = CODEC_ID_PCM_S24LE;
768
            break;
769
        case CODEC_ID_PCM_S32BE:
770
            st->codec->codec_id = CODEC_ID_PCM_S32LE;
771
            break;
772
        default:
773
            break;
774
        }
775
    }
776
    return 0;
777
}
778

    
779
static int mov_read_alac(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
780
{
781
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
782

    
783
    // currently ALAC decoder expect full atom header - so let's fake it
784
    // this should be fixed and just ALAC header should be passed
785

    
786
    av_free(st->codec->extradata);
787
    st->codec->extradata_size = 36;
788
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
789

    
790
    if (st->codec->extradata) {
791
        strcpy(st->codec->extradata + 4, "alac"); // fake
792
        get_buffer(pb, st->codec->extradata + 8, 36 - 8);
793
        dprintf("Reading alac %d  %s\n", st->codec->extradata_size, (char*)st->codec->extradata);
794
    } else
795
        url_fskip(pb, atom.size);
796
    return 0;
797
}
798

    
799
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
800
{
801
    offset_t start_pos = url_ftell(pb);
802
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
803

    
804
    if((uint64_t)atom.size > (1<<30))
805
        return -1;
806

    
807
    if (st->codec->codec_id == CODEC_ID_QDM2) {
808
        // pass all frma atom to codec, needed at least for QDM2
809
        av_free(st->codec->extradata);
810
        st->codec->extradata_size = atom.size;
811
        st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
812

    
813
        if (st->codec->extradata) {
814
            get_buffer(pb, st->codec->extradata, atom.size);
815
        } else
816
            url_fskip(pb, atom.size);
817
    } else if (atom.size > 8) { /* to read frma, esds atoms */
818
        mov_read_default(c, pb, atom);
819
    } else if (atom.size > 0)
820
        url_fskip(pb, atom.size);
821
    /* in any case, skip garbage */
822
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
823
    return 0;
824
}
825

    
826
static int mov_read_jp2h(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
827
{
828
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
829

    
830
    if((uint64_t)atom.size > (1<<30))
831
        return -1;
832

    
833
    av_free(st->codec->extradata);
834

    
835
    st->codec->extradata_size = atom.size + 8;
836
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
837

    
838
    /* pass all jp2h atom to codec */
839
    if (st->codec->extradata) {
840
        strcpy(st->codec->extradata + 4, "jp2h");
841
        get_buffer(pb, st->codec->extradata + 8, atom.size);
842
    } else
843
        url_fskip(pb, atom.size);
844
    return 0;
845
}
846

    
847
static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
848
{
849
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
850

    
851
    if((uint64_t)atom.size > (1<<30))
852
        return -1;
853

    
854
    av_free(st->codec->extradata);
855

    
856
    st->codec->extradata_size = atom.size;
857
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
858

    
859
    if (st->codec->extradata) {
860
        get_buffer(pb, st->codec->extradata, atom.size);
861
    } else
862
        url_fskip(pb, atom.size);
863

    
864
    return 0;
865
}
866

    
867
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
868
{
869
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
870
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
871
    unsigned int i, entries;
872

    
873
    get_byte(pb); /* version */
874
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
875

    
876
    entries = get_be32(pb);
877

    
878
    if(entries >= UINT_MAX/sizeof(int64_t))
879
        return -1;
880

    
881
    sc->chunk_count = entries;
882
    sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t));
883
    if (!sc->chunk_offsets)
884
        return -1;
885
    if (atom.type == MKTAG('s', 't', 'c', 'o')) {
886
        for(i=0; i<entries; i++) {
887
            sc->chunk_offsets[i] = get_be32(pb);
888
        }
889
    } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
890
        for(i=0; i<entries; i++) {
891
            sc->chunk_offsets[i] = get_be64(pb);
892
        }
893
    } else
894
        return -1;
895

    
896
    for(i=0; i<c->fc->nb_streams; i++){
897
        MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
898
        if(sc2 && sc2->chunk_offsets){
899
            int64_t first= sc2->chunk_offsets[0];
900
            int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
901
            if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
902
                c->ni=1;
903
        }
904
    }
905
    return 0;
906
}
907

    
908
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
909
{
910
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
911
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
912
    int entries, frames_per_sample;
913
    uint32_t format;
914
    uint8_t codec_name[32];
915

    
916
    /* for palette traversal */
917
    int color_depth;
918
    int color_start;
919
    int color_count;
920
    int color_end;
921
    int color_index;
922
    int color_dec;
923
    int color_greyscale;
924
    unsigned char *color_table;
925
    int j;
926
    unsigned char r, g, b;
927

    
928
    get_byte(pb); /* version */
929
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
930

    
931
    entries = get_be32(pb);
932

    
933
    while(entries--) { //Parsing Sample description table
934
        enum CodecID id;
935
        MOV_atom_t a = { 0, 0, 0 };
936
        offset_t start_pos = url_ftell(pb);
937
        int size = get_be32(pb); /* size */
938
        format = get_le32(pb); /* data format */
939

    
940
        get_be32(pb); /* reserved */
941
        get_be16(pb); /* reserved */
942
        get_be16(pb); /* index */
943

    
944
        dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
945
                size,
946
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
947
                st->codec->codec_type);
948
        st->codec->codec_tag = format;
949
        id = codec_get_id(mov_audio_tags, format);
950
        if (id > 0) {
951
            st->codec->codec_type = CODEC_TYPE_AUDIO;
952
        } else if (format != MKTAG('m', 'p', '4', 's')) { /* skip old asf mpeg4 tag */
953
            id = codec_get_id(mov_video_tags, format);
954
            if (id <= 0)
955
                id = codec_get_id(codec_bmp_tags, format);
956
            if (id > 0)
957
                st->codec->codec_type = CODEC_TYPE_VIDEO;
958
        }
959

    
960
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
961
            st->codec->codec_id = id;
962
            get_be16(pb); /* version */
963
            get_be16(pb); /* revision level */
964
            get_be32(pb); /* vendor */
965
            get_be32(pb); /* temporal quality */
966
            get_be32(pb); /* spacial quality */
967
            if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
968
                get_be16(pb);
969
                get_be16(pb);
970
            }else{
971
                st->codec->width = get_be16(pb); /* width */
972
                st->codec->height = get_be16(pb); /* height */
973
            }
974
            get_be32(pb); /* horiz resolution */
975
            get_be32(pb); /* vert resolution */
976
            get_be32(pb); /* data size, always 0 */
977
            frames_per_sample = get_be16(pb); /* frames per samples */
978
#ifdef DEBUG
979
            av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
980
#endif
981
            get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
982
            if (codec_name[0] <= 31) {
983
                memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
984
                st->codec->codec_name[codec_name[0]] = 0;
985
            }
986

    
987
            st->codec->bits_per_sample = get_be16(pb); /* depth */
988
            st->codec->color_table_id = get_be16(pb); /* colortable id */
989

    
990
/*          These are set in mov_read_stts and might already be set!
991
            st->codec->time_base.den      = 25;
992
            st->codec->time_base.num = 1;
993
*/
994

    
995
            /* figure out the palette situation */
996
            color_depth = st->codec->bits_per_sample & 0x1F;
997
            color_greyscale = st->codec->bits_per_sample & 0x20;
998

    
999
            /* if the depth is 2, 4, or 8 bpp, file is palettized */
1000
            if ((color_depth == 2) || (color_depth == 4) ||
1001
                (color_depth == 8)) {
1002

    
1003
                if (color_greyscale) {
1004

    
1005
                    /* compute the greyscale palette */
1006
                    color_count = 1 << color_depth;
1007
                    color_index = 255;
1008
                    color_dec = 256 / (color_count - 1);
1009
                    for (j = 0; j < color_count; j++) {
1010
                        r = g = b = color_index;
1011
                        c->palette_control.palette[j] =
1012
                            (r << 16) | (g << 8) | (b);
1013
                        color_index -= color_dec;
1014
                        if (color_index < 0)
1015
                            color_index = 0;
1016
                    }
1017

    
1018
                } else if (st->codec->color_table_id & 0x08) {
1019

    
1020
                    /* if flag bit 3 is set, use the default palette */
1021
                    color_count = 1 << color_depth;
1022
                    if (color_depth == 2)
1023
                        color_table = ff_qt_default_palette_4;
1024
                    else if (color_depth == 4)
1025
                        color_table = ff_qt_default_palette_16;
1026
                    else
1027
                        color_table = ff_qt_default_palette_256;
1028

    
1029
                    for (j = 0; j < color_count; j++) {
1030
                        r = color_table[j * 4 + 0];
1031
                        g = color_table[j * 4 + 1];
1032
                        b = color_table[j * 4 + 2];
1033
                        c->palette_control.palette[j] =
1034
                            (r << 16) | (g << 8) | (b);
1035
                    }
1036

    
1037
                } else {
1038

    
1039
                    /* load the palette from the file */
1040
                    color_start = get_be32(pb);
1041
                    color_count = get_be16(pb);
1042
                    color_end = get_be16(pb);
1043
                    for (j = color_start; j <= color_end; j++) {
1044
                        /* each R, G, or B component is 16 bits;
1045
                         * only use the top 8 bits; skip alpha bytes
1046
                         * up front */
1047
                        get_byte(pb);
1048
                        get_byte(pb);
1049
                        r = get_byte(pb);
1050
                        get_byte(pb);
1051
                        g = get_byte(pb);
1052
                        get_byte(pb);
1053
                        b = get_byte(pb);
1054
                        get_byte(pb);
1055
                        c->palette_control.palette[j] =
1056
                            (r << 16) | (g << 8) | (b);
1057
                    }
1058
                }
1059

    
1060
                st->codec->palctrl = &c->palette_control;
1061
                st->codec->palctrl->palette_changed = 1;
1062
            } else
1063
                st->codec->palctrl = NULL;
1064
        } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
1065
            uint16_t version = get_be16(pb);
1066

    
1067
            st->codec->codec_id = id;
1068
            get_be16(pb); /* revision level */
1069
            get_be32(pb); /* vendor */
1070

    
1071
            st->codec->channels = get_be16(pb);             /* channel count */
1072
            st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1073
            /* do we need to force to 16 for AMR ? */
1074

    
1075
            /* handle specific s8 codec */
1076
            get_be16(pb); /* compression id = 0*/
1077
            get_be16(pb); /* packet size = 0 */
1078

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

    
1081
            switch (st->codec->codec_id) {
1082
            case CODEC_ID_PCM_S16LE:
1083
            case CODEC_ID_PCM_S16BE:
1084
                if (st->codec->bits_per_sample == 8)
1085
                    st->codec->codec_id = CODEC_ID_PCM_S8;
1086
                st->codec->bit_rate = st->codec->sample_rate * 8;
1087
                break;
1088
            case CODEC_ID_PCM_U8:
1089
                if (st->codec->bits_per_sample == 16)
1090
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
1091
                st->codec->bit_rate = st->codec->sample_rate * 8;
1092
                break;
1093
            case CODEC_ID_AMR_WB:
1094
                st->codec->sample_rate = 16000; /* should really we ? */
1095
                st->codec->channels=1; /* really needed */
1096
                break;
1097
            case CODEC_ID_AMR_NB:
1098
                st->codec->sample_rate = 8000; /* should really we ? */
1099
                st->codec->channels=1; /* really needed */
1100
                break;
1101
            default:
1102
                break;
1103
            }
1104

    
1105
            //Read QT version 1 fields. In version 0 theese dont exist
1106
            dprintf("version =%d mp4=%d\n",version,c->mp4);
1107
            if(version==1) {
1108
                get_be32(pb); /* samples per packet */
1109
                get_be32(pb); /* bytes per packet */
1110
                get_be32(pb); /* bytes per frame */
1111
                get_be32(pb); /* bytes per sample */
1112
            } else if(version==2) {
1113
                get_be32(pb); /* sizeof struct only */
1114
                st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */
1115
                st->codec->channels = get_be32(pb);
1116
                get_be32(pb); /* always 0x7F000000 */
1117
                get_be32(pb); /* bits per channel if sound is uncompressed */
1118
                get_be32(pb); /* lcpm format specific flag */
1119
                get_be32(pb); /* bytes per audio packet if constant */
1120
                get_be32(pb); /* lpcm frames per audio packet if constant */
1121
            }
1122
        } else {
1123
            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
1124
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
1125
        }
1126
        /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
1127
        a.size = size - (url_ftell(pb) - start_pos);
1128
        if (a.size > 8)
1129
            mov_read_default(c, pb, a);
1130
        else if (a.size > 0)
1131
            url_fskip(pb, a.size);
1132
    }
1133

    
1134
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1135
        st->codec->sample_rate= sc->time_scale;
1136
    }
1137
#ifdef CONFIG_FAAD
1138
    if(st->codec->codec_id ==CODEC_ID_AAC) {
1139
        st->codec->sample_rate= 0; /* let faad init parameters properly */
1140
    }
1141
#endif
1142

    
1143
    return 0;
1144
}
1145

    
1146
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1147
{
1148
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1149
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1150
    unsigned int i, entries;
1151

    
1152
    get_byte(pb); /* version */
1153
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1154

    
1155
    entries = get_be32(pb);
1156

    
1157
    if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1158
        return -1;
1159

    
1160
#ifdef DEBUG
1161
av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1162
#endif
1163
    sc->sample_to_chunk_sz = entries;
1164
    sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1165
    if (!sc->sample_to_chunk)
1166
        return -1;
1167
    for(i=0; i<entries; i++) {
1168
        sc->sample_to_chunk[i].first = get_be32(pb);
1169
        sc->sample_to_chunk[i].count = get_be32(pb);
1170
        sc->sample_to_chunk[i].id = get_be32(pb);
1171
    }
1172
    return 0;
1173
}
1174

    
1175
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1176
{
1177
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1178
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1179
    unsigned int i, entries;
1180

    
1181
    get_byte(pb); /* version */
1182
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1183

    
1184
    entries = get_be32(pb);
1185

    
1186
    if(entries >= UINT_MAX / sizeof(long))
1187
        return -1;
1188

    
1189
    sc->keyframe_count = entries;
1190
#ifdef DEBUG
1191
    av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1192
#endif
1193
    sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1194
    if (!sc->keyframes)
1195
        return -1;
1196
    for(i=0; i<entries; i++) {
1197
        sc->keyframes[i] = get_be32(pb);
1198
#ifdef DEBUG
1199
/*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1200
#endif
1201
    }
1202
    return 0;
1203
}
1204

    
1205
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1206
{
1207
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1208
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1209
    unsigned int i, entries;
1210

    
1211
    get_byte(pb); /* version */
1212
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1213

    
1214
    sc->sample_size = get_be32(pb);
1215
    entries = get_be32(pb);
1216
    if(entries >= UINT_MAX / sizeof(long))
1217
        return -1;
1218

    
1219
    sc->sample_count = entries;
1220
#ifdef DEBUG
1221
    av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1222
#endif
1223
    if(sc->sample_size) {
1224
        /* override sample size for uncompressed sound */
1225
        switch (st->codec->codec_id) {
1226
        case CODEC_ID_PCM_S32BE:
1227
        case CODEC_ID_PCM_S32LE:
1228
            sc->sample_size = 4 * st->codec->channels;
1229
            break;
1230
        case CODEC_ID_PCM_S24BE:
1231
        case CODEC_ID_PCM_S24LE:
1232
            sc->sample_size = 3 * st->codec->channels;
1233
            break;
1234
        case CODEC_ID_PCM_S16BE:
1235
        case CODEC_ID_PCM_S16LE:
1236
            sc->sample_size = 2 * st->codec->channels;
1237
            break;
1238
        case CODEC_ID_PCM_MULAW:
1239
        case CODEC_ID_PCM_ALAW:
1240
        case CODEC_ID_PCM_S8:
1241
        case CODEC_ID_PCM_U8:
1242
            sc->sample_size = 1 * st->codec->channels;
1243
            break;
1244
        default:
1245
            break;
1246
        }
1247
        assert(sc->sample_size);
1248
        return 0; /* there isn't any table following */
1249
    }
1250
    sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1251
    if (!sc->sample_sizes)
1252
        return -1;
1253
    for(i=0; i<entries; i++) {
1254
        sc->sample_sizes[i] = get_be32(pb);
1255
#ifdef DEBUG
1256
        av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1257
#endif
1258
    }
1259
    return 0;
1260
}
1261

    
1262
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1263
{
1264
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1265
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1266
    unsigned int i, entries;
1267
    int64_t duration=0;
1268
    int64_t total_sample_count=0;
1269

    
1270
    get_byte(pb); /* version */
1271
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1272
    entries = get_be32(pb);
1273
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1274
        return -1;
1275

    
1276
    sc->stts_count = entries;
1277
    sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1278

    
1279
#ifdef DEBUG
1280
av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1281
#endif
1282

    
1283
    sc->time_rate=0;
1284

    
1285
    for(i=0; i<entries; i++) {
1286
        int sample_duration;
1287
        int sample_count;
1288

    
1289
        sample_count=get_be32(pb);
1290
        sample_duration = get_be32(pb);
1291
        sc->stts_data[i].count= sample_count;
1292
        sc->stts_data[i].duration= sample_duration;
1293

    
1294
        sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1295

    
1296
        dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1297

    
1298
        duration+=(int64_t)sample_duration*sample_count;
1299
        total_sample_count+=sample_count;
1300
    }
1301

    
1302
    st->nb_frames= total_sample_count;
1303
    if(duration)
1304
        st->duration= duration;
1305
    return 0;
1306
}
1307

    
1308
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1309
{
1310
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1311
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1312
    unsigned int i, entries;
1313

    
1314
    get_byte(pb); /* version */
1315
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1316
    entries = get_be32(pb);
1317
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1318
        return -1;
1319

    
1320
    sc->ctts_count = entries;
1321
    sc->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1322

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

    
1325
    for(i=0; i<entries; i++) {
1326
        int count    =get_be32(pb);
1327
        int duration =get_be32(pb);
1328

    
1329
        sc->ctts_data[i].count   = count;
1330
        sc->ctts_data[i].duration= duration;
1331

    
1332
        sc->time_rate= ff_gcd(sc->time_rate, duration);
1333
    }
1334
    return 0;
1335
}
1336

    
1337
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1338
{
1339
    AVStream *st;
1340
    MOVStreamContext *sc;
1341

    
1342
    st = av_new_stream(c->fc, c->fc->nb_streams);
1343
    if (!st) return -2;
1344
    sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1345
    if (!sc) {
1346
        av_free(st);
1347
        return -1;
1348
    }
1349

    
1350
    sc->sample_to_chunk_index = -1;
1351
    st->priv_data = sc;
1352
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1353
    st->start_time = 0; /* XXX: check */
1354
    c->streams[c->fc->nb_streams-1] = sc;
1355

    
1356
    return mov_read_default(c, pb, atom);
1357
}
1358

    
1359
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1360
{
1361
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1362
    int version = get_byte(pb);
1363

    
1364
    get_byte(pb); get_byte(pb);
1365
    get_byte(pb); /* flags */
1366
    /*
1367
    MOV_TRACK_ENABLED 0x0001
1368
    MOV_TRACK_IN_MOVIE 0x0002
1369
    MOV_TRACK_IN_PREVIEW 0x0004
1370
    MOV_TRACK_IN_POSTER 0x0008
1371
    */
1372

    
1373
    if (version == 1) {
1374
        get_be64(pb);
1375
        get_be64(pb);
1376
    } else {
1377
        get_be32(pb); /* creation time */
1378
        get_be32(pb); /* modification time */
1379
    }
1380
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1381
    get_be32(pb); /* reserved */
1382
    st->start_time = 0; /* check */
1383
    (version == 1) ? get_be64(pb) : get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1384
    get_be32(pb); /* reserved */
1385
    get_be32(pb); /* reserved */
1386

    
1387
    get_be16(pb); /* layer */
1388
    get_be16(pb); /* alternate group */
1389
    get_be16(pb); /* volume */
1390
    get_be16(pb); /* reserved */
1391

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

    
1394
    /* those are fixed-point */
1395
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1396
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1397

    
1398
    return 0;
1399
}
1400

    
1401
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1402
/* like the files created with Adobe Premiere 5.0, for samples see */
1403
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1404
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1405
{
1406
    int err;
1407

    
1408
    if (atom.size < 8)
1409
        return 0; /* continue */
1410
    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1411
        url_fskip(pb, atom.size - 4);
1412
        return 0;
1413
    }
1414
    atom.type = get_le32(pb);
1415
    atom.offset += 8;
1416
    atom.size -= 8;
1417
    if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1418
        url_fskip(pb, atom.size);
1419
        return 0;
1420
    }
1421
    err = mov_read_mdat(c, pb, atom);
1422
    return err;
1423
}
1424

    
1425

    
1426
#ifdef CONFIG_ZLIB
1427
static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1428
{
1429
    return -1;
1430
}
1431

    
1432
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1433
{
1434
    ByteIOContext ctx;
1435
    uint8_t *cmov_data;
1436
    uint8_t *moov_data; /* uncompressed data */
1437
    long cmov_len, moov_len;
1438
    int ret;
1439

    
1440
    get_be32(pb); /* dcom atom */
1441
    if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1442
        return -1;
1443
    if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1444
        av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
1445
        return -1;
1446
    }
1447
    get_be32(pb); /* cmvd atom */
1448
    if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1449
        return -1;
1450
    moov_len = get_be32(pb); /* uncompressed size */
1451
    cmov_len = atom.size - 6 * 4;
1452

    
1453
    cmov_data = (uint8_t *) av_malloc(cmov_len);
1454
    if (!cmov_data)
1455
        return -1;
1456
    moov_data = (uint8_t *) av_malloc(moov_len);
1457
    if (!moov_data) {
1458
        av_free(cmov_data);
1459
        return -1;
1460
    }
1461
    get_buffer(pb, cmov_data, cmov_len);
1462
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1463
        return -1;
1464
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1465
        return -1;
1466
    ctx.buf_end = ctx.buffer + moov_len;
1467
    atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1468
    atom.offset = 0;
1469
    atom.size = moov_len;
1470
#ifdef DEBUG
1471
//    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1472
#endif
1473
    ret = mov_read_default(c, &ctx, atom);
1474
    av_free(moov_data);
1475
    av_free(cmov_data);
1476

    
1477
    return ret;
1478
}
1479
#endif
1480

    
1481
/* edit list atom */
1482
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1483
{
1484
  int i, edit_count;
1485

    
1486
  get_byte(pb); /* version */
1487
  get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1488
  edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1489

    
1490
  for(i=0; i<edit_count; i++){
1491
    get_be32(pb); /* Track duration */
1492
    get_be32(pb); /* Media time */
1493
    get_be32(pb); /* Media rate */
1494
  }
1495
  dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1496
  return 0;
1497
}
1498

    
1499
static const MOVParseTableEntry mov_default_parse_table[] = {
1500
/* mp4 atoms */
1501
{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1502
{ MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1503
{ MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1504
{ MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1505
{ MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1506
{ MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1507
{ MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1508
{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1509
{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1510
{ MKTAG( 'e', 'n', 'd', 'a' ), mov_read_enda },
1511
{ MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1512
{ MKTAG( 'f', 't', 'y', 'p' ), mov_read_ftyp },
1513
{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1514
{ MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1515
{ MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1516
{ MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
1517
{ MKTAG( 'j', 'p', '2', 'h' ), mov_read_jp2h },
1518
{ MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1519
{ MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1520
{ MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1521
{ MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1522
{ MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
1523
{ MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },
1524
{ MKTAG( 'm', 'p', '4', 's' ), mov_read_default },
1525
{ MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },
1526
{ MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },
1527
{ MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
1528
{ MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },
1529
{ MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },
1530
{ MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },
1531
{ MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },
1532
{ MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */
1533
{ MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
1534
{ MKTAG( 'a', 'l', 'a', 'c' ), mov_read_alac }, /* alac specific atom */
1535
{ MKTAG( 'a', 'v', 'c', 'C' ), mov_read_avcC },
1536
{ MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1537
{ MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1538
{ MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1539
{ MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1540
{ MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1541
{ MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1542
{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1543
{ MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1544
{ MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1545
{ MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1546
{ MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1547
{ MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1548
{ MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1549
{ MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1550
{ MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1551
{ MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1552
{ MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1553
{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1554
/* extra mp4 */
1555
{ MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1556
/* QT atoms */
1557
{ MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1558
{ MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1559
{ MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1560
{ MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1561
{ MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1562
{ MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1563
{ MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1564
{ MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1565
{ MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1566
{ MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1567
{ MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1568
{ MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1569
{ MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1570
{ MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1571
{ MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1572
{ MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1573
//{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1574
#ifdef CONFIG_ZLIB
1575
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1576
#else
1577
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1578
#endif
1579
{ 0L, mov_read_leaf }
1580
};
1581

    
1582
static void mov_free_stream_context(MOVStreamContext *sc)
1583
{
1584
    if(sc) {
1585
        av_freep(&sc->chunk_offsets);
1586
        av_freep(&sc->sample_to_chunk);
1587
        av_freep(&sc->sample_sizes);
1588
        av_freep(&sc->keyframes);
1589
        av_freep(&sc->stts_data);
1590
        av_freep(&sc->ctts_data);
1591
        av_freep(&sc);
1592
    }
1593
}
1594

    
1595
static inline uint32_t mov_to_tag(uint8_t *buf)
1596
{
1597
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1598
}
1599

    
1600
static inline uint32_t to_be32(uint8_t *buf)
1601
{
1602
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1603
}
1604

    
1605
/* XXX: is it sufficient ? */
1606
static int mov_probe(AVProbeData *p)
1607
{
1608
    unsigned int offset;
1609
    uint32_t tag;
1610
    int score = 0;
1611

    
1612
    /* check file header */
1613
    if (p->buf_size <= 12)
1614
        return 0;
1615
    offset = 0;
1616
    for(;;) {
1617
        /* ignore invalid offset */
1618
        if ((offset + 8) > (unsigned int)p->buf_size)
1619
            return score;
1620
        tag = mov_to_tag(p->buf + offset + 4);
1621
        switch(tag) {
1622
        /* check for obvious tags */
1623
        case MKTAG( 'j', 'P', ' ', ' ' ): /* jpeg 2000 signature */
1624
        case MKTAG( 'm', 'o', 'o', 'v' ):
1625
        case MKTAG( 'm', 'd', 'a', 't' ):
1626
        case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1627
        case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1628
            return AVPROBE_SCORE_MAX;
1629
        /* those are more common words, so rate then a bit less */
1630
        case MKTAG( 'w', 'i', 'd', 'e' ):
1631
        case MKTAG( 'f', 'r', 'e', 'e' ):
1632
        case MKTAG( 'j', 'u', 'n', 'k' ):
1633
        case MKTAG( 'p', 'i', 'c', 't' ):
1634
            return AVPROBE_SCORE_MAX - 5;
1635
        case MKTAG( 'f', 't', 'y', 'p' ):
1636
        case MKTAG( 's', 'k', 'i', 'p' ):
1637
        case MKTAG( 'u', 'u', 'i', 'd' ):
1638
            offset = to_be32(p->buf+offset) + offset;
1639
            /* if we only find those cause probedata is too small at least rate them */
1640
            score = AVPROBE_SCORE_MAX - 50;
1641
            break;
1642
        default:
1643
            /* unrecognized tag */
1644
            return score;
1645
        }
1646
    }
1647
    return score;
1648
}
1649

    
1650
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1651
{
1652
    MOVContext *mov = (MOVContext *) s->priv_data;
1653
    ByteIOContext *pb = &s->pb;
1654
    int i, j, nb, err;
1655
    MOV_atom_t atom = { 0, 0, 0 };
1656

    
1657
    mov->fc = s;
1658
    mov->parse_table = mov_default_parse_table;
1659

    
1660
    if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1661
        atom.size = url_fsize(pb);
1662
    else
1663
        atom.size = 0x7FFFFFFFFFFFFFFFLL;
1664

    
1665
    /* check MOV header */
1666
    err = mov_read_default(mov, pb, atom);
1667
    if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1668
        av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1669
                err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1670
        return -1;
1671
    }
1672
    dprintf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1673

    
1674
    /* some cleanup : make sure we are on the mdat atom */
1675
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1676
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1677

    
1678
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1679
    mov->total_streams = nb = s->nb_streams;
1680

    
1681
#if 1
1682
    for(i=0; i<s->nb_streams;) {
1683
        if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1684
            av_free(s->streams[i]);
1685
            for(j=i+1; j<s->nb_streams; j++)
1686
                s->streams[j-1] = s->streams[j];
1687
            s->nb_streams--;
1688
        } else
1689
            i++;
1690
    }
1691
    for(i=0; i<s->nb_streams;i++) {
1692
        MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
1693

    
1694
        if(!sc->time_rate)
1695
            sc->time_rate=1;
1696
        if(!sc->time_scale)
1697
            sc->time_scale= mov->time_scale;
1698
        av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1699

    
1700
        if(s->streams[i]->duration != AV_NOPTS_VALUE){
1701
            assert(s->streams[i]->duration % sc->time_rate == 0);
1702
            s->streams[i]->duration /= sc->time_rate;
1703
        }
1704

    
1705
        sc->ffindex = i;
1706
        sc->is_ff_stream = 1;
1707
    }
1708
#endif
1709
    return 0;
1710
}
1711

    
1712
/* Yes, this is ugly... I didn't write the specs of QT :p */
1713
/* XXX:remove useless commented code sometime */
1714
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1715
{
1716
    MOVContext *mov = (MOVContext *) s->priv_data;
1717
    MOVStreamContext *sc;
1718
    AVStream *st;
1719
    int64_t offset = INT64_MAX;
1720
    int64_t best_dts = INT64_MAX;
1721
    int i, a, b, m;
1722
    int next_sample= -99;
1723
    int size;
1724
    int idx;
1725
    size = 0x0FFFFFFF;
1726

    
1727
    if (mov->partial) {
1728
        sc = mov->partial;
1729
        idx = sc->sample_to_chunk_index;
1730

    
1731
        if (idx < 0) return 0;
1732
        dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1733
        //size = sc->sample_sizes[sc->current_sample];
1734
        // that ain't working...
1735
        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1736
        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1737

    
1738
        next_sample= sc->current_sample+1;
1739

    
1740
        sc->left_in_chunk--;
1741

    
1742
        if (sc->left_in_chunk <= 0)
1743
            mov->partial = 0;
1744
        offset = mov->next_chunk_offset;
1745
        /* extract the sample */
1746

    
1747
        goto readchunk;
1748
    }
1749

    
1750
again:
1751
    sc = 0;
1752
    if(offset == INT64_MAX)
1753
        best_dts= INT64_MAX;
1754
    for(i=0; i<mov->total_streams; i++) {
1755
        MOVStreamContext *msc = mov->streams[i];
1756

    
1757
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1758
            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1759
                int64_t dts;
1760
                int index= msc->sample_to_time_index;
1761
                int sample= msc->sample_to_time_sample;
1762
                int time= msc->sample_to_time_time;
1763
                int duration = msc->stts_data[index].duration;
1764
                int count = msc->stts_data[index].count;
1765
                if (sample + count <= msc->current_sample) {
1766
                    sample += count;
1767
                    time   += count*duration;
1768
                    index ++;
1769
                    duration = msc->stts_data[index].duration;
1770
                }
1771
                dts = time + (msc->current_sample - sample) * (int64_t)duration;
1772
                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1773
                dprintf("stream: %d dts: %"PRId64" best_dts: %"PRId64" offset: %"PRId64"\n", i, dts, best_dts, offset);
1774
                if(dts < best_dts){
1775
                    best_dts= dts;
1776
                    sc = msc;
1777
                    offset = msc->chunk_offsets[msc->next_chunk];
1778
                }
1779
            }else{
1780
                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1781
                    sc = msc;
1782
                    offset = msc->chunk_offsets[msc->next_chunk];
1783
                }
1784
            }
1785
        }
1786
    }
1787
    if (!sc || offset==INT64_MAX)
1788
        return -1;
1789

    
1790
    sc->next_chunk++;
1791

    
1792
    if(mov->next_chunk_offset < offset) { /* some meta data */
1793
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1794
        mov->next_chunk_offset = offset;
1795
    }
1796

    
1797
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1798
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1799
        mov->next_chunk_offset = offset;
1800
        offset = INT64_MAX;
1801
        goto again;
1802
    }
1803

    
1804
    /* now get the chunk size... */
1805

    
1806
    for(i=0; i<mov->total_streams; i++) {
1807
        MOVStreamContext *msc = mov->streams[i];
1808
        if ((msc->next_chunk < msc->chunk_count)
1809
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1810
            && msc->chunk_offsets[msc->next_chunk] > offset)
1811
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1812
    }
1813

    
1814
#ifdef MOV_MINOLTA_FIX
1815
    //Make sure that size is according to sample_size (Needed by .mov files
1816
    //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1817
    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1818
    //but I have no such movies
1819
    if (sc->sample_size > 0) {
1820
        int foundsize=0;
1821
        for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1822
            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1823
            {
1824
                foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
1825
            }
1826
            dprintf("sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id);
1827
        }
1828
        if( (foundsize>0) && (foundsize<size) )
1829
        {
1830
            size=foundsize;
1831
        }
1832
    }
1833
#endif //MOV_MINOLTA_FIX
1834

    
1835
    idx = sc->sample_to_chunk_index;
1836
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1837
        idx++;
1838
    sc->sample_to_chunk_index = idx;
1839
    /* split chunks into samples */
1840
    if (sc->sample_size == 0 || sc->sample_size > 100) {
1841
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1842
            mov->partial = sc;
1843
            /* we'll have to get those samples before next chunk */
1844
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1845
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1846
        }
1847

    
1848
        next_sample= sc->current_sample+1;
1849
    }else if(idx < sc->sample_to_chunk_sz){
1850
        next_sample= sc->current_sample + sc->sample_to_chunk[idx].count;
1851
    }else
1852
        next_sample= sc->current_sample;
1853

    
1854
readchunk:
1855
    dprintf("chunk: %"PRId64" -> %"PRId64" (%i)\n", offset, offset + size, size);
1856
    if(size == 0x0FFFFFFF)
1857
        size = mov->mdat_size + mov->mdat_offset - offset;
1858
    if(size < 0)
1859
        return -1;
1860
    if(size == 0)
1861
        return -1;
1862
    url_fseek(&s->pb, offset, SEEK_SET);
1863

    
1864
    av_get_packet(&s->pb, pkt, size);
1865
    pkt->stream_index = sc->ffindex;
1866

    
1867
    // If the keyframes table exists, mark any samples that are in the table as key frames.
1868
    // If no table exists, treat very sample as a key frame.
1869
    if (sc->keyframes) {
1870
        a = 0;
1871
        b = sc->keyframe_count - 1;
1872

    
1873
        while (a < b) {
1874
            m = (a + b + 1) >> 1;
1875
            if (sc->keyframes[m] > sc->current_sample) {
1876
                b = m - 1;
1877
            } else {
1878
                a = m;
1879
            }
1880
        }
1881

    
1882
        if (sc->keyframes[a] == sc->current_sample)
1883
            pkt->flags |= PKT_FLAG_KEY;
1884
    }
1885
    else
1886
        pkt->flags |= PKT_FLAG_KEY;
1887

    
1888
    mov->next_chunk_offset = offset + size;
1889

    
1890
    /* find the corresponding dts */
1891
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1892
      unsigned int count;
1893
      uint64_t dts, pts;
1894
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1895
      count = sc->stts_data[sc->sample_to_time_index].count;
1896
      if ((sc->sample_to_time_sample + count) <= sc->current_sample) {
1897
        sc->sample_to_time_sample += count;
1898
        sc->sample_to_time_time   += count*duration;
1899
        sc->sample_to_time_index ++;
1900
        duration = sc->stts_data[sc->sample_to_time_index].duration;
1901
      }
1902
      dts = sc->sample_to_time_time + (sc->current_sample - sc->sample_to_time_sample) * (int64_t)duration;
1903
        /* find the corresponding pts */
1904
        if (sc->sample_to_ctime_index < sc->ctts_count) {
1905
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1906
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1907

    
1908
            if ((sc->sample_to_ctime_sample + count) <= sc->current_sample) {
1909
                sc->sample_to_ctime_sample += count;
1910
                sc->sample_to_ctime_index ++;
1911
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1912
            }
1913
            pts = dts + duration;
1914
        }else
1915
            pts = dts;
1916

    
1917
        st= s->streams[ sc->ffindex ];
1918
        assert(pts % st->time_base.num == 0);
1919
        assert(dts % st->time_base.num == 0);
1920

    
1921
        pkt->pts = pts / st->time_base.num;
1922
        pkt->dts = dts / st->time_base.num;
1923
        dprintf("stream #%d smp #%ld dts = %"PRId64" pts = %"PRId64" (smp:%ld time:%"PRId64" idx:%d ent:%d count:%d dur:%d)\n"
1924
                , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1925
                , sc->sample_to_time_sample
1926
                , sc->sample_to_time_time
1927
                , sc->sample_to_time_index
1928
                , sc->stts_count
1929
                , count
1930
                , duration);
1931
    }
1932

    
1933
    assert(next_sample>=0);
1934
    sc->current_sample= next_sample;
1935

    
1936
    return 0;
1937
}
1938

    
1939
#if defined(MOV_SEEK)
1940
/**
1941
 * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1942
 */
1943
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1944
{
1945
    MOVContext* mov = (MOVContext *) s->priv_data;
1946
    MOVStreamContext* sc;
1947
    int32_t i, a, b, m;
1948
    int64_t start_time;
1949
    int32_t seek_sample, sample;
1950
    int32_t duration;
1951
    int32_t count;
1952
    int32_t chunk;
1953
    int32_t left_in_chunk;
1954
    int64_t chunk_file_offset;
1955
    int64_t sample_file_offset;
1956
    int32_t first_chunk_sample;
1957
    int32_t sample_to_chunk_idx;
1958
    int sample_to_time_index;
1959
    long sample_to_time_sample = 0;
1960
    uint64_t sample_to_time_time = 0;
1961
    int mov_idx;
1962

    
1963
    // Find the corresponding mov stream
1964
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1965
        if (mov->streams[mov_idx]->ffindex == stream_index)
1966
            break;
1967
    if (mov_idx == mov->total_streams) {
1968
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1969
        return -1;
1970
    }
1971
    sc = mov->streams[mov_idx];
1972

    
1973
    sample_time *= s->streams[stream_index]->time_base.num;
1974

    
1975
    // Step 1. Find the edit that contains the requested time (elst)
1976
    if (sc->edit_count && 0) {
1977
        // FIXME should handle edit list
1978
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
1979
        return -1;
1980
    }
1981

    
1982
    // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */
1983
    dprintf("Searching for time %li in stream #%i (time_scale=%i)\n", (long)sample_time, mov_idx, sc->time_scale);
1984
    start_time = 0; // FIXME use elst atom
1985
    sample = 1; // sample are 0 based in table
1986

    
1987
    for (i = 0; i < sc->stts_count; i++) {
1988
        count = sc->stts_data[i].count;
1989
        duration = sc->stts_data[i].duration;
1990
        if ((start_time + count*duration) > sample_time) {
1991
            sample_to_time_time = start_time;
1992
            sample_to_time_index = i;
1993
            sample_to_time_sample = sample;
1994
            sample += (sample_time - start_time) / duration;
1995
            break;
1996
        }
1997
        sample += count;
1998
        start_time += count * duration;
1999
    }
2000
    sample_to_time_time = start_time;
2001
    sample_to_time_index = i;
2002
    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
2003
       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
2004

    
2005
    dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
2006
    if (sample > sc->sample_count) {
2007
        av_log(s, AV_LOG_ERROR, "mov: sample pos is too high, unable to seek (req. sample=%i, sample count=%ld)\n", sample, sc->sample_count);
2008
        return -1;
2009
    }
2010

    
2011
    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
2012
    if (sc->keyframes) {
2013
        a = 0;
2014
        b = sc->keyframe_count - 1;
2015
        while (a < b) {
2016
            m = (a + b + 1) >> 1;
2017
            if (sc->keyframes[m] > sample) {
2018
                b = m - 1;
2019
            } else {
2020
                a = m;
2021
            }
2022
        }
2023
        // for low latency prob: always use the previous keyframe, just uncomment the next line
2024
        // if (a) a--;
2025
        seek_sample = sc->keyframes[a];
2026
    }
2027
    else
2028
        seek_sample = sample; // else all samples are key frames
2029
    dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
2030

    
2031
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2032
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2033
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2034
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2035
            break;
2036
        first_chunk_sample += b;
2037
    }
2038
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2039
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2040
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2041
    sample_to_chunk_idx = i;
2042
    dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2043

    
2044
    // Step 5. Find the offset of the chunk using the chunk offset atom
2045
    if (!sc->chunk_offsets) {
2046
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2047
        return -1;
2048
    }
2049
    if (chunk > sc->chunk_count) {
2050
        av_log(s, AV_LOG_ERROR, "mov: chunk offset atom too short, unable to seek (req. chunk=%i, chunk count=%li)\n", chunk, sc->chunk_count);
2051
        return -1;
2052
    }
2053
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
2054
    dprintf("Chunk file offset is #%"PRIu64"\n", chunk_file_offset);
2055

    
2056
    // Step 6. Find the byte offset within the chunk using the sample size atom
2057
    sample_file_offset = chunk_file_offset;
2058
    if (sc->sample_size)
2059
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2060
    else {
2061
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2062
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2063
        }
2064
    }
2065
    dprintf("Sample file offset is #%"PRIu64"\n", sample_file_offset);
2066

    
2067
    // Step 6. Update the parser
2068
    mov->partial = sc;
2069
    mov->next_chunk_offset = sample_file_offset;
2070
    // Update current stream state
2071
    sc->current_sample = seek_sample - 1;  // zero based
2072
    sc->left_in_chunk = left_in_chunk;
2073
    sc->next_chunk = chunk; // +1 -1 (zero based)
2074
    sc->sample_to_chunk_index = sample_to_chunk_idx;
2075

    
2076
    // Update other streams
2077
    for (i = 0; i<mov->total_streams; i++) {
2078
        MOVStreamContext *msc;
2079
        if (i == mov_idx) continue;
2080
        // Find the nearest 'next' chunk
2081
        msc = mov->streams[i];
2082
        a = 0;
2083
        b = msc->chunk_count - 1;
2084
        while (a < b) {
2085
            m = (a + b + 1) >> 1;
2086
            if (msc->chunk_offsets[m] > chunk_file_offset) {
2087
                b = m - 1;
2088
            } else {
2089
                a = m;
2090
            }
2091
        }
2092
        msc->next_chunk = a;
2093
        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2094
            msc->next_chunk ++;
2095
        dprintf("Nearest next chunk for stream #%i is #%li @%"PRId64"\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2096

    
2097
        // Compute sample count and index in the sample_to_chunk table (what a pity)
2098
        msc->sample_to_chunk_index = 0;
2099
        msc->current_sample = 0;
2100
        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2101
            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2102
            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2103
            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2104
        }
2105
        msc->current_sample += (msc->next_chunk - (msc->sample_to_chunk[msc->sample_to_chunk_index].first - 1)) * sc->sample_to_chunk[msc->sample_to_chunk_index].count;
2106
        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2107
        // Find corresponding position in stts (used later to compute dts)
2108
        sample = 0;
2109
        start_time = 0;
2110
        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2111
            count = msc->stts_data[msc->sample_to_time_index].count;
2112
            duration = msc->stts_data[msc->sample_to_time_index].duration;
2113
            if ((sample + count - 1) > msc->current_sample) {
2114
                msc->sample_to_time_time = start_time;
2115
                msc->sample_to_time_sample = sample;
2116
                break;
2117
            }
2118
            sample += count;
2119
            start_time += count * duration;
2120
        }
2121
        sample = 0;
2122
        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2123
            count = msc->ctts_data[msc->sample_to_ctime_index].count;
2124
            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2125
            if ((sample + count - 1) > msc->current_sample) {
2126
                msc->sample_to_ctime_sample = sample;
2127
                break;
2128
            }
2129
            sample += count;
2130
        }
2131
        dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2132
    }
2133
    return 0;
2134
}
2135
#endif
2136

    
2137
static int mov_read_close(AVFormatContext *s)
2138
{
2139
    int i;
2140
    MOVContext *mov = (MOVContext *) s->priv_data;
2141
    for(i=0; i<mov->total_streams; i++)
2142
        mov_free_stream_context(mov->streams[i]);
2143
    /* free color tabs */
2144
    for(i=0; i<mov->ctab_size; i++)
2145
        av_freep(&mov->ctab[i]);
2146
    av_freep(&mov->ctab);
2147
    return 0;
2148
}
2149

    
2150
static AVInputFormat mov_iformat = {
2151
    "mov,mp4,m4a,3gp,3g2,mj2",
2152
    "QuickTime/MPEG4/Motion JPEG 2000 format",
2153
    sizeof(MOVContext),
2154
    mov_probe,
2155
    mov_read_header,
2156
    mov_read_packet,
2157
    mov_read_close,
2158
#if defined(MOV_SEEK)
2159
    mov_read_seek,
2160
#endif
2161
};
2162

    
2163
int mov_init(void)
2164
{
2165
    av_register_input_format(&mov_iformat);
2166
    return 0;
2167
}