add AVID DV fourcc
[ffmpeg.git] / libavformat / mov.c
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_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         dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
948                 size,
949                 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
950                 st->codec->codec_type);
951         st->codec->codec_tag = format;
952         id = codec_get_id(mov_audio_tags, format);
953         if (id > 0) {
954             st->codec->codec_type = CODEC_TYPE_AUDIO;
955         } else if (format != MKTAG('m', 'p', '4', 's')) { /* skip old asf mpeg4 tag */
956             id = codec_get_id(mov_video_tags, format);
957             if (id <= 0)
958                 id = codec_get_id(codec_bmp_tags, format);
959             if (id > 0)
960                 st->codec->codec_type = CODEC_TYPE_VIDEO;
961         }
962
963         if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
964             st->codec->codec_id = id;
965             get_be16(pb); /* version */
966             get_be16(pb); /* revision level */
967             get_be32(pb); /* vendor */
968             get_be32(pb); /* temporal quality */
969             get_be32(pb); /* spacial quality */
970             if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
971                 get_be16(pb);
972                 get_be16(pb);
973             }else{
974                 st->codec->width = get_be16(pb); /* width */
975                 st->codec->height = get_be16(pb); /* height */
976             }
977             get_be32(pb); /* horiz resolution */
978             get_be32(pb); /* vert resolution */
979             get_be32(pb); /* data size, always 0 */
980             frames_per_sample = get_be16(pb); /* frames per samples */
981 #ifdef DEBUG
982             av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
983 #endif
984             get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
985             if (codec_name[0] <= 31) {
986                 memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
987                 st->codec->codec_name[codec_name[0]] = 0;
988             }
989
990             st->codec->bits_per_sample = get_be16(pb); /* depth */
991             st->codec->color_table_id = get_be16(pb); /* colortable id */
992
993 /*          These are set in mov_read_stts and might already be set!
994             st->codec->time_base.den      = 25;
995             st->codec->time_base.num = 1;
996 */
997
998             /* figure out the palette situation */
999             color_depth = st->codec->bits_per_sample & 0x1F;
1000             color_greyscale = st->codec->bits_per_sample & 0x20;
1001
1002             /* if the depth is 2, 4, or 8 bpp, file is palettized */
1003             if ((color_depth == 2) || (color_depth == 4) ||
1004                 (color_depth == 8)) {
1005
1006                 if (color_greyscale) {
1007
1008                     /* compute the greyscale palette */
1009                     color_count = 1 << color_depth;
1010                     color_index = 255;
1011                     color_dec = 256 / (color_count - 1);
1012                     for (j = 0; j < color_count; j++) {
1013                         r = g = b = color_index;
1014                         c->palette_control.palette[j] =
1015                             (r << 16) | (g << 8) | (b);
1016                         color_index -= color_dec;
1017                         if (color_index < 0)
1018                             color_index = 0;
1019                     }
1020
1021                 } else if (st->codec->color_table_id & 0x08) {
1022
1023                     /* if flag bit 3 is set, use the default palette */
1024                     color_count = 1 << color_depth;
1025                     if (color_depth == 2)
1026                         color_table = ff_qt_default_palette_4;
1027                     else if (color_depth == 4)
1028                         color_table = ff_qt_default_palette_16;
1029                     else
1030                         color_table = ff_qt_default_palette_256;
1031
1032                     for (j = 0; j < color_count; j++) {
1033                         r = color_table[j * 4 + 0];
1034                         g = color_table[j * 4 + 1];
1035                         b = color_table[j * 4 + 2];
1036                         c->palette_control.palette[j] =
1037                             (r << 16) | (g << 8) | (b);
1038                     }
1039
1040                 } else {
1041
1042                     /* load the palette from the file */
1043                     color_start = get_be32(pb);
1044                     color_count = get_be16(pb);
1045                     color_end = get_be16(pb);
1046                     for (j = color_start; j <= color_end; j++) {
1047                         /* each R, G, or B component is 16 bits;
1048                          * only use the top 8 bits; skip alpha bytes
1049                          * up front */
1050                         get_byte(pb);
1051                         get_byte(pb);
1052                         r = get_byte(pb);
1053                         get_byte(pb);
1054                         g = get_byte(pb);
1055                         get_byte(pb);
1056                         b = get_byte(pb);
1057                         get_byte(pb);
1058                         c->palette_control.palette[j] =
1059                             (r << 16) | (g << 8) | (b);
1060                     }
1061                 }
1062
1063                 st->codec->palctrl = &c->palette_control;
1064                 st->codec->palctrl->palette_changed = 1;
1065             } else
1066                 st->codec->palctrl = NULL;
1067         } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
1068             uint16_t version = get_be16(pb);
1069
1070             st->codec->codec_id = id;
1071             get_be16(pb); /* revision level */
1072             get_be32(pb); /* vendor */
1073
1074             st->codec->channels = get_be16(pb);             /* channel count */
1075             st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1076             /* do we need to force to 16 for AMR ? */
1077
1078             /* handle specific s8 codec */
1079             get_be16(pb); /* compression id = 0*/
1080             get_be16(pb); /* packet size = 0 */
1081
1082             st->codec->sample_rate = ((get_be32(pb) >> 16));
1083
1084             switch (st->codec->codec_id) {
1085             case CODEC_ID_PCM_S16LE:
1086             case CODEC_ID_PCM_S16BE:
1087                 if (st->codec->bits_per_sample == 8)
1088                     st->codec->codec_id = CODEC_ID_PCM_S8;
1089                 st->codec->bit_rate = st->codec->sample_rate * 8;
1090                 break;
1091             case CODEC_ID_PCM_U8:
1092                 if (st->codec->bits_per_sample == 16)
1093                     st->codec->codec_id = CODEC_ID_PCM_S16BE;
1094                 st->codec->bit_rate = st->codec->sample_rate * 8;
1095                 break;
1096             case CODEC_ID_AMR_WB:
1097                 st->codec->sample_rate = 16000; /* should really we ? */
1098                 st->codec->channels=1; /* really needed */
1099                 break;
1100             case CODEC_ID_AMR_NB:
1101                 st->codec->sample_rate = 8000; /* should really we ? */
1102                 st->codec->channels=1; /* really needed */
1103                 break;
1104             default:
1105                 break;
1106             }
1107
1108             //Read QT version 1 fields. In version 0 theese dont exist
1109             dprintf("version =%d mp4=%d\n",version,c->mp4);
1110             if(version==1) {
1111                 get_be32(pb); /* samples per packet */
1112                 get_be32(pb); /* bytes per packet */
1113                 get_be32(pb); /* bytes per frame */
1114                 get_be32(pb); /* bytes per sample */
1115             } else if(version==2) {
1116                 get_be32(pb); /* sizeof struct only */
1117                 st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */
1118                 st->codec->channels = get_be32(pb);
1119                 get_be32(pb); /* always 0x7F000000 */
1120                 get_be32(pb); /* bits per channel if sound is uncompressed */
1121                 get_be32(pb); /* lcpm format specific flag */
1122                 get_be32(pb); /* bytes per audio packet if constant */
1123                 get_be32(pb); /* lpcm frames per audio packet if constant */
1124             }
1125         } else {
1126             /* other codec type, just skip (rtp, mp4s, tmcd ...) */
1127             url_fskip(pb, size - (url_ftell(pb) - start_pos));
1128         }
1129         /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
1130         a.size = size - (url_ftell(pb) - start_pos);
1131         if (a.size > 8)
1132             mov_read_default(c, pb, a);
1133         else if (a.size > 0)
1134             url_fskip(pb, a.size);
1135     }
1136
1137     if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1138         st->codec->sample_rate= sc->time_scale;
1139     }
1140
1141     switch (st->codec->codec_id) {
1142 #ifdef CONFIG_FAAD
1143     case CODEC_ID_AAC:
1144 #endif
1145 #ifdef CONFIG_VORBIS_DECODER
1146     case CODEC_ID_VORBIS:
1147 #endif
1148     case CODEC_ID_MP3ON4:
1149         st->codec->sample_rate= 0; /* let decoder init parameters properly */
1150         break;
1151     default:
1152         break;
1153     }
1154
1155     return 0;
1156 }
1157
1158 static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1159 {
1160     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1161     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1162     unsigned int i, entries;
1163
1164     get_byte(pb); /* version */
1165     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1166
1167     entries = get_be32(pb);
1168
1169     if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1170         return -1;
1171
1172 #ifdef DEBUG
1173 av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1174 #endif
1175     sc->sample_to_chunk_sz = entries;
1176     sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1177     if (!sc->sample_to_chunk)
1178         return -1;
1179     for(i=0; i<entries; i++) {
1180         sc->sample_to_chunk[i].first = get_be32(pb);
1181         sc->sample_to_chunk[i].count = get_be32(pb);
1182         sc->sample_to_chunk[i].id = get_be32(pb);
1183     }
1184     return 0;
1185 }
1186
1187 static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1188 {
1189     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1190     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1191     unsigned int i, entries;
1192
1193     get_byte(pb); /* version */
1194     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1195
1196     entries = get_be32(pb);
1197
1198     if(entries >= UINT_MAX / sizeof(long))
1199         return -1;
1200
1201     sc->keyframe_count = entries;
1202 #ifdef DEBUG
1203     av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1204 #endif
1205     sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1206     if (!sc->keyframes)
1207         return -1;
1208     for(i=0; i<entries; i++) {
1209         sc->keyframes[i] = get_be32(pb);
1210 #ifdef DEBUG
1211 /*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1212 #endif
1213     }
1214     return 0;
1215 }
1216
1217 static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1218 {
1219     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1220     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1221     unsigned int i, entries;
1222
1223     get_byte(pb); /* version */
1224     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1225
1226     sc->sample_size = get_be32(pb);
1227     entries = get_be32(pb);
1228     if(entries >= UINT_MAX / sizeof(long))
1229         return -1;
1230
1231     sc->sample_count = entries;
1232 #ifdef DEBUG
1233     av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1234 #endif
1235     if(sc->sample_size) {
1236         /* override sample size for uncompressed sound */
1237         switch (st->codec->codec_id) {
1238         case CODEC_ID_PCM_S32BE:
1239         case CODEC_ID_PCM_S32LE:
1240             sc->sample_size = 4 * st->codec->channels;
1241             break;
1242         case CODEC_ID_PCM_S24BE:
1243         case CODEC_ID_PCM_S24LE:
1244             sc->sample_size = 3 * st->codec->channels;
1245             break;
1246         case CODEC_ID_PCM_S16BE:
1247         case CODEC_ID_PCM_S16LE:
1248             sc->sample_size = 2 * st->codec->channels;
1249             break;
1250         case CODEC_ID_PCM_MULAW:
1251         case CODEC_ID_PCM_ALAW:
1252         case CODEC_ID_PCM_S8:
1253         case CODEC_ID_PCM_U8:
1254             sc->sample_size = 1 * st->codec->channels;
1255             break;
1256         default:
1257             break;
1258         }
1259         assert(sc->sample_size);
1260         return 0; /* there isn't any table following */
1261     }
1262     sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1263     if (!sc->sample_sizes)
1264         return -1;
1265     for(i=0; i<entries; i++) {
1266         sc->sample_sizes[i] = get_be32(pb);
1267 #ifdef DEBUG
1268         av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1269 #endif
1270     }
1271     return 0;
1272 }
1273
1274 static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1275 {
1276     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1277     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1278     unsigned int i, entries;
1279     int64_t duration=0;
1280     int64_t total_sample_count=0;
1281
1282     get_byte(pb); /* version */
1283     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1284     entries = get_be32(pb);
1285     if(entries >= UINT_MAX / sizeof(Time2Sample))
1286         return -1;
1287
1288     sc->stts_count = entries;
1289     sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1290
1291 #ifdef DEBUG
1292 av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1293 #endif
1294
1295     sc->time_rate=0;
1296
1297     for(i=0; i<entries; i++) {
1298         int sample_duration;
1299         int sample_count;
1300
1301         sample_count=get_be32(pb);
1302         sample_duration = get_be32(pb);
1303         sc->stts_data[i].count= sample_count;
1304         sc->stts_data[i].duration= sample_duration;
1305
1306         sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1307
1308         dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1309
1310         duration+=(int64_t)sample_duration*sample_count;
1311         total_sample_count+=sample_count;
1312     }
1313
1314     st->nb_frames= total_sample_count;
1315     if(duration)
1316         st->duration= duration;
1317     return 0;
1318 }
1319
1320 static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1321 {
1322     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1323     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1324     unsigned int i, entries;
1325
1326     get_byte(pb); /* version */
1327     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1328     entries = get_be32(pb);
1329     if(entries >= UINT_MAX / sizeof(Time2Sample))
1330         return -1;
1331
1332     sc->ctts_count = entries;
1333     sc->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1334
1335     dprintf("track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
1336
1337     for(i=0; i<entries; i++) {
1338         int count    =get_be32(pb);
1339         int duration =get_be32(pb);
1340
1341         if (duration < 0) {
1342             av_log(c->fc, AV_LOG_ERROR, "negative ctts, ignoring\n");
1343             sc->ctts_count = 0;
1344             url_fskip(pb, 8 * (entries - i - 1));
1345             break;
1346         }
1347         sc->ctts_data[i].count   = count;
1348         sc->ctts_data[i].duration= duration;
1349
1350         sc->time_rate= ff_gcd(sc->time_rate, duration);
1351     }
1352     return 0;
1353 }
1354
1355 static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1356 {
1357     AVStream *st;
1358     MOVStreamContext *sc;
1359
1360     st = av_new_stream(c->fc, c->fc->nb_streams);
1361     if (!st) return -2;
1362     sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1363     if (!sc) {
1364         av_free(st);
1365         return -1;
1366     }
1367
1368     sc->sample_to_chunk_index = -1;
1369     st->priv_data = sc;
1370     st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1371     st->start_time = 0; /* XXX: check */
1372     c->streams[c->fc->nb_streams-1] = sc;
1373
1374     return mov_read_default(c, pb, atom);
1375 }
1376
1377 static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1378 {
1379     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1380     int version = get_byte(pb);
1381
1382     get_byte(pb); get_byte(pb);
1383     get_byte(pb); /* flags */
1384     /*
1385     MOV_TRACK_ENABLED 0x0001
1386     MOV_TRACK_IN_MOVIE 0x0002
1387     MOV_TRACK_IN_PREVIEW 0x0004
1388     MOV_TRACK_IN_POSTER 0x0008
1389     */
1390
1391     if (version == 1) {
1392         get_be64(pb);
1393         get_be64(pb);
1394     } else {
1395         get_be32(pb); /* creation time */
1396         get_be32(pb); /* modification time */
1397     }
1398     st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1399     get_be32(pb); /* reserved */
1400     st->start_time = 0; /* check */
1401     (version == 1) ? get_be64(pb) : get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1402     get_be32(pb); /* reserved */
1403     get_be32(pb); /* reserved */
1404
1405     get_be16(pb); /* layer */
1406     get_be16(pb); /* alternate group */
1407     get_be16(pb); /* volume */
1408     get_be16(pb); /* reserved */
1409
1410     url_fskip(pb, 36); /* display matrix */
1411
1412     /* those are fixed-point */
1413     /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1414     /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1415
1416     return 0;
1417 }
1418
1419 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1420 /* like the files created with Adobe Premiere 5.0, for samples see */
1421 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1422 static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1423 {
1424     int err;
1425
1426     if (atom.size < 8)
1427         return 0; /* continue */
1428     if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1429         url_fskip(pb, atom.size - 4);
1430         return 0;
1431     }
1432     atom.type = get_le32(pb);
1433     atom.offset += 8;
1434     atom.size -= 8;
1435     if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1436         url_fskip(pb, atom.size);
1437         return 0;
1438     }
1439     err = mov_read_mdat(c, pb, atom);
1440     return err;
1441 }
1442
1443
1444 #ifdef CONFIG_ZLIB
1445 static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1446 {
1447     return -1;
1448 }
1449
1450 static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1451 {
1452     ByteIOContext ctx;
1453     uint8_t *cmov_data;
1454     uint8_t *moov_data; /* uncompressed data */
1455     long cmov_len, moov_len;
1456     int ret;
1457
1458     get_be32(pb); /* dcom atom */
1459     if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1460         return -1;
1461     if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1462         av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
1463         return -1;
1464     }
1465     get_be32(pb); /* cmvd atom */
1466     if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1467         return -1;
1468     moov_len = get_be32(pb); /* uncompressed size */
1469     cmov_len = atom.size - 6 * 4;
1470
1471     cmov_data = (uint8_t *) av_malloc(cmov_len);
1472     if (!cmov_data)
1473         return -1;
1474     moov_data = (uint8_t *) av_malloc(moov_len);
1475     if (!moov_data) {
1476         av_free(cmov_data);
1477         return -1;
1478     }
1479     get_buffer(pb, cmov_data, cmov_len);
1480     if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1481         return -1;
1482     if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1483         return -1;
1484     ctx.buf_end = ctx.buffer + moov_len;
1485     atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1486     atom.offset = 0;
1487     atom.size = moov_len;
1488 #ifdef DEBUG
1489 //    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1490 #endif
1491     ret = mov_read_default(c, &ctx, atom);
1492     av_free(moov_data);
1493     av_free(cmov_data);
1494
1495     return ret;
1496 }
1497 #endif
1498
1499 /* edit list atom */
1500 static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1501 {
1502     int i, edit_count;
1503
1504     get_byte(pb); /* version */
1505     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1506     edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1507
1508     for(i=0; i<edit_count; i++){
1509         get_be32(pb); /* Track duration */
1510         get_be32(pb); /* Media time */
1511         get_be32(pb); /* Media rate */
1512     }
1513     dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1514     return 0;
1515 }
1516
1517 static const MOVParseTableEntry mov_default_parse_table[] = {
1518 /* mp4 atoms */
1519 { MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1520 { MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1521 { MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1522 { MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1523 { MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1524 { MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1525 { MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1526 { MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1527 { MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1528 { MKTAG( 'e', 'n', 'd', 'a' ), mov_read_enda },
1529 { MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1530 { MKTAG( 'f', 't', 'y', 'p' ), mov_read_ftyp },
1531 { MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1532 { MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1533 { MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1534 { MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
1535 { MKTAG( 'j', 'p', '2', 'h' ), mov_read_jp2h },
1536 { MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1537 { MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1538 { MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1539 { MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1540 { MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
1541 { MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },
1542 { MKTAG( 'm', 'p', '4', 's' ), mov_read_default },
1543 { MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },
1544 { MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },
1545 { MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
1546 { MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },
1547 { MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },
1548 { MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },
1549 { MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },
1550 { MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */
1551 { MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
1552 { MKTAG( 'a', 'l', 'a', 'c' ), mov_read_alac }, /* alac specific atom */
1553 { MKTAG( 'a', 'v', 'c', 'C' ), mov_read_avcC },
1554 { MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1555 { MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1556 { MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1557 { MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1558 { MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1559 { MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1560 { MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1561 { MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1562 { MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1563 { MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1564 { MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1565 { MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1566 { MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1567 { MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1568 { MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1569 { MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1570 { MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1571 { MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1572 /* extra mp4 */
1573 { MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1574 /* QT atoms */
1575 { MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1576 { MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1577 { MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1578 { MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1579 { MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1580 { MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1581 { MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1582 { MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1583 { MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1584 { MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1585 { MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1586 { MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1587 { MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1588 { MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1589 { MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1590 { MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1591 //{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1592 #ifdef CONFIG_ZLIB
1593 { MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1594 #else
1595 { MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1596 #endif
1597 { 0L, mov_read_leaf }
1598 };
1599
1600 static void mov_free_stream_context(MOVStreamContext *sc)
1601 {
1602     if(sc) {
1603         av_freep(&sc->chunk_offsets);
1604         av_freep(&sc->sample_to_chunk);
1605         av_freep(&sc->sample_sizes);
1606         av_freep(&sc->keyframes);
1607         av_freep(&sc->stts_data);
1608         av_freep(&sc->ctts_data);
1609         av_freep(&sc);
1610     }
1611 }
1612
1613 static inline uint32_t mov_to_tag(uint8_t *buf)
1614 {
1615     return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1616 }
1617
1618 static inline uint32_t to_be32(uint8_t *buf)
1619 {
1620     return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1621 }
1622
1623 /* XXX: is it sufficient ? */
1624 static int mov_probe(AVProbeData *p)
1625 {
1626     unsigned int offset;
1627     uint32_t tag;
1628     int score = 0;
1629
1630     /* check file header */
1631     if (p->buf_size <= 12)
1632         return 0;
1633     offset = 0;
1634     for(;;) {
1635         /* ignore invalid offset */
1636         if ((offset + 8) > (unsigned int)p->buf_size)
1637             return score;
1638         tag = mov_to_tag(p->buf + offset + 4);
1639         switch(tag) {
1640         /* check for obvious tags */
1641         case MKTAG( 'j', 'P', ' ', ' ' ): /* jpeg 2000 signature */
1642         case MKTAG( 'm', 'o', 'o', 'v' ):
1643         case MKTAG( 'm', 'd', 'a', 't' ):
1644         case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1645         case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1646             return AVPROBE_SCORE_MAX;
1647         /* those are more common words, so rate then a bit less */
1648         case MKTAG( 'w', 'i', 'd', 'e' ):
1649         case MKTAG( 'f', 'r', 'e', 'e' ):
1650         case MKTAG( 'j', 'u', 'n', 'k' ):
1651         case MKTAG( 'p', 'i', 'c', 't' ):
1652             return AVPROBE_SCORE_MAX - 5;
1653         case MKTAG( 'f', 't', 'y', 'p' ):
1654         case MKTAG( 's', 'k', 'i', 'p' ):
1655         case MKTAG( 'u', 'u', 'i', 'd' ):
1656             offset = to_be32(p->buf+offset) + offset;
1657             /* if we only find those cause probedata is too small at least rate them */
1658             score = AVPROBE_SCORE_MAX - 50;
1659             break;
1660         default:
1661             /* unrecognized tag */
1662             return score;
1663         }
1664     }
1665     return score;
1666 }
1667
1668 static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1669 {
1670     MOVContext *mov = (MOVContext *) s->priv_data;
1671     ByteIOContext *pb = &s->pb;
1672     int i, j, nb, err;
1673     MOV_atom_t atom = { 0, 0, 0 };
1674
1675     mov->fc = s;
1676     mov->parse_table = mov_default_parse_table;
1677
1678     if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1679         atom.size = url_fsize(pb);
1680     else
1681         atom.size = 0x7FFFFFFFFFFFFFFFLL;
1682
1683     /* check MOV header */
1684     err = mov_read_default(mov, pb, atom);
1685     if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1686         av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1687                 err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1688         return -1;
1689     }
1690     dprintf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1691
1692     /* some cleanup : make sure we are on the mdat atom */
1693     if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1694         url_fseek(pb, mov->mdat_offset, SEEK_SET);
1695
1696     mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1697     mov->total_streams = nb = s->nb_streams;
1698
1699 #if 1
1700     for(i=0; i<s->nb_streams;) {
1701         if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1702             av_free(s->streams[i]);
1703             for(j=i+1; j<s->nb_streams; j++)
1704                 s->streams[j-1] = s->streams[j];
1705             s->nb_streams--;
1706         } else
1707             i++;
1708     }
1709     for(i=0; i<s->nb_streams;i++) {
1710         MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
1711
1712         if(!sc->time_rate)
1713             sc->time_rate=1;
1714         if(!sc->time_scale)
1715             sc->time_scale= mov->time_scale;
1716         av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1717
1718         if(s->streams[i]->duration != AV_NOPTS_VALUE){
1719             assert(s->streams[i]->duration % sc->time_rate == 0);
1720             s->streams[i]->duration /= sc->time_rate;
1721         }
1722
1723         sc->ffindex = i;
1724         sc->is_ff_stream = 1;
1725     }
1726 #endif
1727     return 0;
1728 }
1729
1730 /* Yes, this is ugly... I didn't write the specs of QT :p */
1731 /* XXX:remove useless commented code sometime */
1732 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1733 {
1734     MOVContext *mov = (MOVContext *) s->priv_data;
1735     MOVStreamContext *sc;
1736     AVStream *st;
1737     int64_t offset = INT64_MAX;
1738     int64_t best_dts = INT64_MAX;
1739     int i, a, b, m;
1740     int next_sample= -99;
1741     int size;
1742     int idx;
1743     size = 0x0FFFFFFF;
1744
1745     if (mov->partial) {
1746         sc = mov->partial;
1747         idx = sc->sample_to_chunk_index;
1748
1749         if (idx < 0) return 0;
1750         dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1751         //size = sc->sample_sizes[sc->current_sample];
1752         // that ain't working...
1753         //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1754         size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1755
1756         next_sample= sc->current_sample+1;
1757
1758         sc->left_in_chunk--;
1759
1760         if (sc->left_in_chunk <= 0)
1761             mov->partial = 0;
1762         offset = mov->next_chunk_offset;
1763         /* extract the sample */
1764
1765         goto readchunk;
1766     }
1767
1768 again:
1769     sc = 0;
1770     if(offset == INT64_MAX)
1771         best_dts= INT64_MAX;
1772     for(i=0; i<mov->total_streams; i++) {
1773         MOVStreamContext *msc = mov->streams[i];
1774
1775         if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1776             if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1777                 int64_t dts;
1778                 int index= msc->sample_to_time_index;
1779                 int sample= msc->sample_to_time_sample;
1780                 int time= msc->sample_to_time_time;
1781                 int duration = msc->stts_data[index].duration;
1782                 int count = msc->stts_data[index].count;
1783                 if (sample + count <= msc->current_sample) {
1784                     sample += count;
1785                     time   += count*duration;
1786                     index ++;
1787                     duration = msc->stts_data[index].duration;
1788                 }
1789                 dts = time + (msc->current_sample - sample) * (int64_t)duration;
1790                 dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1791                 dprintf("stream: %d dts: %"PRId64" best_dts: %"PRId64" offset: %"PRId64"\n", i, dts, best_dts, offset);
1792                 if(dts < best_dts){
1793                     best_dts= dts;
1794                     sc = msc;
1795                     offset = msc->chunk_offsets[msc->next_chunk];
1796                 }
1797             }else{
1798                 if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1799                     sc = msc;
1800                     offset = msc->chunk_offsets[msc->next_chunk];
1801                 }
1802             }
1803         }
1804     }
1805     if (!sc || offset==INT64_MAX)
1806         return -1;
1807
1808     sc->next_chunk++;
1809
1810     if(mov->next_chunk_offset < offset) { /* some meta data */
1811         url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1812         mov->next_chunk_offset = offset;
1813     }
1814
1815     if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1816         url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1817         mov->next_chunk_offset = offset;
1818         offset = INT64_MAX;
1819         goto again;
1820     }
1821
1822     /* now get the chunk size... */
1823
1824     for(i=0; i<mov->total_streams; i++) {
1825         MOVStreamContext *msc = mov->streams[i];
1826         if ((msc->next_chunk < msc->chunk_count)
1827             && msc->chunk_offsets[msc->next_chunk] - offset < size
1828             && msc->chunk_offsets[msc->next_chunk] > offset)
1829             size = msc->chunk_offsets[msc->next_chunk] - offset;
1830     }
1831
1832 #ifdef MOV_MINOLTA_FIX
1833     //Make sure that size is according to sample_size (Needed by .mov files
1834     //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1835     //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1836     //but I have no such movies
1837     if (sc->sample_size > 0) {
1838         int foundsize=0;
1839         for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1840             if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1841             {
1842                 foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
1843             }
1844             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);
1845         }
1846         if( (foundsize>0) && (foundsize<size) )
1847         {
1848             size=foundsize;
1849         }
1850     }
1851 #endif //MOV_MINOLTA_FIX
1852
1853     idx = sc->sample_to_chunk_index;
1854     if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1855         idx++;
1856     sc->sample_to_chunk_index = idx;
1857     /* split chunks into samples */
1858     if (sc->sample_size == 0 || sc->sample_size > 100) {
1859         if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1860             mov->partial = sc;
1861             /* we'll have to get those samples before next chunk */
1862             sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1863             size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1864         }
1865
1866         next_sample= sc->current_sample+1;
1867     }else if(idx < sc->sample_to_chunk_sz){
1868         next_sample= sc->current_sample + sc->sample_to_chunk[idx].count;
1869     }else
1870         next_sample= sc->current_sample;
1871
1872 readchunk:
1873     dprintf("chunk: %"PRId64" -> %"PRId64" (%i)\n", offset, offset + size, size);
1874     if(size == 0x0FFFFFFF)
1875         size = mov->mdat_size + mov->mdat_offset - offset;
1876     if(size < 0)
1877         return -1;
1878     if(size == 0)
1879         return -1;
1880     url_fseek(&s->pb, offset, SEEK_SET);
1881
1882     av_get_packet(&s->pb, pkt, size);
1883     pkt->stream_index = sc->ffindex;
1884
1885     // If the keyframes table exists, mark any samples that are in the table as key frames.
1886     // If no table exists, treat very sample as a key frame.
1887     if (sc->keyframes) {
1888         a = 0;
1889         b = sc->keyframe_count - 1;
1890
1891         while (a < b) {
1892             m = (a + b + 1) >> 1;
1893             if (sc->keyframes[m] > sc->current_sample) {
1894                 b = m - 1;
1895             } else {
1896                 a = m;
1897             }
1898         }
1899
1900         if (sc->keyframes[a] == sc->current_sample)
1901             pkt->flags |= PKT_FLAG_KEY;
1902     }
1903     else
1904         pkt->flags |= PKT_FLAG_KEY;
1905
1906     mov->next_chunk_offset = offset + size;
1907
1908     /* find the corresponding dts */
1909     if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1910       unsigned int count;
1911       uint64_t dts, pts;
1912       unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1913       count = sc->stts_data[sc->sample_to_time_index].count;
1914       if ((sc->sample_to_time_sample + count) <= sc->current_sample) {
1915         sc->sample_to_time_sample += count;
1916         sc->sample_to_time_time   += count*duration;
1917         sc->sample_to_time_index ++;
1918         duration = sc->stts_data[sc->sample_to_time_index].duration;
1919       }
1920       dts = sc->sample_to_time_time + (sc->current_sample - sc->sample_to_time_sample) * (int64_t)duration;
1921         /* find the corresponding pts */
1922         if (sc->sample_to_ctime_index < sc->ctts_count) {
1923             int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1924             int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1925
1926             if ((sc->sample_to_ctime_sample + count) <= sc->current_sample) {
1927                 sc->sample_to_ctime_sample += count;
1928                 sc->sample_to_ctime_index ++;
1929                 duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1930             }
1931             pts = dts + duration;
1932         }else
1933             pts = dts;
1934
1935         st= s->streams[ sc->ffindex ];
1936         assert(pts % st->time_base.num == 0);
1937         assert(dts % st->time_base.num == 0);
1938
1939         pkt->pts = pts / st->time_base.num;
1940         pkt->dts = dts / st->time_base.num;
1941         dprintf("stream #%d smp #%ld dts = %"PRId64" pts = %"PRId64" (smp:%ld time:%"PRId64" idx:%d ent:%d count:%d dur:%d)\n"
1942                 , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1943                 , sc->sample_to_time_sample
1944                 , sc->sample_to_time_time
1945                 , sc->sample_to_time_index
1946                 , sc->stts_count
1947                 , count
1948                 , duration);
1949     }
1950
1951     assert(next_sample>=0);
1952     sc->current_sample= next_sample;
1953
1954     return 0;
1955 }
1956
1957 #if defined(MOV_SEEK)
1958 /**
1959  * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1960  */
1961 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1962 {
1963     MOVContext* mov = (MOVContext *) s->priv_data;
1964     MOVStreamContext* sc;
1965     int32_t i, a, b, m;
1966     int64_t start_time;
1967     int32_t seek_sample, sample;
1968     int32_t duration;
1969     int32_t count;
1970     int32_t chunk;
1971     int32_t left_in_chunk;
1972     int64_t chunk_file_offset;
1973     int64_t sample_file_offset;
1974     int32_t first_chunk_sample;
1975     int32_t sample_to_chunk_idx;
1976     int sample_to_time_index;
1977     long sample_to_time_sample = 0;
1978     uint64_t sample_to_time_time = 0;
1979     int mov_idx;
1980
1981     // Find the corresponding mov stream
1982     for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1983         if (mov->streams[mov_idx]->ffindex == stream_index)
1984             break;
1985     if (mov_idx == mov->total_streams) {
1986         av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1987         return -1;
1988     }
1989     sc = mov->streams[mov_idx];
1990
1991     sample_time *= s->streams[stream_index]->time_base.num;
1992
1993     // Step 1. Find the edit that contains the requested time (elst)
1994     if (sc->edit_count && 0) {
1995         // FIXME should handle edit list
1996         av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
1997         return -1;
1998     }
1999
2000     // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */
2001     dprintf("Searching for time %li in stream #%i (time_scale=%i)\n", (long)sample_time, mov_idx, sc->time_scale);
2002     start_time = 0; // FIXME use elst atom
2003     sample = 1; // sample are 0 based in table
2004
2005     for (i = 0; i < sc->stts_count; i++) {
2006         count = sc->stts_data[i].count;
2007         duration = sc->stts_data[i].duration;
2008         if ((start_time + count*duration) > sample_time) {
2009             sample_to_time_time = start_time;
2010             sample_to_time_index = i;
2011             sample_to_time_sample = sample;
2012             sample += (sample_time - start_time) / duration;
2013             break;
2014         }
2015         sample += count;
2016         start_time += count * duration;
2017     }
2018     sample_to_time_time = start_time;
2019     sample_to_time_index = i;
2020     /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
2021        is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
2022
2023     dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
2024     if (sample > sc->sample_count) {
2025         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);
2026         return -1;
2027     }
2028
2029     // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
2030     if (sc->keyframes) {
2031         a = 0;
2032         b = sc->keyframe_count - 1;
2033         while (a < b) {
2034             m = (a + b + 1) >> 1;
2035             if (sc->keyframes[m] > sample) {
2036                 b = m - 1;
2037             } else {
2038                 a = m;
2039             }
2040         }
2041         // for low latency prob: always use the previous keyframe, just uncomment the next line
2042         // if (a) a--;
2043         seek_sample = sc->keyframes[a];
2044     }
2045     else
2046         seek_sample = sample; // else all samples are key frames
2047     dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
2048
2049     // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2050     for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2051         b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2052         if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2053             break;
2054         first_chunk_sample += b;
2055     }
2056     chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2057     left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2058     first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2059     sample_to_chunk_idx = i;
2060     dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2061
2062     // Step 5. Find the offset of the chunk using the chunk offset atom
2063     if (!sc->chunk_offsets) {
2064         av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2065         return -1;
2066     }
2067     if (chunk > sc->chunk_count) {
2068         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);
2069         return -1;
2070     }
2071     chunk_file_offset = sc->chunk_offsets[chunk - 1];
2072     dprintf("Chunk file offset is #%"PRIu64"\n", chunk_file_offset);
2073
2074     // Step 6. Find the byte offset within the chunk using the sample size atom
2075     sample_file_offset = chunk_file_offset;
2076     if (sc->sample_size)
2077         sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2078     else {
2079         for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2080         sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2081         }
2082     }
2083     dprintf("Sample file offset is #%"PRIu64"\n", sample_file_offset);
2084
2085     // Step 6. Update the parser
2086     mov->partial = sc;
2087     mov->next_chunk_offset = sample_file_offset;
2088     // Update current stream state
2089     sc->current_sample = seek_sample - 1;  // zero based
2090     sc->left_in_chunk = left_in_chunk;
2091     sc->next_chunk = chunk; // +1 -1 (zero based)
2092     sc->sample_to_chunk_index = sample_to_chunk_idx;
2093
2094     // Update other streams
2095     for (i = 0; i<mov->total_streams; i++) {
2096         MOVStreamContext *msc;
2097         if (i == mov_idx) continue;
2098         // Find the nearest 'next' chunk
2099         msc = mov->streams[i];
2100         a = 0;
2101         b = msc->chunk_count - 1;
2102         while (a < b) {
2103             m = (a + b + 1) >> 1;
2104             if (msc->chunk_offsets[m] > chunk_file_offset) {
2105                 b = m - 1;
2106             } else {
2107                 a = m;
2108             }
2109         }
2110         msc->next_chunk = a;
2111         if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2112             msc->next_chunk ++;
2113         dprintf("Nearest next chunk for stream #%i is #%li @%"PRId64"\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2114
2115         // Compute sample count and index in the sample_to_chunk table (what a pity)
2116         msc->sample_to_chunk_index = 0;
2117         msc->current_sample = 0;
2118         for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2119             && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2120             msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2121             * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2122         }
2123         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;
2124         msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2125         // Find corresponding position in stts (used later to compute dts)
2126         sample = 0;
2127         start_time = 0;
2128         for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2129             count = msc->stts_data[msc->sample_to_time_index].count;
2130             duration = msc->stts_data[msc->sample_to_time_index].duration;
2131             if ((sample + count - 1) > msc->current_sample) {
2132                 msc->sample_to_time_time = start_time;
2133                 msc->sample_to_time_sample = sample;
2134                 break;
2135             }
2136             sample += count;
2137             start_time += count * duration;
2138         }
2139         sample = 0;
2140         for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2141             count = msc->ctts_data[msc->sample_to_ctime_index].count;
2142             duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2143             if ((sample + count - 1) > msc->current_sample) {
2144                 msc->sample_to_ctime_sample = sample;
2145                 break;
2146             }
2147             sample += count;
2148         }
2149         dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2150     }
2151     return 0;
2152 }
2153 #endif
2154
2155 static int mov_read_close(AVFormatContext *s)
2156 {
2157     int i;
2158     MOVContext *mov = (MOVContext *) s->priv_data;
2159     for(i=0; i<mov->total_streams; i++)
2160         mov_free_stream_context(mov->streams[i]);
2161     /* free color tabs */
2162     for(i=0; i<mov->ctab_size; i++)
2163         av_freep(&mov->ctab[i]);
2164     av_freep(&mov->ctab);
2165     return 0;
2166 }
2167
2168 static AVInputFormat mov_iformat = {
2169     "mov,mp4,m4a,3gp,3g2,mj2",
2170     "QuickTime/MPEG4/Motion JPEG 2000 format",
2171     sizeof(MOVContext),
2172     mov_probe,
2173     mov_read_header,
2174     mov_read_packet,
2175     mov_read_close,
2176 #if defined(MOV_SEEK)
2177     mov_read_seek,
2178 #endif
2179 };
2180
2181 int mov_init(void)
2182 {
2183     av_register_input_format(&mov_iformat);
2184     return 0;
2185 }