]> git.sesse.net Git - ffmpeg/blob - libavformat/mov.c
Quicktime creates S8 that way too
[ffmpeg] / 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_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */
158     { CODEC_ID_NONE, 0 },
159 };
160
161 static const CodecTag mov_audio_tags[] = {
162     { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') },
163     { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
164 /*    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */
165     { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
166     /* { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') },*/ /* 8 bits */
167     { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
168     { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /*  */
169     { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /*  */
170     { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /*  */
171     { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */
172     { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */
173     { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */
174
175     { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */
176     { CODEC_ID_MP2, 0x6D730055 }, /* MPEG layer 3 */
177     { CODEC_ID_MP2, 0x5500736D }, /* MPEG layer 3 *//* XXX: check endianness */
178 /*    { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
179 /* MP4 tags */
180     { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, /* MPEG-4 AAC */
181     /* The standard for mpeg4 audio is still not normalised AFAIK anyway */
182     { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */
183     { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */
184     { CODEC_ID_AC3, MKTAG('m', 's', 0x20, 0x00) }, /* Dolby AC-3 */
185     { CODEC_ID_ALAC,MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */
186     { CODEC_ID_QDM2,MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */
187     { CODEC_ID_NONE, 0 },
188 };
189
190 /* map numeric codes from mdhd atom to ISO 639 */
191 /* cf. QTFileFormat.pdf p253, qtff.pdf p205 */
192 /* http://developer.apple.com/documentation/mac/Text/Text-368.html */
193 /* deprecated by putting the code as 3*5bit ascii */
194 static const char *mov_mdhd_language_map[] = {
195 /* 0-9 */
196 "eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
197 "heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/,
198 "urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav",  NULL,
199 "fo ",  NULL, "rus", "chi",  NULL, "iri", "alb", "ron", "ces", "slk",
200 "slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
201 /*?*/
202 "aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon",  NULL, "pus",
203 "kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
204 "pa ", "ori", "mal", "kan", "tam", "tel",  NULL, "bur", "khm", "lao",
205 /*                   roman? arabic? */
206 "vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
207 /*==rundi?*/
208  NULL, "run",  NULL, "mlg", "epo",  NULL,  NULL,  NULL,  NULL,  NULL,
209 /* 100 */
210  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
211  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
212  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, "wel", "baq",
213 "cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
214 };
215
216 /* the QuickTime file format is quite convoluted...
217  * it has lots of index tables, each indexing something in another one...
218  * Here we just use what is needed to read the chunks
219  */
220
221 typedef struct MOV_sample_to_chunk_tbl {
222     long first;
223     long count;
224     long id;
225 } MOV_sample_to_chunk_tbl;
226
227 typedef struct {
228     uint32_t type;
229     int64_t offset;
230     int64_t size; /* total size (excluding the size and type fields) */
231 } MOV_atom_t;
232
233 typedef struct {
234     int seed;
235     int flags;
236     int size;
237     void* clrs;
238 } MOV_ctab_t;
239
240 typedef struct {
241     uint8_t  version;
242     uint32_t flags; // 24bit
243
244     /* 0x03 ESDescrTag */
245     uint16_t es_id;
246 #define MP4ODescrTag                    0x01
247 #define MP4IODescrTag                   0x02
248 #define MP4ESDescrTag                   0x03
249 #define MP4DecConfigDescrTag            0x04
250 #define MP4DecSpecificDescrTag          0x05
251 #define MP4SLConfigDescrTag             0x06
252 #define MP4ContentIdDescrTag            0x07
253 #define MP4SupplContentIdDescrTag       0x08
254 #define MP4IPIPtrDescrTag               0x09
255 #define MP4IPMPPtrDescrTag              0x0A
256 #define MP4IPMPDescrTag                 0x0B
257 #define MP4RegistrationDescrTag         0x0D
258 #define MP4ESIDIncDescrTag              0x0E
259 #define MP4ESIDRefDescrTag              0x0F
260 #define MP4FileIODescrTag               0x10
261 #define MP4FileODescrTag                0x11
262 #define MP4ExtProfileLevelDescrTag      0x13
263 #define MP4ExtDescrTagsStart            0x80
264 #define MP4ExtDescrTagsEnd              0xFE
265     uint8_t  stream_priority;
266
267     /* 0x04 DecConfigDescrTag */
268     uint8_t  object_type_id;
269     uint8_t  stream_type;
270     /* XXX: really streamType is
271      * only 6bit, followed by:
272      * 1bit  upStream
273      * 1bit  reserved
274      */
275     uint32_t buffer_size_db; // 24
276     uint32_t max_bitrate;
277     uint32_t avg_bitrate;
278
279     /* 0x05 DecSpecificDescrTag */
280     uint8_t  decoder_cfg_len;
281     uint8_t *decoder_cfg;
282
283     /* 0x06 SLConfigDescrTag */
284     uint8_t  sl_config_len;
285     uint8_t *sl_config;
286 } MOV_esds_t;
287
288 struct MOVParseTableEntry;
289
290 typedef struct MOVStreamContext {
291     int ffindex; /* the ffmpeg stream id */
292     int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */
293     long next_chunk;
294     long chunk_count;
295     int64_t *chunk_offsets;
296     int stts_count;
297     Time2Sample *stts_data;
298     int ctts_count;
299     Time2Sample *ctts_data;
300     int edit_count;             /* number of 'edit' (elst atom) */
301     long sample_to_chunk_sz;
302     MOV_sample_to_chunk_tbl *sample_to_chunk;
303     long sample_to_chunk_index;
304     int sample_to_time_index;
305     long sample_to_time_sample;
306     uint64_t sample_to_time_time;
307     int sample_to_ctime_index;
308     int sample_to_ctime_sample;
309     long sample_size;
310     long sample_count;
311     long *sample_sizes;
312     long keyframe_count;
313     long *keyframes;
314     int time_scale;
315     int time_rate;
316     long current_sample;
317     long left_in_chunk; /* how many samples before next chunk */
318     MOV_esds_t esds;
319 } MOVStreamContext;
320
321 typedef struct MOVContext {
322     int mp4; /* set to 1 as soon as we are sure that the file is an .mp4 file (even some header parsing depends on this) */
323     AVFormatContext *fc;
324     int time_scale;
325     int64_t duration; /* duration of the longest track */
326     int found_moov; /* when both 'moov' and 'mdat' sections has been found */
327     int found_mdat; /* we suppose we have enough data to read the file */
328     int64_t mdat_size;
329     int64_t mdat_offset;
330     int ni;                                         ///< non interleaved mode
331     int total_streams;
332     /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio
333      * but we need the info to be able to skip data from those streams in the 'mdat' section
334      */
335     MOVStreamContext *streams[MAX_STREAMS];
336
337     int64_t next_chunk_offset;
338     MOVStreamContext *partial; /* != 0 : there is still to read in the current chunk */
339     int ctab_size;
340     MOV_ctab_t **ctab;           /* color tables */
341     const struct MOVParseTableEntry *parse_table; /* could be eventually used to change the table */
342     /* NOTE: for recursion save to/ restore from local variable! */
343
344     AVPaletteControl palette_control;
345 } MOVContext;
346
347
348 /* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */
349
350 /* those functions parse an atom */
351 /* return code:
352  1: found what I wanted, exit
353  0: continue to parse next atom
354  -1: error occured, exit
355  */
356 typedef int (*mov_parse_function)(MOVContext *ctx, ByteIOContext *pb, MOV_atom_t atom);
357
358 /* links atom IDs to parse functions */
359 typedef struct MOVParseTableEntry {
360     uint32_t type;
361     mov_parse_function func;
362 } MOVParseTableEntry;
363
364 static int ff_mov_lang_to_iso639(int code, char *to)
365 {
366     int i;
367     /* is it the mangled iso code? */
368     /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */
369     if (code > 138) {
370         for (i = 2; i >= 0; i--) {
371             to[i] = 0x60 + (code & 0x1f);
372             code >>= 5;
373         }
374         return 1;
375     }
376     /* old fashion apple lang code */
377     if (code >= (sizeof(mov_mdhd_language_map)/sizeof(char *)))
378         return 0;
379     if (!mov_mdhd_language_map[code])
380         return 0;
381     strncpy(to, mov_mdhd_language_map[code], 4);
382     return 1;
383 }
384
385 extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */
386 int ff_mov_iso639_to_lang(const char *lang, int mp4)
387 {
388     int i, code = 0;
389
390     /* old way, only for QT? */
391     for (i = 0; !mp4 && (i < (sizeof(mov_mdhd_language_map)/sizeof(char *))); i++) {
392         if (mov_mdhd_language_map[i] && !strcmp(lang, mov_mdhd_language_map[i]))
393             return i;
394     }
395     /* XXX:can we do that in mov too? */
396     if (!mp4)
397         return 0;
398     /* handle undefined as such */
399     if (lang[0] == '\0')
400         lang = "und";
401     /* 5bit ascii */
402     for (i = 0; i < 3; i++) {
403         unsigned char c = (unsigned char)lang[i];
404         if (c < 0x60)
405             return 0;
406         if (c > 0x60 + 0x1f)
407             return 0;
408         code <<= 5;
409         code |= (c - 0x60);
410     }
411     return code;
412 }
413
414 static int mov_read_leaf(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
415 {
416     if (atom.size>1)
417         url_fskip(pb, atom.size);
418 /*        url_seek(pb, atom_offset+atom.size, SEEK_SET); */
419     return 0;
420 }
421
422 static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
423 {
424     int64_t total_size = 0;
425     MOV_atom_t a;
426     int i;
427     int err = 0;
428
429     a.offset = atom.offset;
430
431     if (atom.size < 0)
432         atom.size = 0x7fffffffffffffffLL;
433     while(((total_size + 8) < atom.size) && !url_feof(pb) && !err) {
434         a.size = atom.size;
435         a.type=0L;
436         if(atom.size >= 8) {
437             a.size = get_be32(pb);
438             a.type = get_le32(pb);
439         }
440         total_size += 8;
441         a.offset += 8;
442         dprintf("type: %08x  %.4s  sz: %"PRIx64"  %"PRIx64"   %"PRIx64"\n", a.type, (char*)&a.type, a.size, atom.size, total_size);
443         if (a.size == 1) { /* 64 bit extended size */
444             a.size = get_be64(pb) - 8;
445             a.offset += 8;
446             total_size += 8;
447         }
448         if (a.size == 0) {
449             a.size = atom.size - total_size;
450             if (a.size <= 8)
451                 break;
452         }
453         for (i = 0; c->parse_table[i].type != 0L
454              && c->parse_table[i].type != a.type; i++)
455             /* empty */;
456
457         a.size -= 8;
458
459         if(a.size < 0)
460             break;
461
462         if (c->parse_table[i].type == 0) { /* skip leaf atoms data */
463             url_fskip(pb, a.size);
464         } else {
465             err = (c->parse_table[i].func)(c, pb, a);
466         }
467
468         a.offset += a.size;
469         total_size += a.size;
470     }
471
472     if (!err && total_size < atom.size && atom.size < 0x7ffff) {
473         url_fskip(pb, atom.size - total_size);
474     }
475
476     return err;
477 }
478
479 static int mov_read_ctab(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
480 {
481 #if 1
482     url_fskip(pb, atom.size); // for now
483 #else
484     VERY VERY BROKEN, NEVER execute this, needs rewrite
485     unsigned int len;
486     MOV_ctab_t *t;
487     c->ctab = av_realloc(c->ctab, ++c->ctab_size);
488     t = c->ctab[c->ctab_size];
489     t->seed = get_be32(pb);
490     t->flags = get_be16(pb);
491     t->size = get_be16(pb) + 1;
492     len = 2 * t->size * 4;
493     if (len > 0) {
494         t->clrs = av_malloc(len); // 16bit A R G B
495         if (t->clrs)
496             get_buffer(pb, t->clrs, len);
497     }
498 #endif
499
500     return 0;
501 }
502
503 static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
504 {
505     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
506     int len = 0;
507     uint32_t type;
508     uint32_t ctype;
509
510     get_byte(pb); /* version */
511     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
512
513     /* component type */
514     ctype = get_le32(pb);
515     type = get_le32(pb); /* component subtype */
516
517     dprintf("ctype= %c%c%c%c (0x%08lx)\n", *((char *)&ctype), ((char *)&ctype)[1], ((char *)&ctype)[2], ((char *)&ctype)[3], (long) ctype);
518     dprintf("stype= %c%c%c%c\n", *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]);
519     if(ctype == MKTAG('m', 'h', 'l', 'r')) /* MOV */
520         c->mp4 = 0;
521     else if(ctype == 0)
522         c->mp4 = 1;
523     if(type == MKTAG('v', 'i', 'd', 'e'))
524         st->codec->codec_type = CODEC_TYPE_VIDEO;
525     else if(type == MKTAG('s', 'o', 'u', 'n'))
526         st->codec->codec_type = CODEC_TYPE_AUDIO;
527     get_be32(pb); /* component  manufacture */
528     get_be32(pb); /* component flags */
529     get_be32(pb); /* component flags mask */
530
531     if(atom.size <= 24)
532         return 0; /* nothing left to read */
533     /* XXX: MP4 uses a C string, not a pascal one */
534     /* component name */
535
536     if(c->mp4) {
537         /* .mp4: C string */
538         while(get_byte(pb) && (++len < (atom.size - 24)));
539     } else {
540         /* .mov: PASCAL string */
541         len = get_byte(pb);
542         url_fskip(pb, len);
543     }
544
545     url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
546     return 0;
547 }
548
549 static int mov_mp4_read_descr_len(ByteIOContext *pb)
550 {
551     int len = 0;
552     int count = 4;
553     while (count--) {
554         int c = get_byte(pb);
555         len = (len << 7) | (c & 0x7f);
556         if (!(c & 0x80))
557             break;
558     }
559     return len;
560 }
561
562 static int mov_mp4_read_descr(ByteIOContext *pb, int *tag)
563 {
564     int len;
565     *tag = get_byte(pb);
566     len = mov_mp4_read_descr_len(pb);
567     dprintf("MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
568     return len;
569 }
570
571 static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
572 {
573     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
574     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
575     int64_t start_pos = url_ftell(pb);
576     int tag, len;
577
578     /* Well, broken but suffisant for some MP4 streams */
579     get_be32(pb); /* version + flags */
580     len = mov_mp4_read_descr(pb, &tag);
581     if (tag == MP4ESDescrTag) {
582         get_be16(pb); /* ID */
583         get_byte(pb); /* priority */
584     } else
585         get_be16(pb); /* ID */
586
587     len = mov_mp4_read_descr(pb, &tag);
588     if (tag == MP4DecConfigDescrTag) {
589         sc->esds.object_type_id = get_byte(pb);
590         sc->esds.stream_type = get_byte(pb);
591         sc->esds.buffer_size_db = get_be24(pb);
592         sc->esds.max_bitrate = get_be32(pb);
593         sc->esds.avg_bitrate = get_be32(pb);
594
595         st->codec->codec_id= codec_get_id(ff_mov_obj_type, sc->esds.object_type_id);
596         len = mov_mp4_read_descr(pb, &tag);
597         if (tag == MP4DecSpecificDescrTag) {
598             dprintf("Specific MPEG4 header len=%d\n", len);
599             st->codec->extradata = (uint8_t*) av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
600             if (st->codec->extradata) {
601                 get_buffer(pb, st->codec->extradata, len);
602                 st->codec->extradata_size = len;
603             }
604         }
605     }
606     /* in any case, skip garbage */
607     url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
608     return 0;
609 }
610
611 /* this atom contains actual media data */
612 static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
613 {
614     if(atom.size == 0) /* wrong one (MP4) */
615         return 0;
616     c->found_mdat=1;
617     c->mdat_offset = atom.offset;
618     c->mdat_size = atom.size;
619     if(c->found_moov)
620         return 1; /* found both, just go */
621     url_fskip(pb, atom.size);
622     return 0; /* now go for moov */
623 }
624
625 static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
626 {
627     uint32_t type = get_le32(pb);
628
629     /* from mplayer */
630     switch (type) {
631     case MKTAG('i', 's', 'o', 'm'):
632     case MKTAG('m', 'p', '4', '1'):
633     case MKTAG('m', 'p', '4', '2'):
634     case MKTAG('3', 'g', 'p', '1'):
635     case MKTAG('3', 'g', 'p', '2'):
636     case MKTAG('3', 'g', '2', 'a'):
637     case MKTAG('3', 'g', 'p', '3'):
638     case MKTAG('3', 'g', 'p', '4'):
639     case MKTAG('3', 'g', 'p', '5'):
640     case MKTAG('m', 'm', 'p', '4'): /* Mobile MP4 */
641     case MKTAG('M', '4', 'A', ' '): /* Apple iTunes AAC-LC Audio */
642     case MKTAG('M', '4', 'P', ' '): /* Apple iTunes AAC-LC Protected Audio */
643     case MKTAG('m', 'j', 'p', '2'): /* Motion Jpeg 2000 */
644         c->mp4 = 1;
645     case MKTAG('q', 't', ' ', ' '):
646     default:
647         av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
648     }
649     get_be32(pb); /* minor version */
650     url_fskip(pb, atom.size - 8);
651     return 0;
652 }
653
654 /* this atom should contain all header atoms */
655 static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
656 {
657     int err;
658
659     err = mov_read_default(c, pb, atom);
660     /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
661     /* so we don't parse the whole file if over a network */
662     c->found_moov=1;
663     if(c->found_mdat)
664         return 1; /* found both, just go */
665     return 0; /* now go for mdat */
666 }
667
668
669 static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
670 {
671     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
672     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
673     int version = get_byte(pb);
674     int lang;
675
676     if (version > 1)
677         return 1; /* unsupported */
678
679     get_byte(pb); get_byte(pb);
680     get_byte(pb); /* flags */
681
682     if (version == 1) {
683         get_be64(pb);
684         get_be64(pb);
685     } else {
686         get_be32(pb); /* creation time */
687         get_be32(pb); /* modification time */
688     }
689
690     sc->time_scale = get_be32(pb);
691     st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
692
693     lang = get_be16(pb); /* language */
694     ff_mov_lang_to_iso639(lang, st->language);
695     get_be16(pb); /* quality */
696
697     return 0;
698 }
699
700 static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
701 {
702     int version = get_byte(pb); /* version */
703     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
704
705     if (version == 1) {
706         get_be64(pb);
707         get_be64(pb);
708     } else {
709         get_be32(pb); /* creation time */
710         get_be32(pb); /* modification time */
711     }
712     c->time_scale = get_be32(pb); /* time scale */
713 #ifdef DEBUG
714     av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);
715 #endif
716     c->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
717     get_be32(pb); /* preferred scale */
718
719     get_be16(pb); /* preferred volume */
720
721     url_fskip(pb, 10); /* reserved */
722
723     url_fskip(pb, 36); /* display matrix */
724
725     get_be32(pb); /* preview time */
726     get_be32(pb); /* preview duration */
727     get_be32(pb); /* poster time */
728     get_be32(pb); /* selection time */
729     get_be32(pb); /* selection duration */
730     get_be32(pb); /* current time */
731     get_be32(pb); /* next track ID */
732
733     return 0;
734 }
735
736 static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
737 {
738     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
739
740     if((uint64_t)atom.size > (1<<30))
741         return -1;
742
743     // currently SVQ3 decoder expect full STSD header - so let's fake it
744     // this should be fixed and just SMI header should be passed
745     av_free(st->codec->extradata);
746     st->codec->extradata_size = 0x5a + atom.size;
747     st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
748
749     if (st->codec->extradata) {
750         strcpy(st->codec->extradata, "SVQ3"); // fake
751         get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
752         dprintf("Reading SMI %"PRId64"  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
753     } else
754         url_fskip(pb, atom.size);
755
756     return 0;
757 }
758
759 static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
760 {
761     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
762     int little_endian = get_be16(pb);
763
764     if (little_endian) {
765         switch (st->codec->codec_id) {
766         case CODEC_ID_PCM_S24BE:
767             st->codec->codec_id = CODEC_ID_PCM_S24LE;
768             break;
769         case CODEC_ID_PCM_S32BE:
770             st->codec->codec_id = CODEC_ID_PCM_S32LE;
771             break;
772         default:
773             break;
774         }
775     }
776     return 0;
777 }
778
779 static int mov_read_alac(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
780 {
781     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
782
783     // currently ALAC decoder expect full atom header - so let's fake it
784     // this should be fixed and just ALAC header should be passed
785
786     av_free(st->codec->extradata);
787     st->codec->extradata_size = 36;
788     st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
789
790     if (st->codec->extradata) {
791         strcpy(st->codec->extradata + 4, "alac"); // fake
792         get_buffer(pb, st->codec->extradata + 8, 36 - 8);
793         dprintf("Reading alac %d  %s\n", st->codec->extradata_size, (char*)st->codec->extradata);
794     } else
795         url_fskip(pb, atom.size);
796     return 0;
797 }
798
799 static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
800 {
801     offset_t start_pos = url_ftell(pb);
802     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
803
804     if((uint64_t)atom.size > (1<<30))
805         return -1;
806
807     if (st->codec->codec_id == CODEC_ID_QDM2) {
808         // pass all frma atom to codec, needed at least for QDM2
809         av_free(st->codec->extradata);
810         st->codec->extradata_size = atom.size;
811         st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
812
813         if (st->codec->extradata) {
814             get_buffer(pb, st->codec->extradata, atom.size);
815         } else
816             url_fskip(pb, atom.size);
817     } else if (atom.size > 8) { /* to read frma, esds atoms */
818         mov_read_default(c, pb, atom);
819     } else if (atom.size > 0)
820         url_fskip(pb, atom.size);
821     /* in any case, skip garbage */
822     url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
823     return 0;
824 }
825
826 static int mov_read_jp2h(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
827 {
828     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
829
830     if((uint64_t)atom.size > (1<<30))
831         return -1;
832
833     av_free(st->codec->extradata);
834
835     st->codec->extradata_size = atom.size + 8;
836     st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
837
838     /* pass all jp2h atom to codec */
839     if (st->codec->extradata) {
840         strcpy(st->codec->extradata + 4, "jp2h");
841         get_buffer(pb, st->codec->extradata + 8, atom.size);
842     } else
843         url_fskip(pb, atom.size);
844     return 0;
845 }
846
847 static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
848 {
849     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
850
851     if((uint64_t)atom.size > (1<<30))
852         return -1;
853
854     av_free(st->codec->extradata);
855
856     st->codec->extradata_size = atom.size;
857     st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
858
859     if (st->codec->extradata) {
860         get_buffer(pb, st->codec->extradata, atom.size);
861     } else
862         url_fskip(pb, atom.size);
863
864     return 0;
865 }
866
867 static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
868 {
869     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
870     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
871     unsigned int i, entries;
872
873     get_byte(pb); /* version */
874     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
875
876     entries = get_be32(pb);
877
878     if(entries >= UINT_MAX/sizeof(int64_t))
879         return -1;
880
881     sc->chunk_count = entries;
882     sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t));
883     if (!sc->chunk_offsets)
884         return -1;
885     if (atom.type == MKTAG('s', 't', 'c', 'o')) {
886         for(i=0; i<entries; i++) {
887             sc->chunk_offsets[i] = get_be32(pb);
888         }
889     } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
890         for(i=0; i<entries; i++) {
891             sc->chunk_offsets[i] = get_be64(pb);
892         }
893     } else
894         return -1;
895
896     for(i=0; i<c->fc->nb_streams; i++){
897         MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
898         if(sc2 && sc2->chunk_offsets){
899             int64_t first= sc2->chunk_offsets[0];
900             int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
901             if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
902                 c->ni=1;
903         }
904     }
905     return 0;
906 }
907
908 static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
909 {
910     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
911     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
912     int entries, frames_per_sample;
913     uint32_t format;
914     uint8_t codec_name[32];
915
916     /* for palette traversal */
917     int color_depth;
918     int color_start;
919     int color_count;
920     int color_end;
921     int color_index;
922     int color_dec;
923     int color_greyscale;
924     unsigned char *color_table;
925     int j;
926     unsigned char r, g, b;
927
928     get_byte(pb); /* version */
929     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
930
931     entries = get_be32(pb);
932
933     while(entries--) { //Parsing Sample description table
934         enum CodecID id;
935         MOV_atom_t a = { 0, 0, 0 };
936         offset_t start_pos = url_ftell(pb);
937         int size = get_be32(pb); /* size */
938         format = get_le32(pb); /* data format */
939
940         get_be32(pb); /* reserved */
941         get_be16(pb); /* reserved */
942         get_be16(pb); /* index */
943
944         dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
945                 size,
946                 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
947                 st->codec->codec_type);
948         st->codec->codec_tag = format;
949         /* codec_type is set earlier by read_hdlr */
950         if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
951             /* for MPEG4: set codec type by looking for it */
952             id = codec_get_id(mov_video_tags, format);
953             if(id <= 0)
954                 id = codec_get_id(codec_bmp_tags, format);
955             st->codec->codec_id = id;
956             get_be16(pb); /* version */
957             get_be16(pb); /* revision level */
958             get_be32(pb); /* vendor */
959             get_be32(pb); /* temporal quality */
960             get_be32(pb); /* spacial quality */
961             if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
962                 get_be16(pb);
963                 get_be16(pb);
964             }else{
965                 st->codec->width = get_be16(pb); /* width */
966                 st->codec->height = get_be16(pb); /* height */
967             }
968             get_be32(pb); /* horiz resolution */
969             get_be32(pb); /* vert resolution */
970             get_be32(pb); /* data size, always 0 */
971             frames_per_sample = get_be16(pb); /* frames per samples */
972 #ifdef DEBUG
973             av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
974 #endif
975             get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
976             if (codec_name[0] <= 31) {
977                 memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
978                 st->codec->codec_name[codec_name[0]] = 0;
979             }
980
981             st->codec->bits_per_sample = get_be16(pb); /* depth */
982             st->codec->color_table_id = get_be16(pb); /* colortable id */
983
984 /*          These are set in mov_read_stts and might already be set!
985             st->codec->time_base.den      = 25;
986             st->codec->time_base.num = 1;
987 */
988
989             /* figure out the palette situation */
990             color_depth = st->codec->bits_per_sample & 0x1F;
991             color_greyscale = st->codec->bits_per_sample & 0x20;
992
993             /* if the depth is 2, 4, or 8 bpp, file is palettized */
994             if ((color_depth == 2) || (color_depth == 4) ||
995                 (color_depth == 8)) {
996
997                 if (color_greyscale) {
998
999                     /* compute the greyscale palette */
1000                     color_count = 1 << color_depth;
1001                     color_index = 255;
1002                     color_dec = 256 / (color_count - 1);
1003                     for (j = 0; j < color_count; j++) {
1004                         r = g = b = color_index;
1005                         c->palette_control.palette[j] =
1006                             (r << 16) | (g << 8) | (b);
1007                         color_index -= color_dec;
1008                         if (color_index < 0)
1009                             color_index = 0;
1010                     }
1011
1012                 } else if (st->codec->color_table_id & 0x08) {
1013
1014                     /* if flag bit 3 is set, use the default palette */
1015                     color_count = 1 << color_depth;
1016                     if (color_depth == 2)
1017                         color_table = ff_qt_default_palette_4;
1018                     else if (color_depth == 4)
1019                         color_table = ff_qt_default_palette_16;
1020                     else
1021                         color_table = ff_qt_default_palette_256;
1022
1023                     for (j = 0; j < color_count; j++) {
1024                         r = color_table[j * 4 + 0];
1025                         g = color_table[j * 4 + 1];
1026                         b = color_table[j * 4 + 2];
1027                         c->palette_control.palette[j] =
1028                             (r << 16) | (g << 8) | (b);
1029                     }
1030
1031                 } else {
1032
1033                     /* load the palette from the file */
1034                     color_start = get_be32(pb);
1035                     color_count = get_be16(pb);
1036                     color_end = get_be16(pb);
1037                     for (j = color_start; j <= color_end; j++) {
1038                         /* each R, G, or B component is 16 bits;
1039                          * only use the top 8 bits; skip alpha bytes
1040                          * up front */
1041                         get_byte(pb);
1042                         get_byte(pb);
1043                         r = get_byte(pb);
1044                         get_byte(pb);
1045                         g = get_byte(pb);
1046                         get_byte(pb);
1047                         b = get_byte(pb);
1048                         get_byte(pb);
1049                         c->palette_control.palette[j] =
1050                             (r << 16) | (g << 8) | (b);
1051                     }
1052                 }
1053
1054                 st->codec->palctrl = &c->palette_control;
1055                 st->codec->palctrl->palette_changed = 1;
1056             } else
1057                 st->codec->palctrl = NULL;
1058         } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
1059             uint16_t version = get_be16(pb);
1060
1061             st->codec->codec_id = codec_get_id(mov_audio_tags, format);
1062             get_be16(pb); /* revision level */
1063             get_be32(pb); /* vendor */
1064
1065             st->codec->channels = get_be16(pb);             /* channel count */
1066             st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1067             /* do we need to force to 16 for AMR ? */
1068
1069             /* handle specific s8 codec */
1070             get_be16(pb); /* compression id = 0*/
1071             get_be16(pb); /* packet size = 0 */
1072
1073             st->codec->sample_rate = ((get_be32(pb) >> 16));
1074
1075             switch (st->codec->codec_id) {
1076             case CODEC_ID_PCM_S16LE:
1077             case CODEC_ID_PCM_S16BE:
1078                 if (st->codec->bits_per_sample == 8)
1079                     st->codec->codec_id = CODEC_ID_PCM_S8;
1080                 /* fall */
1081             case CODEC_ID_PCM_U8:
1082                 if (st->codec->bits_per_sample == 16)
1083                     st->codec->codec_id = CODEC_ID_PCM_S16BE;
1084                 st->codec->bit_rate = st->codec->sample_rate * 8;
1085                 break;
1086             case CODEC_ID_AMR_WB:
1087                 st->codec->sample_rate = 16000; /* should really we ? */
1088                 st->codec->channels=1; /* really needed */
1089                 break;
1090             case CODEC_ID_AMR_NB:
1091                 st->codec->sample_rate = 8000; /* should really we ? */
1092                 st->codec->channels=1; /* really needed */
1093                 break;
1094             default:
1095                 break;
1096             }
1097
1098             //Read QT version 1 fields. In version 0 theese dont exist
1099             dprintf("version =%d mp4=%d\n",version,c->mp4);
1100             if(version==1) {
1101                 get_be32(pb); /* samples per packet */
1102                 get_be32(pb); /* bytes per packet */
1103                 get_be32(pb); /* bytes per frame */
1104                 get_be32(pb); /* bytes per sample */
1105             } else if(version==2) {
1106                 get_be32(pb); /* sizeof struct only */
1107                 st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */
1108                 st->codec->channels = get_be32(pb);
1109                 get_be32(pb); /* always 0x7F000000 */
1110                 get_be32(pb); /* bits per channel if sound is uncompressed */
1111                 get_be32(pb); /* lcpm format specific flag */
1112                 get_be32(pb); /* bytes per audio packet if constant */
1113                 get_be32(pb); /* lpcm frames per audio packet if constant */
1114             }
1115         } else {
1116             /* other codec type, just skip (rtp, mp4s, tmcd ...) */
1117             url_fskip(pb, size - (url_ftell(pb) - start_pos));
1118         }
1119         /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
1120         a.size = size - (url_ftell(pb) - start_pos);
1121         if (a.size > 8)
1122             mov_read_default(c, pb, a);
1123         else if (a.size > 0)
1124             url_fskip(pb, a.size);
1125     }
1126
1127     if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1128         st->codec->sample_rate= sc->time_scale;
1129     }
1130
1131     return 0;
1132 }
1133
1134 static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1135 {
1136     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1137     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1138     unsigned int i, entries;
1139
1140     get_byte(pb); /* version */
1141     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1142
1143     entries = get_be32(pb);
1144
1145     if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1146         return -1;
1147
1148 #ifdef DEBUG
1149 av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1150 #endif
1151     sc->sample_to_chunk_sz = entries;
1152     sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1153     if (!sc->sample_to_chunk)
1154         return -1;
1155     for(i=0; i<entries; i++) {
1156         sc->sample_to_chunk[i].first = get_be32(pb);
1157         sc->sample_to_chunk[i].count = get_be32(pb);
1158         sc->sample_to_chunk[i].id = get_be32(pb);
1159     }
1160     return 0;
1161 }
1162
1163 static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1164 {
1165     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1166     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1167     unsigned int i, entries;
1168
1169     get_byte(pb); /* version */
1170     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1171
1172     entries = get_be32(pb);
1173
1174     if(entries >= UINT_MAX / sizeof(long))
1175         return -1;
1176
1177     sc->keyframe_count = entries;
1178 #ifdef DEBUG
1179     av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1180 #endif
1181     sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1182     if (!sc->keyframes)
1183         return -1;
1184     for(i=0; i<entries; i++) {
1185         sc->keyframes[i] = get_be32(pb);
1186 #ifdef DEBUG
1187 /*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1188 #endif
1189     }
1190     return 0;
1191 }
1192
1193 static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1194 {
1195     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1196     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1197     unsigned int i, entries;
1198
1199     get_byte(pb); /* version */
1200     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1201
1202     sc->sample_size = get_be32(pb);
1203     entries = get_be32(pb);
1204     if(entries >= UINT_MAX / sizeof(long))
1205         return -1;
1206
1207     sc->sample_count = entries;
1208 #ifdef DEBUG
1209     av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1210 #endif
1211     if(sc->sample_size) {
1212         /* override sample size for uncompressed sound */
1213         switch (st->codec->codec_id) {
1214         case CODEC_ID_PCM_S32BE:
1215         case CODEC_ID_PCM_S32LE:
1216             sc->sample_size = 4 * st->codec->channels;
1217             break;
1218         case CODEC_ID_PCM_S24BE:
1219         case CODEC_ID_PCM_S24LE:
1220             sc->sample_size = 3 * st->codec->channels;
1221             break;
1222         case CODEC_ID_PCM_S16BE:
1223         case CODEC_ID_PCM_S16LE:
1224             sc->sample_size = 2 * st->codec->channels;
1225             break;
1226         case CODEC_ID_PCM_MULAW:
1227         case CODEC_ID_PCM_ALAW:
1228         case CODEC_ID_PCM_S8:
1229         case CODEC_ID_PCM_U8:
1230             sc->sample_size = 1 * st->codec->channels;
1231             break;
1232         default:
1233             break;
1234         }
1235         assert(sc->sample_size);
1236         return 0; /* there isn't any table following */
1237     }
1238     sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1239     if (!sc->sample_sizes)
1240         return -1;
1241     for(i=0; i<entries; i++) {
1242         sc->sample_sizes[i] = get_be32(pb);
1243 #ifdef DEBUG
1244         av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1245 #endif
1246     }
1247     return 0;
1248 }
1249
1250 static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1251 {
1252     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1253     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1254     unsigned int i, entries;
1255     int64_t duration=0;
1256     int64_t total_sample_count=0;
1257
1258     get_byte(pb); /* version */
1259     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1260     entries = get_be32(pb);
1261     if(entries >= UINT_MAX / sizeof(Time2Sample))
1262         return -1;
1263
1264     sc->stts_count = entries;
1265     sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1266
1267 #ifdef DEBUG
1268 av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1269 #endif
1270
1271     sc->time_rate=0;
1272
1273     for(i=0; i<entries; i++) {
1274         int sample_duration;
1275         int sample_count;
1276
1277         sample_count=get_be32(pb);
1278         sample_duration = get_be32(pb);
1279         sc->stts_data[i].count= sample_count;
1280         sc->stts_data[i].duration= sample_duration;
1281
1282         sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1283
1284         dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1285
1286         duration+=(int64_t)sample_duration*sample_count;
1287         total_sample_count+=sample_count;
1288     }
1289
1290     st->nb_frames= total_sample_count;
1291     if(duration)
1292         st->duration= duration;
1293     return 0;
1294 }
1295
1296 static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1297 {
1298     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1299     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1300     unsigned int i, entries;
1301
1302     get_byte(pb); /* version */
1303     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1304     entries = get_be32(pb);
1305     if(entries >= UINT_MAX / sizeof(Time2Sample))
1306         return -1;
1307
1308     sc->ctts_count = entries;
1309     sc->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1310
1311     dprintf("track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
1312
1313     for(i=0; i<entries; i++) {
1314         int count    =get_be32(pb);
1315         int duration =get_be32(pb);
1316
1317         sc->ctts_data[i].count   = count;
1318         sc->ctts_data[i].duration= duration;
1319
1320         sc->time_rate= ff_gcd(sc->time_rate, duration);
1321     }
1322     return 0;
1323 }
1324
1325 static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1326 {
1327     AVStream *st;
1328     MOVStreamContext *sc;
1329
1330     st = av_new_stream(c->fc, c->fc->nb_streams);
1331     if (!st) return -2;
1332     sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1333     if (!sc) {
1334         av_free(st);
1335         return -1;
1336     }
1337
1338     sc->sample_to_chunk_index = -1;
1339     st->priv_data = sc;
1340     st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1341     st->start_time = 0; /* XXX: check */
1342     c->streams[c->fc->nb_streams-1] = sc;
1343
1344     return mov_read_default(c, pb, atom);
1345 }
1346
1347 static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1348 {
1349     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1350     int version = get_byte(pb);
1351
1352     get_byte(pb); get_byte(pb);
1353     get_byte(pb); /* flags */
1354     /*
1355     MOV_TRACK_ENABLED 0x0001
1356     MOV_TRACK_IN_MOVIE 0x0002
1357     MOV_TRACK_IN_PREVIEW 0x0004
1358     MOV_TRACK_IN_POSTER 0x0008
1359     */
1360
1361     if (version == 1) {
1362         get_be64(pb);
1363         get_be64(pb);
1364     } else {
1365         get_be32(pb); /* creation time */
1366         get_be32(pb); /* modification time */
1367     }
1368     st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1369     get_be32(pb); /* reserved */
1370     st->start_time = 0; /* check */
1371     (version == 1) ? get_be64(pb) : get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1372     get_be32(pb); /* reserved */
1373     get_be32(pb); /* reserved */
1374
1375     get_be16(pb); /* layer */
1376     get_be16(pb); /* alternate group */
1377     get_be16(pb); /* volume */
1378     get_be16(pb); /* reserved */
1379
1380     url_fskip(pb, 36); /* display matrix */
1381
1382     /* those are fixed-point */
1383     /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1384     /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1385
1386     return 0;
1387 }
1388
1389 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1390 /* like the files created with Adobe Premiere 5.0, for samples see */
1391 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1392 static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1393 {
1394     int err;
1395
1396     if (atom.size < 8)
1397         return 0; /* continue */
1398     if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1399         url_fskip(pb, atom.size - 4);
1400         return 0;
1401     }
1402     atom.type = get_le32(pb);
1403     atom.offset += 8;
1404     atom.size -= 8;
1405     if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1406         url_fskip(pb, atom.size);
1407         return 0;
1408     }
1409     err = mov_read_mdat(c, pb, atom);
1410     return err;
1411 }
1412
1413
1414 #ifdef CONFIG_ZLIB
1415 static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1416 {
1417     return -1;
1418 }
1419
1420 static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1421 {
1422     ByteIOContext ctx;
1423     uint8_t *cmov_data;
1424     uint8_t *moov_data; /* uncompressed data */
1425     long cmov_len, moov_len;
1426     int ret;
1427
1428     get_be32(pb); /* dcom atom */
1429     if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1430         return -1;
1431     if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1432         av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
1433         return -1;
1434     }
1435     get_be32(pb); /* cmvd atom */
1436     if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1437         return -1;
1438     moov_len = get_be32(pb); /* uncompressed size */
1439     cmov_len = atom.size - 6 * 4;
1440
1441     cmov_data = (uint8_t *) av_malloc(cmov_len);
1442     if (!cmov_data)
1443         return -1;
1444     moov_data = (uint8_t *) av_malloc(moov_len);
1445     if (!moov_data) {
1446         av_free(cmov_data);
1447         return -1;
1448     }
1449     get_buffer(pb, cmov_data, cmov_len);
1450     if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1451         return -1;
1452     if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1453         return -1;
1454     ctx.buf_end = ctx.buffer + moov_len;
1455     atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1456     atom.offset = 0;
1457     atom.size = moov_len;
1458 #ifdef DEBUG
1459 //    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1460 #endif
1461     ret = mov_read_default(c, &ctx, atom);
1462     av_free(moov_data);
1463     av_free(cmov_data);
1464
1465     return ret;
1466 }
1467 #endif
1468
1469 /* edit list atom */
1470 static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1471 {
1472   int i, edit_count;
1473
1474   get_byte(pb); /* version */
1475   get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1476   edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1477
1478   for(i=0; i<edit_count; i++){
1479     get_be32(pb); /* Track duration */
1480     get_be32(pb); /* Media time */
1481     get_be32(pb); /* Media rate */
1482   }
1483   dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1484   return 0;
1485 }
1486
1487 static const MOVParseTableEntry mov_default_parse_table[] = {
1488 /* mp4 atoms */
1489 { MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1490 { MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1491 { MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1492 { MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1493 { MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1494 { MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1495 { MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1496 { MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1497 { MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1498 { MKTAG( 'e', 'n', 'd', 'a' ), mov_read_enda },
1499 { MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1500 { MKTAG( 'f', 't', 'y', 'p' ), mov_read_ftyp },
1501 { MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1502 { MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1503 { MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1504 { MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
1505 { MKTAG( 'j', 'p', '2', 'h' ), mov_read_jp2h },
1506 { MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1507 { MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1508 { MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1509 { MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1510 { MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
1511 { MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },
1512 { MKTAG( 'm', 'p', '4', 's' ), mov_read_default },
1513 { MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },
1514 { MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },
1515 { MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
1516 { MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },
1517 { MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },
1518 { MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },
1519 { MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },
1520 { MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */
1521 { MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
1522 { MKTAG( 'a', 'l', 'a', 'c' ), mov_read_alac }, /* alac specific atom */
1523 { MKTAG( 'a', 'v', 'c', 'C' ), mov_read_avcC },
1524 { MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1525 { MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1526 { MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1527 { MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1528 { MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1529 { MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1530 { MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1531 { MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1532 { MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1533 { MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1534 { MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1535 { MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1536 { MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1537 { MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1538 { MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1539 { MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1540 { MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1541 { MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1542 /* extra mp4 */
1543 { MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1544 /* QT atoms */
1545 { MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1546 { MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1547 { MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1548 { MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1549 { MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1550 { MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1551 { MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1552 { MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1553 { MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1554 { MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1555 { MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1556 { MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1557 { MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1558 { MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1559 { MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1560 { MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1561 //{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1562 #ifdef CONFIG_ZLIB
1563 { MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1564 #else
1565 { MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1566 #endif
1567 { 0L, mov_read_leaf }
1568 };
1569
1570 static void mov_free_stream_context(MOVStreamContext *sc)
1571 {
1572     if(sc) {
1573         av_freep(&sc->chunk_offsets);
1574         av_freep(&sc->sample_to_chunk);
1575         av_freep(&sc->sample_sizes);
1576         av_freep(&sc->keyframes);
1577         av_freep(&sc->stts_data);
1578         av_freep(&sc->ctts_data);
1579         av_freep(&sc);
1580     }
1581 }
1582
1583 static inline uint32_t mov_to_tag(uint8_t *buf)
1584 {
1585     return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1586 }
1587
1588 static inline uint32_t to_be32(uint8_t *buf)
1589 {
1590     return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1591 }
1592
1593 /* XXX: is it sufficient ? */
1594 static int mov_probe(AVProbeData *p)
1595 {
1596     unsigned int offset;
1597     uint32_t tag;
1598     int score = 0;
1599
1600     /* check file header */
1601     if (p->buf_size <= 12)
1602         return 0;
1603     offset = 0;
1604     for(;;) {
1605         /* ignore invalid offset */
1606         if ((offset + 8) > (unsigned int)p->buf_size)
1607             return score;
1608         tag = mov_to_tag(p->buf + offset + 4);
1609         switch(tag) {
1610         /* check for obvious tags */
1611         case MKTAG( 'j', 'P', ' ', ' ' ): /* jpeg 2000 signature */
1612         case MKTAG( 'm', 'o', 'o', 'v' ):
1613         case MKTAG( 'm', 'd', 'a', 't' ):
1614         case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1615         case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1616             return AVPROBE_SCORE_MAX;
1617         /* those are more common words, so rate then a bit less */
1618         case MKTAG( 'w', 'i', 'd', 'e' ):
1619         case MKTAG( 'f', 'r', 'e', 'e' ):
1620         case MKTAG( 'j', 'u', 'n', 'k' ):
1621         case MKTAG( 'p', 'i', 'c', 't' ):
1622             return AVPROBE_SCORE_MAX - 5;
1623         case MKTAG( 'f', 't', 'y', 'p' ):
1624         case MKTAG( 's', 'k', 'i', 'p' ):
1625         case MKTAG( 'u', 'u', 'i', 'd' ):
1626             offset = to_be32(p->buf+offset) + offset;
1627             /* if we only find those cause probedata is too small at least rate them */
1628             score = AVPROBE_SCORE_MAX - 50;
1629             break;
1630         default:
1631             /* unrecognized tag */
1632             return score;
1633         }
1634     }
1635     return score;
1636 }
1637
1638 static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1639 {
1640     MOVContext *mov = (MOVContext *) s->priv_data;
1641     ByteIOContext *pb = &s->pb;
1642     int i, j, nb, err;
1643     MOV_atom_t atom = { 0, 0, 0 };
1644
1645     mov->fc = s;
1646     mov->parse_table = mov_default_parse_table;
1647
1648     if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1649         atom.size = url_fsize(pb);
1650     else
1651         atom.size = 0x7FFFFFFFFFFFFFFFLL;
1652
1653     /* check MOV header */
1654     err = mov_read_default(mov, pb, atom);
1655     if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1656         av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1657                 err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1658         return -1;
1659     }
1660     dprintf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1661
1662     /* some cleanup : make sure we are on the mdat atom */
1663     if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1664         url_fseek(pb, mov->mdat_offset, SEEK_SET);
1665
1666     mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1667     mov->total_streams = nb = s->nb_streams;
1668
1669 #if 1
1670     for(i=0; i<s->nb_streams;) {
1671         if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1672             av_free(s->streams[i]);
1673             for(j=i+1; j<s->nb_streams; j++)
1674                 s->streams[j-1] = s->streams[j];
1675             s->nb_streams--;
1676         } else
1677             i++;
1678     }
1679     for(i=0; i<s->nb_streams;i++) {
1680         MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
1681
1682         if(!sc->time_rate)
1683             sc->time_rate=1;
1684         if(!sc->time_scale)
1685             sc->time_scale= mov->time_scale;
1686         av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1687
1688         if(s->streams[i]->duration != AV_NOPTS_VALUE){
1689             assert(s->streams[i]->duration % sc->time_rate == 0);
1690             s->streams[i]->duration /= sc->time_rate;
1691         }
1692
1693         sc->ffindex = i;
1694         sc->is_ff_stream = 1;
1695     }
1696 #endif
1697     return 0;
1698 }
1699
1700 /* Yes, this is ugly... I didn't write the specs of QT :p */
1701 /* XXX:remove useless commented code sometime */
1702 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1703 {
1704     MOVContext *mov = (MOVContext *) s->priv_data;
1705     MOVStreamContext *sc;
1706     AVStream *st;
1707     int64_t offset = INT64_MAX;
1708     int64_t best_dts = INT64_MAX;
1709     int i, a, b, m;
1710     int next_sample= -99;
1711     int size;
1712     int idx;
1713     size = 0x0FFFFFFF;
1714
1715     if (mov->partial) {
1716         sc = mov->partial;
1717         idx = sc->sample_to_chunk_index;
1718
1719         if (idx < 0) return 0;
1720         dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1721         //size = sc->sample_sizes[sc->current_sample];
1722         // that ain't working...
1723         //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1724         size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1725
1726         next_sample= sc->current_sample+1;
1727
1728         sc->left_in_chunk--;
1729
1730         if (sc->left_in_chunk <= 0)
1731             mov->partial = 0;
1732         offset = mov->next_chunk_offset;
1733         /* extract the sample */
1734
1735         goto readchunk;
1736     }
1737
1738 again:
1739     sc = 0;
1740     if(offset == INT64_MAX)
1741         best_dts= INT64_MAX;
1742     for(i=0; i<mov->total_streams; i++) {
1743         MOVStreamContext *msc = mov->streams[i];
1744
1745         if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1746             if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1747                 int64_t dts;
1748                 int index= msc->sample_to_time_index;
1749                 int sample= msc->sample_to_time_sample;
1750                 int time= msc->sample_to_time_time;
1751                 int duration = msc->stts_data[index].duration;
1752                 int count = msc->stts_data[index].count;
1753                 if (sample + count <= msc->current_sample) {
1754                     sample += count;
1755                     time   += count*duration;
1756                     index ++;
1757                     duration = msc->stts_data[index].duration;
1758                 }
1759                 dts = time + (msc->current_sample - sample) * (int64_t)duration;
1760                 dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1761                 dprintf("stream: %d dts: %"PRId64" best_dts: %"PRId64" offset: %"PRId64"\n", i, dts, best_dts, offset);
1762                 if(dts < best_dts){
1763                     best_dts= dts;
1764                     sc = msc;
1765                     offset = msc->chunk_offsets[msc->next_chunk];
1766                 }
1767             }else{
1768                 if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1769                     sc = msc;
1770                     offset = msc->chunk_offsets[msc->next_chunk];
1771                 }
1772             }
1773         }
1774     }
1775     if (!sc || offset==INT64_MAX)
1776         return -1;
1777
1778     sc->next_chunk++;
1779
1780     if(mov->next_chunk_offset < offset) { /* some meta data */
1781         url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1782         mov->next_chunk_offset = offset;
1783     }
1784
1785     if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1786         url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1787         mov->next_chunk_offset = offset;
1788         offset = INT64_MAX;
1789         goto again;
1790     }
1791
1792     /* now get the chunk size... */
1793
1794     for(i=0; i<mov->total_streams; i++) {
1795         MOVStreamContext *msc = mov->streams[i];
1796         if ((msc->next_chunk < msc->chunk_count)
1797             && msc->chunk_offsets[msc->next_chunk] - offset < size
1798             && msc->chunk_offsets[msc->next_chunk] > offset)
1799             size = msc->chunk_offsets[msc->next_chunk] - offset;
1800     }
1801
1802 #ifdef MOV_MINOLTA_FIX
1803     //Make sure that size is according to sample_size (Needed by .mov files
1804     //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1805     //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1806     //but I have no such movies
1807     if (sc->sample_size > 0) {
1808         int foundsize=0;
1809         for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1810             if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1811             {
1812                 foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
1813             }
1814             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);
1815         }
1816         if( (foundsize>0) && (foundsize<size) )
1817         {
1818             size=foundsize;
1819         }
1820     }
1821 #endif //MOV_MINOLTA_FIX
1822
1823     idx = sc->sample_to_chunk_index;
1824     if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1825         idx++;
1826     sc->sample_to_chunk_index = idx;
1827     /* split chunks into samples */
1828     if (sc->sample_size == 0 || sc->sample_size > 100) {
1829         if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1830             mov->partial = sc;
1831             /* we'll have to get those samples before next chunk */
1832             sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1833             size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1834         }
1835
1836         next_sample= sc->current_sample+1;
1837     }else if(idx < sc->sample_to_chunk_sz){
1838         next_sample= sc->current_sample + sc->sample_to_chunk[idx].count;
1839     }else
1840         next_sample= sc->current_sample;
1841
1842 readchunk:
1843     dprintf("chunk: %"PRId64" -> %"PRId64" (%i)\n", offset, offset + size, size);
1844     if(size == 0x0FFFFFFF)
1845         size = mov->mdat_size + mov->mdat_offset - offset;
1846     if(size < 0)
1847         return -1;
1848     if(size == 0)
1849         return -1;
1850     url_fseek(&s->pb, offset, SEEK_SET);
1851
1852     av_get_packet(&s->pb, pkt, size);
1853     pkt->stream_index = sc->ffindex;
1854
1855     // If the keyframes table exists, mark any samples that are in the table as key frames.
1856     // If no table exists, treat very sample as a key frame.
1857     if (sc->keyframes) {
1858         a = 0;
1859         b = sc->keyframe_count - 1;
1860
1861         while (a < b) {
1862             m = (a + b + 1) >> 1;
1863             if (sc->keyframes[m] > sc->current_sample) {
1864                 b = m - 1;
1865             } else {
1866                 a = m;
1867             }
1868         }
1869
1870         if (sc->keyframes[a] == sc->current_sample)
1871             pkt->flags |= PKT_FLAG_KEY;
1872     }
1873     else
1874         pkt->flags |= PKT_FLAG_KEY;
1875
1876     mov->next_chunk_offset = offset + size;
1877
1878     /* find the corresponding dts */
1879     if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1880       unsigned int count;
1881       uint64_t dts, pts;
1882       unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1883       count = sc->stts_data[sc->sample_to_time_index].count;
1884       if ((sc->sample_to_time_sample + count) <= sc->current_sample) {
1885         sc->sample_to_time_sample += count;
1886         sc->sample_to_time_time   += count*duration;
1887         sc->sample_to_time_index ++;
1888         duration = sc->stts_data[sc->sample_to_time_index].duration;
1889       }
1890       dts = sc->sample_to_time_time + (sc->current_sample - sc->sample_to_time_sample) * (int64_t)duration;
1891         /* find the corresponding pts */
1892         if (sc->sample_to_ctime_index < sc->ctts_count) {
1893             int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1894             int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1895
1896             if ((sc->sample_to_ctime_sample + count) <= sc->current_sample) {
1897                 sc->sample_to_ctime_sample += count;
1898                 sc->sample_to_ctime_index ++;
1899                 duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1900             }
1901             pts = dts + duration;
1902         }else
1903             pts = dts;
1904
1905         st= s->streams[ sc->ffindex ];
1906         assert(pts % st->time_base.num == 0);
1907         assert(dts % st->time_base.num == 0);
1908
1909         pkt->pts = pts / st->time_base.num;
1910         pkt->dts = dts / st->time_base.num;
1911         dprintf("stream #%d smp #%ld dts = %"PRId64" pts = %"PRId64" (smp:%ld time:%"PRId64" idx:%d ent:%d count:%d dur:%d)\n"
1912                 , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1913                 , sc->sample_to_time_sample
1914                 , sc->sample_to_time_time
1915                 , sc->sample_to_time_index
1916                 , sc->stts_count
1917                 , count
1918                 , duration);
1919     }
1920
1921     assert(next_sample>=0);
1922     sc->current_sample= next_sample;
1923
1924     return 0;
1925 }
1926
1927 #if defined(MOV_SEEK)
1928 /**
1929  * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1930  */
1931 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1932 {
1933     MOVContext* mov = (MOVContext *) s->priv_data;
1934     MOVStreamContext* sc;
1935     int32_t i, a, b, m;
1936     int64_t start_time;
1937     int32_t seek_sample, sample;
1938     int32_t duration;
1939     int32_t count;
1940     int32_t chunk;
1941     int32_t left_in_chunk;
1942     int64_t chunk_file_offset;
1943     int64_t sample_file_offset;
1944     int32_t first_chunk_sample;
1945     int32_t sample_to_chunk_idx;
1946     int sample_to_time_index;
1947     long sample_to_time_sample = 0;
1948     uint64_t sample_to_time_time = 0;
1949     int mov_idx;
1950
1951     // Find the corresponding mov stream
1952     for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1953         if (mov->streams[mov_idx]->ffindex == stream_index)
1954             break;
1955     if (mov_idx == mov->total_streams) {
1956         av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1957         return -1;
1958     }
1959     sc = mov->streams[mov_idx];
1960
1961     sample_time *= s->streams[stream_index]->time_base.num;
1962
1963     // Step 1. Find the edit that contains the requested time (elst)
1964     if (sc->edit_count && 0) {
1965         // FIXME should handle edit list
1966         av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
1967         return -1;
1968     }
1969
1970     // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */
1971     dprintf("Searching for time %li in stream #%i (time_scale=%i)\n", (long)sample_time, mov_idx, sc->time_scale);
1972     start_time = 0; // FIXME use elst atom
1973     sample = 1; // sample are 0 based in table
1974
1975     for (i = 0; i < sc->stts_count; i++) {
1976         count = sc->stts_data[i].count;
1977         duration = sc->stts_data[i].duration;
1978         if ((start_time + count*duration) > sample_time) {
1979             sample_to_time_time = start_time;
1980             sample_to_time_index = i;
1981             sample_to_time_sample = sample;
1982             sample += (sample_time - start_time) / duration;
1983             break;
1984         }
1985         sample += count;
1986         start_time += count * duration;
1987     }
1988     sample_to_time_time = start_time;
1989     sample_to_time_index = i;
1990     /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
1991        is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
1992
1993     dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
1994     if (sample > sc->sample_count) {
1995         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);
1996         return -1;
1997     }
1998
1999     // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
2000     if (sc->keyframes) {
2001         a = 0;
2002         b = sc->keyframe_count - 1;
2003         while (a < b) {
2004             m = (a + b + 1) >> 1;
2005             if (sc->keyframes[m] > sample) {
2006                 b = m - 1;
2007             } else {
2008                 a = m;
2009             }
2010         }
2011         // for low latency prob: always use the previous keyframe, just uncomment the next line
2012         // if (a) a--;
2013         seek_sample = sc->keyframes[a];
2014     }
2015     else
2016         seek_sample = sample; // else all samples are key frames
2017     dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
2018
2019     // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2020     for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2021         b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2022         if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2023             break;
2024         first_chunk_sample += b;
2025     }
2026     chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2027     left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2028     first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2029     sample_to_chunk_idx = i;
2030     dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2031
2032     // Step 5. Find the offset of the chunk using the chunk offset atom
2033     if (!sc->chunk_offsets) {
2034         av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2035         return -1;
2036     }
2037     if (chunk > sc->chunk_count) {
2038         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);
2039         return -1;
2040     }
2041     chunk_file_offset = sc->chunk_offsets[chunk - 1];
2042     dprintf("Chunk file offset is #%"PRIu64"\n", chunk_file_offset);
2043
2044     // Step 6. Find the byte offset within the chunk using the sample size atom
2045     sample_file_offset = chunk_file_offset;
2046     if (sc->sample_size)
2047         sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2048     else {
2049         for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2050         sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2051         }
2052     }
2053     dprintf("Sample file offset is #%"PRIu64"\n", sample_file_offset);
2054
2055     // Step 6. Update the parser
2056     mov->partial = sc;
2057     mov->next_chunk_offset = sample_file_offset;
2058     // Update current stream state
2059     sc->current_sample = seek_sample - 1;  // zero based
2060     sc->left_in_chunk = left_in_chunk;
2061     sc->next_chunk = chunk; // +1 -1 (zero based)
2062     sc->sample_to_chunk_index = sample_to_chunk_idx;
2063
2064     // Update other streams
2065     for (i = 0; i<mov->total_streams; i++) {
2066         MOVStreamContext *msc;
2067         if (i == mov_idx) continue;
2068         // Find the nearest 'next' chunk
2069         msc = mov->streams[i];
2070         a = 0;
2071         b = msc->chunk_count - 1;
2072         while (a < b) {
2073             m = (a + b + 1) >> 1;
2074             if (msc->chunk_offsets[m] > chunk_file_offset) {
2075                 b = m - 1;
2076             } else {
2077                 a = m;
2078             }
2079         }
2080         msc->next_chunk = a;
2081         if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2082             msc->next_chunk ++;
2083         dprintf("Nearest next chunk for stream #%i is #%li @%"PRId64"\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2084
2085         // Compute sample count and index in the sample_to_chunk table (what a pity)
2086         msc->sample_to_chunk_index = 0;
2087         msc->current_sample = 0;
2088         for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2089             && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2090             msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2091             * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2092         }
2093         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;
2094         msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2095         // Find corresponding position in stts (used later to compute dts)
2096         sample = 0;
2097         start_time = 0;
2098         for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2099             count = msc->stts_data[msc->sample_to_time_index].count;
2100             duration = msc->stts_data[msc->sample_to_time_index].duration;
2101             if ((sample + count - 1) > msc->current_sample) {
2102                 msc->sample_to_time_time = start_time;
2103                 msc->sample_to_time_sample = sample;
2104                 break;
2105             }
2106             sample += count;
2107             start_time += count * duration;
2108         }
2109         sample = 0;
2110         for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2111             count = msc->ctts_data[msc->sample_to_ctime_index].count;
2112             duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2113             if ((sample + count - 1) > msc->current_sample) {
2114                 msc->sample_to_ctime_sample = sample;
2115                 break;
2116             }
2117             sample += count;
2118         }
2119         dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2120     }
2121     return 0;
2122 }
2123 #endif
2124
2125 static int mov_read_close(AVFormatContext *s)
2126 {
2127     int i;
2128     MOVContext *mov = (MOVContext *) s->priv_data;
2129     for(i=0; i<mov->total_streams; i++)
2130         mov_free_stream_context(mov->streams[i]);
2131     /* free color tabs */
2132     for(i=0; i<mov->ctab_size; i++)
2133         av_freep(&mov->ctab[i]);
2134     av_freep(&mov->ctab);
2135     return 0;
2136 }
2137
2138 static AVInputFormat mov_iformat = {
2139     "mov,mp4,m4a,3gp,3g2,mj2",
2140     "QuickTime/MPEG4/Motion JPEG 2000 format",
2141     sizeof(MOVContext),
2142     mov_probe,
2143     mov_read_header,
2144     mov_read_packet,
2145     mov_read_close,
2146 #if defined(MOV_SEEK)
2147     mov_read_seek,
2148 #endif
2149 };
2150
2151 int mov_init(void)
2152 {
2153     av_register_input_format(&mov_iformat);
2154     return 0;
2155 }