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