Statistics
| Branch: | Revision:

ffmpeg / libavformat / mov.c @ 750b4aaa

History | View | Annotate | Download (76.5 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_MJPEGB, 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_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, /* AVID DV */
158
    //{ CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */
159
    { CODEC_ID_NONE, 0 },
160
};
161

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

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

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

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

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

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

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

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

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

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

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

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

    
289
struct MOVParseTableEntry;
290

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

    
322
typedef struct MOVContext {
323
    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) */
324
    AVFormatContext *fc;
325
    int time_scale;
326
    int64_t duration; /* duration of the longest track */
327
    int found_moov; /* when both 'moov' and 'mdat' sections has been found */
328
    int found_mdat; /* we suppose we have enough data to read the file */
329
    int64_t mdat_size;
330
    int64_t mdat_offset;
331
    int ni;                                         ///< non interleaved mode
332
    int total_streams;
333
    /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio
334
     * but we need the info to be able to skip data from those streams in the 'mdat' section
335
     */
336
    MOVStreamContext *streams[MAX_STREAMS];
337

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

    
345
    AVPaletteControl palette_control;
346
} MOVContext;
347

    
348

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

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

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

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

    
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
            offset_t start_pos = url_ftell(pb);
466
            int64_t left;
467
            err = (c->parse_table[i].func)(c, pb, a);
468
            left = a.size - url_ftell(pb) + start_pos;
469
            if (left > 0) /* skip garbage at atom end */
470
                url_fskip(pb, left);
471
        }
472

    
473
        a.offset += a.size;
474
        total_size += a.size;
475
    }
476

    
477
    if (!err && total_size < atom.size && atom.size < 0x7ffff) {
478
        url_fskip(pb, atom.size - total_size);
479
    }
480

    
481
    return err;
482
}
483

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

    
505
    return 0;
506
}
507

    
508
static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
509
{
510
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
511
    int len = 0;
512
    uint32_t type;
513
    uint32_t ctype;
514

    
515
    get_byte(pb); /* version */
516
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
517

    
518
    /* component type */
519
    ctype = get_le32(pb);
520
    type = get_le32(pb); /* component subtype */
521

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

    
536
    if(atom.size <= 24)
537
        return 0; /* nothing left to read */
538
    /* XXX: MP4 uses a C string, not a pascal one */
539
    /* component name */
540

    
541
    if(c->mp4) {
542
        /* .mp4: C string */
543
        while(get_byte(pb) && (++len < (atom.size - 24)));
544
    } else {
545
        /* .mov: PASCAL string */
546
        len = get_byte(pb);
547
        url_fskip(pb, len);
548
    }
549

    
550
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
551
    return 0;
552
}
553

    
554
static int mov_mp4_read_descr_len(ByteIOContext *pb)
555
{
556
    int len = 0;
557
    int count = 4;
558
    while (count--) {
559
        int c = get_byte(pb);
560
        len = (len << 7) | (c & 0x7f);
561
        if (!(c & 0x80))
562
            break;
563
    }
564
    return len;
565
}
566

    
567
static int mov_mp4_read_descr(ByteIOContext *pb, int *tag)
568
{
569
    int len;
570
    *tag = get_byte(pb);
571
    len = mov_mp4_read_descr_len(pb);
572
    dprintf("MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
573
    return len;
574
}
575

    
576
static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
577
{
578
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
579
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
580
    int tag, len;
581

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

    
591
    len = mov_mp4_read_descr(pb, &tag);
592
    if (tag == MP4DecConfigDescrTag) {
593
        sc->esds.object_type_id = get_byte(pb);
594
        sc->esds.stream_type = get_byte(pb);
595
        sc->esds.buffer_size_db = get_be24(pb);
596
        sc->esds.max_bitrate = get_be32(pb);
597
        sc->esds.avg_bitrate = get_be32(pb);
598

    
599
        st->codec->codec_id= codec_get_id(ff_mov_obj_type, sc->esds.object_type_id);
600
        len = mov_mp4_read_descr(pb, &tag);
601
        if (tag == MP4DecSpecificDescrTag) {
602
            dprintf("Specific MPEG4 header len=%d\n", len);
603
            st->codec->extradata = (uint8_t*) av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
604
            if (st->codec->extradata) {
605
                get_buffer(pb, st->codec->extradata, len);
606
                st->codec->extradata_size = len;
607
                /* from mplayer */
608
                if ((*(uint8_t *)st->codec->extradata >> 3) == 29) {
609
                    st->codec->codec_id = CODEC_ID_MP3ON4;
610
                }
611
            }
612
        }
613
    }
614
    return 0;
615
}
616

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

    
631
static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
632
{
633
    uint32_t type = get_le32(pb);
634

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

    
660
/* this atom should contain all header atoms */
661
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
662
{
663
    int err;
664

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

    
674

    
675
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
676
{
677
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
678
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
679
    int version = get_byte(pb);
680
    int lang;
681

    
682
    if (version > 1)
683
        return 1; /* unsupported */
684

    
685
    get_byte(pb); get_byte(pb);
686
    get_byte(pb); /* flags */
687

    
688
    if (version == 1) {
689
        get_be64(pb);
690
        get_be64(pb);
691
    } else {
692
        get_be32(pb); /* creation time */
693
        get_be32(pb); /* modification time */
694
    }
695

    
696
    sc->time_scale = get_be32(pb);
697
    st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
698

    
699
    lang = get_be16(pb); /* language */
700
    ff_mov_lang_to_iso639(lang, st->language);
701
    get_be16(pb); /* quality */
702

    
703
    return 0;
704
}
705

    
706
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
707
{
708
    int version = get_byte(pb); /* version */
709
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
710

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

    
725
    get_be16(pb); /* preferred volume */
726

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

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

    
731
    get_be32(pb); /* preview time */
732
    get_be32(pb); /* preview duration */
733
    get_be32(pb); /* poster time */
734
    get_be32(pb); /* selection time */
735
    get_be32(pb); /* selection duration */
736
    get_be32(pb); /* current time */
737
    get_be32(pb); /* next track ID */
738

    
739
    return 0;
740
}
741

    
742
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
743
{
744
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
745

    
746
    if((uint64_t)atom.size > (1<<30))
747
        return -1;
748

    
749
    // currently SVQ3 decoder expect full STSD header - so let's fake it
750
    // this should be fixed and just SMI header should be passed
751
    av_free(st->codec->extradata);
752
    st->codec->extradata_size = 0x5a + atom.size;
753
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
754

    
755
    if (st->codec->extradata) {
756
        strcpy(st->codec->extradata, "SVQ3"); // fake
757
        get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
758
        dprintf("Reading SMI %"PRId64"  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
759
    } else
760
        url_fskip(pb, atom.size);
761

    
762
    return 0;
763
}
764

    
765
static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
766
{
767
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
768
    int little_endian = get_be16(pb);
769

    
770
    if (little_endian) {
771
        switch (st->codec->codec_id) {
772
        case CODEC_ID_PCM_S24BE:
773
            st->codec->codec_id = CODEC_ID_PCM_S24LE;
774
            break;
775
        case CODEC_ID_PCM_S32BE:
776
            st->codec->codec_id = CODEC_ID_PCM_S32LE;
777
            break;
778
        default:
779
            break;
780
        }
781
    }
782
    return 0;
783
}
784

    
785
static int mov_read_alac(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
786
{
787
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
788

    
789
    // currently ALAC decoder expect full atom header - so let's fake it
790
    // this should be fixed and just ALAC header should be passed
791

    
792
    av_free(st->codec->extradata);
793
    st->codec->extradata_size = 36;
794
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
795

    
796
    if (st->codec->extradata) {
797
        strcpy(st->codec->extradata + 4, "alac"); // fake
798
        get_buffer(pb, st->codec->extradata + 8, 36 - 8);
799
        dprintf("Reading alac %d  %s\n", st->codec->extradata_size, (char*)st->codec->extradata);
800
    } else
801
        url_fskip(pb, atom.size);
802
    return 0;
803
}
804

    
805
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
806
{
807
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
808

    
809
    if((uint64_t)atom.size > (1<<30))
810
        return -1;
811

    
812
    if (st->codec->codec_id == CODEC_ID_QDM2) {
813
        // pass all frma atom to codec, needed at least for QDM2
814
        av_free(st->codec->extradata);
815
        st->codec->extradata_size = atom.size;
816
        st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
817

    
818
        if (st->codec->extradata) {
819
            get_buffer(pb, st->codec->extradata, atom.size);
820
        } else
821
            url_fskip(pb, atom.size);
822
    } else if (atom.size > 8) { /* to read frma, esds atoms */
823
        mov_read_default(c, pb, atom);
824
    } else
825
        url_fskip(pb, atom.size);
826
    return 0;
827
}
828

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

    
833
    if((uint64_t)atom.size > (1<<30))
834
        return -1;
835

    
836
    av_free(st->codec->extradata);
837

    
838
    st->codec->extradata_size = atom.size + 8;
839
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
840

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

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

    
854
    if((uint64_t)atom.size > (1<<30))
855
        return -1;
856

    
857
    av_free(st->codec->extradata);
858

    
859
    st->codec->extradata_size = atom.size;
860
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
861

    
862
    if (st->codec->extradata) {
863
        get_buffer(pb, st->codec->extradata, atom.size);
864
    } else
865
        url_fskip(pb, atom.size);
866

    
867
    return 0;
868
}
869

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

    
876
    get_byte(pb); /* version */
877
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
878

    
879
    entries = get_be32(pb);
880

    
881
    if(entries >= UINT_MAX/sizeof(int64_t))
882
        return -1;
883

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

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

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

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

    
931
    get_byte(pb); /* version */
932
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
933

    
934
    entries = get_be32(pb);
935

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

    
943
        get_be32(pb); /* reserved */
944
        get_be16(pb); /* reserved */
945
        get_be16(pb); /* index */
946

    
947
        st->codec->codec_tag = format;
948
        id = codec_get_id(mov_audio_tags, format);
949
        if (id > 0) {
950
            st->codec->codec_type = CODEC_TYPE_AUDIO;
951
        } else if (format && format != MKTAG('m', 'p', '4', 's')) { /* skip old asf mpeg4 tag */
952
            id = codec_get_id(mov_video_tags, format);
953
            if (id <= 0)
954
                id = codec_get_id(codec_bmp_tags, format);
955
            if (id > 0)
956
                st->codec->codec_type = CODEC_TYPE_VIDEO;
957
        }
958

    
959
        dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
960
                size,
961
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
962
                st->codec->codec_type);
963

    
964
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
965
            st->codec->codec_id = id;
966
            get_be16(pb); /* version */
967
            get_be16(pb); /* revision level */
968
            get_be32(pb); /* vendor */
969
            get_be32(pb); /* temporal quality */
970
            get_be32(pb); /* spacial quality */
971

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

    
975
            get_be32(pb); /* horiz resolution */
976
            get_be32(pb); /* vert resolution */
977
            get_be32(pb); /* data size, always 0 */
978
            frames_per_sample = get_be16(pb); /* frames per samples */
979
#ifdef DEBUG
980
            av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
981
#endif
982
            get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
983
            if (codec_name[0] <= 31) {
984
                memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
985
                st->codec->codec_name[codec_name[0]] = 0;
986
            }
987

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

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

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

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

    
1004
                if (color_greyscale) {
1005

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

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

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

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

    
1038
                } else {
1039

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

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

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

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

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

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

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

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

    
1135
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1136
        st->codec->sample_rate= sc->time_scale;
1137
    }
1138

    
1139
    switch (st->codec->codec_id) {
1140
#ifdef CONFIG_FAAD
1141
    case CODEC_ID_AAC:
1142
#endif
1143
#ifdef CONFIG_VORBIS_DECODER
1144
    case CODEC_ID_VORBIS:
1145
#endif
1146
    case CODEC_ID_MP3ON4:
1147
        st->codec->sample_rate= 0; /* let decoder init parameters properly */
1148
        break;
1149
    default:
1150
        break;
1151
    }
1152

    
1153
    return 0;
1154
}
1155

    
1156
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1157
{
1158
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1159
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1160
    unsigned int i, entries;
1161

    
1162
    get_byte(pb); /* version */
1163
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1164

    
1165
    entries = get_be32(pb);
1166

    
1167
    if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1168
        return -1;
1169

    
1170
#ifdef DEBUG
1171
av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1172
#endif
1173
    sc->sample_to_chunk_sz = entries;
1174
    sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1175
    if (!sc->sample_to_chunk)
1176
        return -1;
1177
    for(i=0; i<entries; i++) {
1178
        sc->sample_to_chunk[i].first = get_be32(pb);
1179
        sc->sample_to_chunk[i].count = get_be32(pb);
1180
        sc->sample_to_chunk[i].id = get_be32(pb);
1181
    }
1182
    return 0;
1183
}
1184

    
1185
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1186
{
1187
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1188
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1189
    unsigned int i, entries;
1190

    
1191
    get_byte(pb); /* version */
1192
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1193

    
1194
    entries = get_be32(pb);
1195

    
1196
    if(entries >= UINT_MAX / sizeof(long))
1197
        return -1;
1198

    
1199
    sc->keyframe_count = entries;
1200
#ifdef DEBUG
1201
    av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1202
#endif
1203
    sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1204
    if (!sc->keyframes)
1205
        return -1;
1206
    for(i=0; i<entries; i++) {
1207
        sc->keyframes[i] = get_be32(pb);
1208
#ifdef DEBUG
1209
/*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1210
#endif
1211
    }
1212
    return 0;
1213
}
1214

    
1215
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1216
{
1217
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1218
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1219
    unsigned int i, entries;
1220

    
1221
    get_byte(pb); /* version */
1222
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1223

    
1224
    sc->sample_size = get_be32(pb);
1225
    entries = get_be32(pb);
1226
    if(entries >= UINT_MAX / sizeof(long))
1227
        return -1;
1228

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

    
1272
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1273
{
1274
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1275
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1276
    unsigned int i, entries;
1277
    int64_t duration=0;
1278
    int64_t total_sample_count=0;
1279

    
1280
    get_byte(pb); /* version */
1281
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1282
    entries = get_be32(pb);
1283
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1284
        return -1;
1285

    
1286
    sc->stts_count = entries;
1287
    sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1288

    
1289
#ifdef DEBUG
1290
av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1291
#endif
1292

    
1293
    sc->time_rate=0;
1294

    
1295
    for(i=0; i<entries; i++) {
1296
        int sample_duration;
1297
        int sample_count;
1298

    
1299
        sample_count=get_be32(pb);
1300
        sample_duration = get_be32(pb);
1301
        sc->stts_data[i].count= sample_count;
1302
        sc->stts_data[i].duration= sample_duration;
1303

    
1304
        sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1305

    
1306
        dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1307

    
1308
        duration+=(int64_t)sample_duration*sample_count;
1309
        total_sample_count+=sample_count;
1310
    }
1311

    
1312
    st->nb_frames= total_sample_count;
1313
    if(duration)
1314
        st->duration= duration;
1315
    return 0;
1316
}
1317

    
1318
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1319
{
1320
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1321
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1322
    unsigned int i, entries;
1323

    
1324
    get_byte(pb); /* version */
1325
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1326
    entries = get_be32(pb);
1327
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1328
        return -1;
1329

    
1330
    sc->ctts_count = entries;
1331
    sc->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1332

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

    
1335
    for(i=0; i<entries; i++) {
1336
        int count    =get_be32(pb);
1337
        int duration =get_be32(pb);
1338

    
1339
        if (duration < 0) {
1340
            av_log(c->fc, AV_LOG_ERROR, "negative ctts, ignoring\n");
1341
            sc->ctts_count = 0;
1342
            url_fskip(pb, 8 * (entries - i - 1));
1343
            break;
1344
        }
1345
        sc->ctts_data[i].count   = count;
1346
        sc->ctts_data[i].duration= duration;
1347

    
1348
        sc->time_rate= ff_gcd(sc->time_rate, duration);
1349
    }
1350
    return 0;
1351
}
1352

    
1353
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1354
{
1355
    AVStream *st;
1356
    MOVStreamContext *sc;
1357

    
1358
    st = av_new_stream(c->fc, c->fc->nb_streams);
1359
    if (!st) return -2;
1360
    sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1361
    if (!sc) {
1362
        av_free(st);
1363
        return -1;
1364
    }
1365

    
1366
    sc->sample_to_chunk_index = -1;
1367
    st->priv_data = sc;
1368
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1369
    st->start_time = 0; /* XXX: check */
1370
    c->streams[c->fc->nb_streams-1] = sc;
1371

    
1372
    return mov_read_default(c, pb, atom);
1373
}
1374

    
1375
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1376
{
1377
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1378
    int version = get_byte(pb);
1379

    
1380
    get_byte(pb); get_byte(pb);
1381
    get_byte(pb); /* flags */
1382
    /*
1383
    MOV_TRACK_ENABLED 0x0001
1384
    MOV_TRACK_IN_MOVIE 0x0002
1385
    MOV_TRACK_IN_PREVIEW 0x0004
1386
    MOV_TRACK_IN_POSTER 0x0008
1387
    */
1388

    
1389
    if (version == 1) {
1390
        get_be64(pb);
1391
        get_be64(pb);
1392
    } else {
1393
        get_be32(pb); /* creation time */
1394
        get_be32(pb); /* modification time */
1395
    }
1396
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1397
    get_be32(pb); /* reserved */
1398
    st->start_time = 0; /* check */
1399
    (version == 1) ? get_be64(pb) : get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1400
    get_be32(pb); /* reserved */
1401
    get_be32(pb); /* reserved */
1402

    
1403
    get_be16(pb); /* layer */
1404
    get_be16(pb); /* alternate group */
1405
    get_be16(pb); /* volume */
1406
    get_be16(pb); /* reserved */
1407

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

    
1410
    /* those are fixed-point */
1411
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1412
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1413

    
1414
    return 0;
1415
}
1416

    
1417
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1418
/* like the files created with Adobe Premiere 5.0, for samples see */
1419
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1420
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1421
{
1422
    int err;
1423

    
1424
    if (atom.size < 8)
1425
        return 0; /* continue */
1426
    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1427
        url_fskip(pb, atom.size - 4);
1428
        return 0;
1429
    }
1430
    atom.type = get_le32(pb);
1431
    atom.offset += 8;
1432
    atom.size -= 8;
1433
    if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1434
        url_fskip(pb, atom.size);
1435
        return 0;
1436
    }
1437
    err = mov_read_mdat(c, pb, atom);
1438
    return err;
1439
}
1440

    
1441

    
1442
#ifdef CONFIG_ZLIB
1443
static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1444
{
1445
    return -1;
1446
}
1447

    
1448
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1449
{
1450
    ByteIOContext ctx;
1451
    uint8_t *cmov_data;
1452
    uint8_t *moov_data; /* uncompressed data */
1453
    long cmov_len, moov_len;
1454
    int ret;
1455

    
1456
    get_be32(pb); /* dcom atom */
1457
    if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1458
        return -1;
1459
    if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1460
        av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
1461
        return -1;
1462
    }
1463
    get_be32(pb); /* cmvd atom */
1464
    if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1465
        return -1;
1466
    moov_len = get_be32(pb); /* uncompressed size */
1467
    cmov_len = atom.size - 6 * 4;
1468

    
1469
    cmov_data = (uint8_t *) av_malloc(cmov_len);
1470
    if (!cmov_data)
1471
        return -1;
1472
    moov_data = (uint8_t *) av_malloc(moov_len);
1473
    if (!moov_data) {
1474
        av_free(cmov_data);
1475
        return -1;
1476
    }
1477
    get_buffer(pb, cmov_data, cmov_len);
1478
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1479
        return -1;
1480
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1481
        return -1;
1482
    ctx.buf_end = ctx.buffer + moov_len;
1483
    atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1484
    atom.offset = 0;
1485
    atom.size = moov_len;
1486
#ifdef DEBUG
1487
//    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1488
#endif
1489
    ret = mov_read_default(c, &ctx, atom);
1490
    av_free(moov_data);
1491
    av_free(cmov_data);
1492

    
1493
    return ret;
1494
}
1495
#endif
1496

    
1497
/* edit list atom */
1498
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1499
{
1500
    int i, edit_count;
1501

    
1502
    get_byte(pb); /* version */
1503
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1504
    edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1505

    
1506
    for(i=0; i<edit_count; i++){
1507
        get_be32(pb); /* Track duration */
1508
        get_be32(pb); /* Media time */
1509
        get_be32(pb); /* Media rate */
1510
    }
1511
    dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1512
    return 0;
1513
}
1514

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

    
1598
static void mov_free_stream_context(MOVStreamContext *sc)
1599
{
1600
    if(sc) {
1601
        av_freep(&sc->chunk_offsets);
1602
        av_freep(&sc->sample_to_chunk);
1603
        av_freep(&sc->sample_sizes);
1604
        av_freep(&sc->keyframes);
1605
        av_freep(&sc->stts_data);
1606
        av_freep(&sc->ctts_data);
1607
        av_freep(&sc);
1608
    }
1609
}
1610

    
1611
static inline uint32_t mov_to_tag(uint8_t *buf)
1612
{
1613
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1614
}
1615

    
1616
static inline uint32_t to_be32(uint8_t *buf)
1617
{
1618
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1619
}
1620

    
1621
/* XXX: is it sufficient ? */
1622
static int mov_probe(AVProbeData *p)
1623
{
1624
    unsigned int offset;
1625
    uint32_t tag;
1626
    int score = 0;
1627

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

    
1666
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1667
{
1668
    MOVContext *mov = (MOVContext *) s->priv_data;
1669
    ByteIOContext *pb = &s->pb;
1670
    int i, j, nb, err;
1671
    MOV_atom_t atom = { 0, 0, 0 };
1672

    
1673
    mov->fc = s;
1674
    mov->parse_table = mov_default_parse_table;
1675

    
1676
    if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1677
        atom.size = url_fsize(pb);
1678
    else
1679
        atom.size = 0x7FFFFFFFFFFFFFFFLL;
1680

    
1681
    /* check MOV header */
1682
    err = mov_read_default(mov, pb, atom);
1683
    if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1684
        av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1685
                err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1686
        return -1;
1687
    }
1688
    dprintf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1689

    
1690
    /* some cleanup : make sure we are on the mdat atom */
1691
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1692
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1693

    
1694
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1695
    mov->total_streams = nb = s->nb_streams;
1696

    
1697
#if 1
1698
    for(i=0; i<s->nb_streams;) {
1699
        if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1700
            av_free(s->streams[i]);
1701
            for(j=i+1; j<s->nb_streams; j++)
1702
                s->streams[j-1] = s->streams[j];
1703
            s->nb_streams--;
1704
        } else
1705
            i++;
1706
    }
1707
    for(i=0; i<s->nb_streams;i++) {
1708
        MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
1709

    
1710
        if(!sc->time_rate)
1711
            sc->time_rate=1;
1712
        if(!sc->time_scale)
1713
            sc->time_scale= mov->time_scale;
1714
        av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1715

    
1716
        if(s->streams[i]->duration != AV_NOPTS_VALUE){
1717
            assert(s->streams[i]->duration % sc->time_rate == 0);
1718
            s->streams[i]->duration /= sc->time_rate;
1719
        }
1720

    
1721
        sc->ffindex = i;
1722
        sc->is_ff_stream = 1;
1723
    }
1724
#endif
1725
    return 0;
1726
}
1727

    
1728
/* Yes, this is ugly... I didn't write the specs of QT :p */
1729
/* XXX:remove useless commented code sometime */
1730
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1731
{
1732
    MOVContext *mov = (MOVContext *) s->priv_data;
1733
    MOVStreamContext *sc;
1734
    AVStream *st;
1735
    int64_t offset = INT64_MAX;
1736
    int64_t best_dts = INT64_MAX;
1737
    int i, a, b, m;
1738
    int next_sample= -99;
1739
    int size;
1740
    int idx;
1741
    size = 0x0FFFFFFF;
1742

    
1743
    if (mov->partial) {
1744
        sc = mov->partial;
1745
        idx = sc->sample_to_chunk_index;
1746

    
1747
        if (idx < 0) return 0;
1748
        dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1749
        //size = sc->sample_sizes[sc->current_sample];
1750
        // that ain't working...
1751
        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1752
        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1753

    
1754
        next_sample= sc->current_sample+1;
1755

    
1756
        sc->left_in_chunk--;
1757

    
1758
        if (sc->left_in_chunk <= 0)
1759
            mov->partial = 0;
1760
        offset = mov->next_chunk_offset;
1761
        /* extract the sample */
1762

    
1763
        goto readchunk;
1764
    }
1765

    
1766
again:
1767
    sc = 0;
1768
    if(offset == INT64_MAX)
1769
        best_dts= INT64_MAX;
1770
    for(i=0; i<mov->total_streams; i++) {
1771
        MOVStreamContext *msc = mov->streams[i];
1772

    
1773
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1774
            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1775
                int64_t dts;
1776
                int index= msc->sample_to_time_index;
1777
                int sample= msc->sample_to_time_sample;
1778
                int time= msc->sample_to_time_time;
1779
                int duration = msc->stts_data[index].duration;
1780
                int count = msc->stts_data[index].count;
1781
                if (sample + count <= msc->current_sample) {
1782
                    sample += count;
1783
                    time   += count*duration;
1784
                    index ++;
1785
                    duration = msc->stts_data[index].duration;
1786
                }
1787
                dts = time + (msc->current_sample - sample) * (int64_t)duration;
1788
                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1789
                dprintf("stream: %d dts: %"PRId64" best_dts: %"PRId64" offset: %"PRId64"\n", i, dts, best_dts, offset);
1790
                if(dts < best_dts){
1791
                    best_dts= dts;
1792
                    sc = msc;
1793
                    offset = msc->chunk_offsets[msc->next_chunk];
1794
                }
1795
            }else{
1796
                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1797
                    sc = msc;
1798
                    offset = msc->chunk_offsets[msc->next_chunk];
1799
                }
1800
            }
1801
        }
1802
    }
1803
    if (!sc || offset==INT64_MAX)
1804
        return -1;
1805

    
1806
    sc->next_chunk++;
1807

    
1808
    if(mov->next_chunk_offset < offset) { /* some meta data */
1809
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1810
        mov->next_chunk_offset = offset;
1811
    }
1812

    
1813
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1814
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1815
        mov->next_chunk_offset = offset;
1816
        offset = INT64_MAX;
1817
        goto again;
1818
    }
1819

    
1820
    /* now get the chunk size... */
1821

    
1822
    for(i=0; i<mov->total_streams; i++) {
1823
        MOVStreamContext *msc = mov->streams[i];
1824
        if ((msc->next_chunk < msc->chunk_count)
1825
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1826
            && msc->chunk_offsets[msc->next_chunk] > offset)
1827
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1828
    }
1829

    
1830
#ifdef MOV_MINOLTA_FIX
1831
    //Make sure that size is according to sample_size (Needed by .mov files
1832
    //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1833
    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1834
    //but I have no such movies
1835
    if (sc->sample_size > 0) {
1836
        int foundsize=0;
1837
        for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1838
            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1839
            {
1840
                foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
1841
            }
1842
            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);
1843
        }
1844
        if( (foundsize>0) && (foundsize<size) )
1845
        {
1846
            size=foundsize;
1847
        }
1848
    }
1849
#endif //MOV_MINOLTA_FIX
1850

    
1851
    idx = sc->sample_to_chunk_index;
1852
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1853
        idx++;
1854
    sc->sample_to_chunk_index = idx;
1855
    /* split chunks into samples */
1856
    if (sc->sample_size == 0 || sc->sample_size > 100) {
1857
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1858
            mov->partial = sc;
1859
            /* we'll have to get those samples before next chunk */
1860
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1861
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1862
        }
1863

    
1864
        next_sample= sc->current_sample+1;
1865
    }else if(idx < sc->sample_to_chunk_sz){
1866
        next_sample= sc->current_sample + sc->sample_to_chunk[idx].count;
1867
    }else
1868
        next_sample= sc->current_sample;
1869

    
1870
readchunk:
1871
    dprintf("chunk: %"PRId64" -> %"PRId64" (%i)\n", offset, offset + size, size);
1872
    if(size == 0x0FFFFFFF)
1873
        size = mov->mdat_size + mov->mdat_offset - offset;
1874
    if(size < 0)
1875
        return -1;
1876
    if(size == 0)
1877
        return -1;
1878
    url_fseek(&s->pb, offset, SEEK_SET);
1879

    
1880
    av_get_packet(&s->pb, pkt, size);
1881
    pkt->stream_index = sc->ffindex;
1882

    
1883
    // If the keyframes table exists, mark any samples that are in the table as key frames.
1884
    // If no table exists, treat very sample as a key frame.
1885
    if (sc->keyframes) {
1886
        a = 0;
1887
        b = sc->keyframe_count - 1;
1888

    
1889
        while (a < b) {
1890
            m = (a + b + 1) >> 1;
1891
            if (sc->keyframes[m] > sc->current_sample) {
1892
                b = m - 1;
1893
            } else {
1894
                a = m;
1895
            }
1896
        }
1897

    
1898
        if (sc->keyframes[a] == sc->current_sample)
1899
            pkt->flags |= PKT_FLAG_KEY;
1900
    }
1901
    else
1902
        pkt->flags |= PKT_FLAG_KEY;
1903

    
1904
    mov->next_chunk_offset = offset + size;
1905

    
1906
    /* find the corresponding dts */
1907
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1908
      unsigned int count;
1909
      uint64_t dts, pts;
1910
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1911
      count = sc->stts_data[sc->sample_to_time_index].count;
1912
      if ((sc->sample_to_time_sample + count) <= sc->current_sample) {
1913
        sc->sample_to_time_sample += count;
1914
        sc->sample_to_time_time   += count*duration;
1915
        sc->sample_to_time_index ++;
1916
        duration = sc->stts_data[sc->sample_to_time_index].duration;
1917
      }
1918
      dts = sc->sample_to_time_time + (sc->current_sample - sc->sample_to_time_sample) * (int64_t)duration;
1919
        /* find the corresponding pts */
1920
        if (sc->sample_to_ctime_index < sc->ctts_count) {
1921
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1922
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1923

    
1924
            if ((sc->sample_to_ctime_sample + count) <= sc->current_sample) {
1925
                sc->sample_to_ctime_sample += count;
1926
                sc->sample_to_ctime_index ++;
1927
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1928
            }
1929
            pts = dts + duration;
1930
        }else
1931
            pts = dts;
1932

    
1933
        st= s->streams[ sc->ffindex ];
1934
        assert(pts % st->time_base.num == 0);
1935
        assert(dts % st->time_base.num == 0);
1936

    
1937
        pkt->pts = pts / st->time_base.num;
1938
        pkt->dts = dts / st->time_base.num;
1939
        dprintf("stream #%d smp #%ld dts = %"PRId64" pts = %"PRId64" (smp:%ld time:%"PRId64" idx:%d ent:%d count:%d dur:%d)\n"
1940
                , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1941
                , sc->sample_to_time_sample
1942
                , sc->sample_to_time_time
1943
                , sc->sample_to_time_index
1944
                , sc->stts_count
1945
                , count
1946
                , duration);
1947
    }
1948

    
1949
    assert(next_sample>=0);
1950
    sc->current_sample= next_sample;
1951

    
1952
    return 0;
1953
}
1954

    
1955
#if defined(MOV_SEEK)
1956
/**
1957
 * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1958
 */
1959
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1960
{
1961
    MOVContext* mov = (MOVContext *) s->priv_data;
1962
    MOVStreamContext* sc;
1963
    int32_t i, a, b, m;
1964
    int64_t start_time;
1965
    int32_t seek_sample, sample;
1966
    int32_t duration;
1967
    int32_t count;
1968
    int32_t chunk;
1969
    int32_t left_in_chunk;
1970
    int64_t chunk_file_offset;
1971
    int64_t sample_file_offset;
1972
    int32_t first_chunk_sample;
1973
    int32_t sample_to_chunk_idx;
1974
    int sample_to_time_index;
1975
    long sample_to_time_sample = 0;
1976
    uint64_t sample_to_time_time = 0;
1977
    int mov_idx;
1978

    
1979
    // Find the corresponding mov stream
1980
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1981
        if (mov->streams[mov_idx]->ffindex == stream_index)
1982
            break;
1983
    if (mov_idx == mov->total_streams) {
1984
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1985
        return -1;
1986
    }
1987
    sc = mov->streams[mov_idx];
1988

    
1989
    sample_time *= s->streams[stream_index]->time_base.num;
1990

    
1991
    // Step 1. Find the edit that contains the requested time (elst)
1992
    if (sc->edit_count && 0) {
1993
        // FIXME should handle edit list
1994
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
1995
        return -1;
1996
    }
1997

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

    
2003
    for (i = 0; i < sc->stts_count; i++) {
2004
        count = sc->stts_data[i].count;
2005
        duration = sc->stts_data[i].duration;
2006
        if ((start_time + count*duration) > sample_time) {
2007
            sample_to_time_time = start_time;
2008
            sample_to_time_index = i;
2009
            sample_to_time_sample = sample;
2010
            sample += (sample_time - start_time) / duration;
2011
            break;
2012
        }
2013
        sample += count;
2014
        start_time += count * duration;
2015
    }
2016
    sample_to_time_time = start_time;
2017
    sample_to_time_index = i;
2018
    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
2019
       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
2020

    
2021
    dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
2022
    if (sample > sc->sample_count) {
2023
        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);
2024
        return -1;
2025
    }
2026

    
2027
    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
2028
    if (sc->keyframes) {
2029
        a = 0;
2030
        b = sc->keyframe_count - 1;
2031
        while (a < b) {
2032
            m = (a + b + 1) >> 1;
2033
            if (sc->keyframes[m] > sample) {
2034
                b = m - 1;
2035
            } else {
2036
                a = m;
2037
            }
2038
        }
2039
        // for low latency prob: always use the previous keyframe, just uncomment the next line
2040
        // if (a) a--;
2041
        seek_sample = sc->keyframes[a];
2042
    }
2043
    else
2044
        seek_sample = sample; // else all samples are key frames
2045
    dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
2046

    
2047
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2048
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2049
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2050
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2051
            break;
2052
        first_chunk_sample += b;
2053
    }
2054
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2055
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2056
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2057
    sample_to_chunk_idx = i;
2058
    dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2059

    
2060
    // Step 5. Find the offset of the chunk using the chunk offset atom
2061
    if (!sc->chunk_offsets) {
2062
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2063
        return -1;
2064
    }
2065
    if (chunk > sc->chunk_count) {
2066
        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);
2067
        return -1;
2068
    }
2069
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
2070
    dprintf("Chunk file offset is #%"PRIu64"\n", chunk_file_offset);
2071

    
2072
    // Step 6. Find the byte offset within the chunk using the sample size atom
2073
    sample_file_offset = chunk_file_offset;
2074
    if (sc->sample_size)
2075
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2076
    else {
2077
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2078
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2079
        }
2080
    }
2081
    dprintf("Sample file offset is #%"PRIu64"\n", sample_file_offset);
2082

    
2083
    // Step 6. Update the parser
2084
    mov->partial = sc;
2085
    mov->next_chunk_offset = sample_file_offset;
2086
    // Update current stream state
2087
    sc->current_sample = seek_sample - 1;  // zero based
2088
    sc->left_in_chunk = left_in_chunk;
2089
    sc->next_chunk = chunk; // +1 -1 (zero based)
2090
    sc->sample_to_chunk_index = sample_to_chunk_idx;
2091

    
2092
    // Update other streams
2093
    for (i = 0; i<mov->total_streams; i++) {
2094
        MOVStreamContext *msc;
2095
        if (i == mov_idx) continue;
2096
        // Find the nearest 'next' chunk
2097
        msc = mov->streams[i];
2098
        a = 0;
2099
        b = msc->chunk_count - 1;
2100
        while (a < b) {
2101
            m = (a + b + 1) >> 1;
2102
            if (msc->chunk_offsets[m] > chunk_file_offset) {
2103
                b = m - 1;
2104
            } else {
2105
                a = m;
2106
            }
2107
        }
2108
        msc->next_chunk = a;
2109
        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2110
            msc->next_chunk ++;
2111
        dprintf("Nearest next chunk for stream #%i is #%li @%"PRId64"\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2112

    
2113
        // Compute sample count and index in the sample_to_chunk table (what a pity)
2114
        msc->sample_to_chunk_index = 0;
2115
        msc->current_sample = 0;
2116
        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2117
            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2118
            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2119
            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2120
        }
2121
        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;
2122
        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2123
        // Find corresponding position in stts (used later to compute dts)
2124
        sample = 0;
2125
        start_time = 0;
2126
        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2127
            count = msc->stts_data[msc->sample_to_time_index].count;
2128
            duration = msc->stts_data[msc->sample_to_time_index].duration;
2129
            if ((sample + count - 1) > msc->current_sample) {
2130
                msc->sample_to_time_time = start_time;
2131
                msc->sample_to_time_sample = sample;
2132
                break;
2133
            }
2134
            sample += count;
2135
            start_time += count * duration;
2136
        }
2137
        sample = 0;
2138
        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2139
            count = msc->ctts_data[msc->sample_to_ctime_index].count;
2140
            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2141
            if ((sample + count - 1) > msc->current_sample) {
2142
                msc->sample_to_ctime_sample = sample;
2143
                break;
2144
            }
2145
            sample += count;
2146
        }
2147
        dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2148
    }
2149
    return 0;
2150
}
2151
#endif
2152

    
2153
static int mov_read_close(AVFormatContext *s)
2154
{
2155
    int i;
2156
    MOVContext *mov = (MOVContext *) s->priv_data;
2157
    for(i=0; i<mov->total_streams; i++)
2158
        mov_free_stream_context(mov->streams[i]);
2159
    /* free color tabs */
2160
    for(i=0; i<mov->ctab_size; i++)
2161
        av_freep(&mov->ctab[i]);
2162
    av_freep(&mov->ctab);
2163
    return 0;
2164
}
2165

    
2166
static AVInputFormat mov_iformat = {
2167
    "mov,mp4,m4a,3gp,3g2,mj2",
2168
    "QuickTime/MPEG4/Motion JPEG 2000 format",
2169
    sizeof(MOVContext),
2170
    mov_probe,
2171
    mov_read_header,
2172
    mov_read_packet,
2173
    mov_read_close,
2174
#if defined(MOV_SEEK)
2175
    mov_read_seek,
2176
#endif
2177
};
2178

    
2179
int mov_init(void)
2180
{
2181
    av_register_input_format(&mov_iformat);
2182
    return 0;
2183
}