simplify mov_read_hdlr 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         c->mp4 = 0;
522     else if(ctype == 0)
523         c->mp4 = 1;
524     if(type == MKTAG('v', 'i', 'd', 'e'))
525         st->codec->codec_type = CODEC_TYPE_VIDEO;
526     else if(type == MKTAG('s', 'o', 'u', 'n'))
527         st->codec->codec_type = CODEC_TYPE_AUDIO;
528     get_be32(pb); /* component  manufacture */
529     get_be32(pb); /* component flags */
530     get_be32(pb); /* component flags mask */
531
532     if(atom.size <= 24)
533         return 0; /* nothing left to read */
534     /* XXX: MP4 uses a C string, not a pascal one */
535     /* component name */
536
537     if(c->mp4) {
538         /* .mp4: C string */
539         while(get_byte(pb) && (++len < (atom.size - 24)));
540     } else {
541         /* .mov: PASCAL string */
542         len = get_byte(pb);
543         url_fskip(pb, len);
544     }
545
546     url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
547     return 0;
548 }
549
550 static int mov_mp4_read_descr_len(ByteIOContext *pb)
551 {
552     int len = 0;
553     int count = 4;
554     while (count--) {
555         int c = get_byte(pb);
556         len = (len << 7) | (c & 0x7f);
557         if (!(c & 0x80))
558             break;
559     }
560     return len;
561 }
562
563 static int mov_mp4_read_descr(ByteIOContext *pb, int *tag)
564 {
565     int len;
566     *tag = get_byte(pb);
567     len = mov_mp4_read_descr_len(pb);
568     dprintf("MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
569     return len;
570 }
571
572 static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
573 {
574     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
575     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
576     int64_t start_pos = url_ftell(pb);
577     int tag, len;
578
579     /* Well, broken but suffisant for some MP4 streams */
580     get_be32(pb); /* version + flags */
581     len = mov_mp4_read_descr(pb, &tag);
582     if (tag == MP4ESDescrTag) {
583         get_be16(pb); /* ID */
584         get_byte(pb); /* priority */
585     } else
586         get_be16(pb); /* ID */
587
588     len = mov_mp4_read_descr(pb, &tag);
589     if (tag == MP4DecConfigDescrTag) {
590         sc->esds.object_type_id = get_byte(pb);
591         sc->esds.stream_type = get_byte(pb);
592         sc->esds.buffer_size_db = get_be24(pb);
593         sc->esds.max_bitrate = get_be32(pb);
594         sc->esds.avg_bitrate = get_be32(pb);
595
596         st->codec->codec_id= codec_get_id(ff_mov_obj_type, sc->esds.object_type_id);
597         len = mov_mp4_read_descr(pb, &tag);
598         if (tag == MP4DecSpecificDescrTag) {
599             dprintf("Specific MPEG4 header len=%d\n", len);
600             st->codec->extradata = (uint8_t*) av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
601             if (st->codec->extradata) {
602                 get_buffer(pb, st->codec->extradata, len);
603                 st->codec->extradata_size = len;
604             }
605         }
606     }
607     /* in any case, skip garbage */
608     url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
609     return 0;
610 }
611
612 /* this atom contains actual media data */
613 static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
614 {
615     if(atom.size == 0) /* wrong one (MP4) */
616         return 0;
617     c->found_mdat=1;
618     c->mdat_offset = atom.offset;
619     c->mdat_size = atom.size;
620     if(c->found_moov)
621         return 1; /* found both, just go */
622     url_fskip(pb, atom.size);
623     return 0; /* now go for moov */
624 }
625
626 static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
627 {
628     uint32_t type = get_le32(pb);
629
630     /* from mplayer */
631     switch (type) {
632     case MKTAG('i', 's', 'o', 'm'):
633     case MKTAG('m', 'p', '4', '1'):
634     case MKTAG('m', 'p', '4', '2'):
635     case MKTAG('3', 'g', 'p', '1'):
636     case MKTAG('3', 'g', 'p', '2'):
637     case MKTAG('3', 'g', '2', 'a'):
638     case MKTAG('3', 'g', 'p', '3'):
639     case MKTAG('3', 'g', 'p', '4'):
640     case MKTAG('3', 'g', 'p', '5'):
641     case MKTAG('m', 'm', 'p', '4'): /* Mobile MP4 */
642     case MKTAG('M', '4', 'A', ' '): /* Apple iTunes AAC-LC Audio */
643     case MKTAG('M', '4', 'P', ' '): /* Apple iTunes AAC-LC Protected Audio */
644         c->mp4 = 1;
645     case MKTAG('q', 't', ' ', ' '):
646         av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
647     }
648     get_be32(pb); /* minor version */
649     url_fskip(pb, atom.size - 8);
650     return 0;
651 }
652
653 /* this atom should contain all header atoms */
654 static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
655 {
656     int err;
657
658     err = mov_read_default(c, pb, atom);
659     /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
660     /* so we don't parse the whole file if over a network */
661     c->found_moov=1;
662     if(c->found_mdat)
663         return 1; /* found both, just go */
664     return 0; /* now go for mdat */
665 }
666
667
668 static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
669 {
670     int version;
671     int lang;
672
673     version = get_byte(pb); /* version */
674     if (version > 1)
675         return 1; /* unsupported */
676
677     get_byte(pb); get_byte(pb);
678     get_byte(pb); /* flags */
679
680     (version==1)?get_be64(pb):get_be32(pb); /* creation time */
681     (version==1)?get_be64(pb):get_be32(pb); /* modification time */
682
683     c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb);
684     c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
685
686     lang = get_be16(pb); /* language */
687     ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
688     get_be16(pb); /* quality */
689
690     return 0;
691 }
692
693 static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
694 {
695     get_byte(pb); /* version */
696     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
697
698     get_be32(pb); /* creation time */
699     get_be32(pb); /* modification time */
700     c->time_scale = get_be32(pb); /* time scale */
701 #ifdef DEBUG
702     av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);
703 #endif
704     c->duration = get_be32(pb); /* duration */
705     get_be32(pb); /* preferred scale */
706
707     get_be16(pb); /* preferred volume */
708
709     url_fskip(pb, 10); /* reserved */
710
711     url_fskip(pb, 36); /* display matrix */
712
713     get_be32(pb); /* preview time */
714     get_be32(pb); /* preview duration */
715     get_be32(pb); /* poster time */
716     get_be32(pb); /* selection time */
717     get_be32(pb); /* selection duration */
718     get_be32(pb); /* current time */
719     get_be32(pb); /* next track ID */
720
721     return 0;
722 }
723
724 static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
725 {
726     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
727
728     if((uint64_t)atom.size > (1<<30))
729         return -1;
730
731     // currently SVQ3 decoder expect full STSD header - so let's fake it
732     // this should be fixed and just SMI header should be passed
733     av_free(st->codec->extradata);
734     st->codec->extradata_size = 0x5a + atom.size;
735     st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
736
737     if (st->codec->extradata) {
738         strcpy(st->codec->extradata, "SVQ3"); // fake
739         get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
740         dprintf("Reading SMI %Ld  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
741     } else
742         url_fskip(pb, atom.size);
743
744     return 0;
745 }
746
747 static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
748 {
749     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
750
751     if((uint64_t)atom.size > (1<<30))
752         return -1;
753
754     if (st->codec->codec_id == CODEC_ID_QDM2) {
755         // pass all frma atom to codec, needed at least for QDM2
756         av_free(st->codec->extradata);
757         st->codec->extradata_size = atom.size;
758         st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
759
760         if (st->codec->extradata) {
761             get_buffer(pb, st->codec->extradata, atom.size);
762         } else
763             url_fskip(pb, atom.size);
764     } else if (atom.size > 8) { /* to read frma, esds atoms */
765         mov_read_default(c, pb, atom);
766     } else if (atom.size > 0)
767         url_fskip(pb, atom.size);
768     return 0;
769 }
770
771 static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
772 {
773     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
774
775     if((uint64_t)atom.size > (1<<30))
776         return -1;
777
778     av_free(st->codec->extradata);
779
780     st->codec->extradata_size = atom.size;
781     st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
782
783     if (st->codec->extradata) {
784         get_buffer(pb, st->codec->extradata, atom.size);
785     } else
786         url_fskip(pb, atom.size);
787
788     return 0;
789 }
790
791 static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
792 {
793     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
794     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
795     unsigned int i, entries;
796
797     get_byte(pb); /* version */
798     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
799
800     entries = get_be32(pb);
801
802     if(entries >= UINT_MAX/sizeof(int64_t))
803         return -1;
804
805     sc->chunk_count = entries;
806     sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t));
807     if (!sc->chunk_offsets)
808         return -1;
809     if (atom.type == MKTAG('s', 't', 'c', 'o')) {
810         for(i=0; i<entries; i++) {
811             sc->chunk_offsets[i] = get_be32(pb);
812         }
813     } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
814         for(i=0; i<entries; i++) {
815             sc->chunk_offsets[i] = get_be64(pb);
816         }
817     } else
818         return -1;
819
820     for(i=0; i<c->fc->nb_streams; i++){
821         MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
822         if(sc2 && sc2->chunk_offsets){
823             int64_t first= sc2->chunk_offsets[0];
824             int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
825             if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
826                 c->ni=1;
827         }
828     }
829     return 0;
830 }
831
832 static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
833 {
834     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
835     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
836     int entries, frames_per_sample;
837     uint32_t format;
838     uint8_t codec_name[32];
839
840     /* for palette traversal */
841     int color_depth;
842     int color_start;
843     int color_count;
844     int color_end;
845     int color_index;
846     int color_dec;
847     int color_greyscale;
848     unsigned char *color_table;
849     int j;
850     unsigned char r, g, b;
851
852     get_byte(pb); /* version */
853     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
854
855     entries = get_be32(pb);
856
857     while(entries--) { //Parsing Sample description table
858         enum CodecID id;
859         offset_t start_pos = url_ftell(pb);
860         int size = get_be32(pb); /* size */
861         format = get_le32(pb); /* data format */
862
863         get_be32(pb); /* reserved */
864         get_be16(pb); /* reserved */
865         get_be16(pb); /* index */
866
867         /* for MPEG4: set codec type by looking for it */
868         id = codec_get_id(mov_video_tags, format);
869         if(id <= 0)
870             id = codec_get_id(codec_bmp_tags, format);
871         if (id >= 0) {
872             AVCodec *codec;
873             codec = avcodec_find_decoder(id);
874             if (codec)
875                 st->codec->codec_type = codec->type;
876         }
877         dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
878                 size,
879                 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
880                 st->codec->codec_type);
881         st->codec->codec_tag = format;
882         if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
883             MOV_atom_t a = { 0, 0, 0 };
884             st->codec->codec_id = id;
885             get_be16(pb); /* version */
886             get_be16(pb); /* revision level */
887             get_be32(pb); /* vendor */
888             get_be32(pb); /* temporal quality */
889             get_be32(pb); /* spacial quality */
890             if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
891                 get_be16(pb);
892                 get_be16(pb);
893             }else{
894                 st->codec->width = get_be16(pb); /* width */
895                 st->codec->height = get_be16(pb); /* height */
896             }
897             get_be32(pb); /* horiz resolution */
898             get_be32(pb); /* vert resolution */
899             get_be32(pb); /* data size, always 0 */
900             frames_per_sample = get_be16(pb); /* frames per samples */
901 #ifdef DEBUG
902             av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
903 #endif
904         get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
905         if (codec_name[0] <= 31) {
906             memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
907             st->codec->codec_name[codec_name[0]] = 0;
908         }
909
910             st->codec->bits_per_sample = get_be16(pb); /* depth */
911             st->codec->color_table_id = get_be16(pb); /* colortable id */
912
913 /*          These are set in mov_read_stts and might already be set!
914             st->codec->time_base.den      = 25;
915             st->codec->time_base.num = 1;
916 */
917
918             /* figure out the palette situation */
919             color_depth = st->codec->bits_per_sample & 0x1F;
920             color_greyscale = st->codec->bits_per_sample & 0x20;
921
922             /* if the depth is 2, 4, or 8 bpp, file is palettized */
923             if ((color_depth == 2) || (color_depth == 4) ||
924                 (color_depth == 8)) {
925
926                 if (color_greyscale) {
927
928                     /* compute the greyscale palette */
929                     color_count = 1 << color_depth;
930                     color_index = 255;
931                     color_dec = 256 / (color_count - 1);
932                     for (j = 0; j < color_count; j++) {
933                         r = g = b = color_index;
934                         c->palette_control.palette[j] =
935                             (r << 16) | (g << 8) | (b);
936                         color_index -= color_dec;
937                         if (color_index < 0)
938                             color_index = 0;
939                     }
940
941                 } else if (st->codec->color_table_id & 0x08) {
942
943                     /* if flag bit 3 is set, use the default palette */
944                     color_count = 1 << color_depth;
945                     if (color_depth == 2)
946                         color_table = ff_qt_default_palette_4;
947                     else if (color_depth == 4)
948                         color_table = ff_qt_default_palette_16;
949                     else
950                         color_table = ff_qt_default_palette_256;
951
952                     for (j = 0; j < color_count; j++) {
953                         r = color_table[j * 4 + 0];
954                         g = color_table[j * 4 + 1];
955                         b = color_table[j * 4 + 2];
956                         c->palette_control.palette[j] =
957                             (r << 16) | (g << 8) | (b);
958                     }
959
960                 } else {
961
962                     /* load the palette from the file */
963                     color_start = get_be32(pb);
964                     color_count = get_be16(pb);
965                     color_end = get_be16(pb);
966                     for (j = color_start; j <= color_end; j++) {
967                         /* each R, G, or B component is 16 bits;
968                          * only use the top 8 bits; skip alpha bytes
969                          * up front */
970                         get_byte(pb);
971                         get_byte(pb);
972                         r = get_byte(pb);
973                         get_byte(pb);
974                         g = get_byte(pb);
975                         get_byte(pb);
976                         b = get_byte(pb);
977                         get_byte(pb);
978                         c->palette_control.palette[j] =
979                             (r << 16) | (g << 8) | (b);
980                     }
981                 }
982
983                 st->codec->palctrl = &c->palette_control;
984                 st->codec->palctrl->palette_changed = 1;
985             } else
986                 st->codec->palctrl = NULL;
987
988             a.size = size - (url_ftell(pb) - start_pos);
989             if (a.size > 8)
990                 mov_read_default(c, pb, a);
991             else if (a.size > 0)
992                 url_fskip(pb, a.size);
993         } else {
994             st->codec->codec_id = codec_get_id(mov_audio_tags, format);
995             if(st->codec->codec_id==CODEC_ID_AMR_NB || st->codec->codec_id==CODEC_ID_AMR_WB) //from TS26.244
996             {
997                dprintf("AMR audio identified %d!!\n", st->codec->codec_id);
998                get_be32(pb);get_be32(pb); //Reserved_8
999                get_be16(pb);//Reserved_2
1000                get_be16(pb);//Reserved_2
1001                get_be32(pb);//Reserved_4
1002                get_be16(pb);//TimeScale
1003                get_be16(pb);//Reserved_2
1004
1005                 //AMRSpecificBox.(10 bytes)
1006
1007                get_be32(pb); //size
1008                get_be32(pb); //type=='damr'
1009                get_be32(pb); //vendor
1010                get_byte(pb); //decoder version
1011                get_be16(pb); //mode_set
1012                get_byte(pb); //mode_change_period
1013                get_byte(pb); //frames_per_sample
1014
1015                st->duration = AV_NOPTS_VALUE;//Not possible to get from this info, must count number of AMR frames
1016                if(st->codec->codec_id==CODEC_ID_AMR_NB)
1017                {
1018                    st->codec->sample_rate=8000;
1019                    st->codec->channels=1;
1020                }
1021                else //AMR-WB
1022                {
1023                    st->codec->sample_rate=16000;
1024                    st->codec->channels=1;
1025                }
1026                st->codec->bits_per_sample=16;
1027                st->codec->bit_rate=0; /*It is not possible to tell this before we have
1028                                        an audio frame and even then every frame can be different*/
1029             }
1030             else if( st->codec->codec_tag == MKTAG( 'm', 'p', '4', 's' ))
1031             {
1032                 //This is some stuff for the hint track, lets ignore it!
1033                 //Do some mp4 auto detect.
1034                 c->mp4=1;
1035                 size-=(16);
1036                 url_fskip(pb, size); /* The mp4s atom also contians a esds atom that we can skip*/
1037             }
1038             else if( st->codec->codec_tag == MKTAG( 'm', 'p', '4', 'a' ))
1039             {
1040                 MOV_atom_t a;
1041                 int mp4_version;
1042
1043                 /* Handle mp4 audio tag */
1044                 mp4_version=get_be16(pb);/*version*/
1045                 get_be16(pb); /*revesion*/
1046                 get_be32(pb);
1047                 st->codec->channels = get_be16(pb); /* channels */
1048                 st->codec->bits_per_sample = get_be16(pb); /* bits per sample */
1049                 get_be32(pb);
1050                 st->codec->sample_rate = get_be16(pb); /* sample rate, not always correct */
1051                 if(st->codec->sample_rate == 1) //nonsese rate? -> ignore
1052                     st->codec->sample_rate= 0;
1053
1054                 get_be16(pb);
1055                 c->mp4=1;
1056
1057                 if(mp4_version==1)
1058                 {
1059                     url_fskip(pb,16);
1060                     a.size=size-(16+20+16);
1061                 }
1062                 else
1063                     a.size=size-(16+20);
1064
1065                 a.offset=url_ftell(pb);
1066
1067                 mov_read_default(c, pb, a);
1068
1069                 /* Get correct sample rate from extradata */
1070                 if(st->codec->extradata_size) {
1071                    const int samplerate_table[] = {
1072                      96000, 88200, 64000, 48000, 44100, 32000,
1073                      24000, 22050, 16000, 12000, 11025, 8000,
1074                      7350, 0, 0, 0
1075                    };
1076                    unsigned char *px = st->codec->extradata;
1077                    // 5 bits objectTypeIndex, 4 bits sampleRateIndex, 4 bits channels
1078                    int samplerate_index = ((px[0] & 7) << 1) + ((px[1] >> 7) & 1);
1079                    st->codec->sample_rate = samplerate_table[samplerate_index];
1080                    st->codec->channels = (px[1] >> 3) & 15;
1081                 }
1082             }
1083             else if( st->codec->codec_tag == MKTAG( 'a', 'l', 'a', 'c' ))
1084             {
1085                 /* Handle alac audio tag + special extradata */
1086                 get_be32(pb); /* version */
1087                 get_be32(pb);
1088                 st->codec->channels = get_be16(pb); /* channels */
1089                 st->codec->bits_per_sample = get_be16(pb); /* bits per sample */
1090                 get_be32(pb);
1091                 st->codec->sample_rate = get_be16(pb);
1092                 get_be16(pb);
1093
1094                 /* fetch the 36-byte extradata needed for alac decoding */
1095                 st->codec->extradata_size = 36;
1096                 st->codec->extradata = (uint8_t*)
1097                     av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
1098                 get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
1099             }
1100             else if(size>=(16+20))
1101             {//16 bytes read, reading atleast 20 more
1102                 uint16_t version;
1103                 version = get_be16(pb); /* version */
1104                 get_be16(pb); /* revision level */
1105                 get_be32(pb); /* vendor */
1106
1107                 st->codec->channels = get_be16(pb);             /* channel count */
1108                 st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1109
1110                 /* handle specific s8 codec */
1111                 get_be16(pb); /* compression id = 0*/
1112                 get_be16(pb); /* packet size = 0 */
1113
1114                 st->codec->sample_rate = ((get_be32(pb) >> 16));
1115
1116                 switch (st->codec->codec_id) {
1117                 case CODEC_ID_PCM_S16BE:
1118                     if (st->codec->bits_per_sample == 8)
1119                         st->codec->codec_id = CODEC_ID_PCM_S8;
1120                     /* fall */
1121                 case CODEC_ID_PCM_U8:
1122                     st->codec->bit_rate = st->codec->sample_rate * 8;
1123                     break;
1124                 default:
1125                     ;
1126                 }
1127
1128                 //Read QT version 1 fields. In version 0 theese dont exist
1129                 dprintf("version =%d mp4=%d\n",version,c->mp4);
1130                 if((version==1) && size>=(16+20+16))
1131                 {
1132                     get_be32(pb); /* samples per packet */
1133                     get_be32(pb); /* bytes per packet */
1134                     get_be32(pb); /* bytes per frame */
1135                     get_be32(pb); /* bytes per sample */
1136                     if(size>(16+20+16))
1137                     {
1138                         //Optional, additional atom-based fields
1139                         MOV_atom_t a = { format, url_ftell(pb), size - (16 + 20 + 16 + 8) };
1140                         mov_read_default(c, pb, a);
1141                     }
1142                 }
1143                 else
1144                 {
1145                     //We should be down to 0 bytes here, but lets make sure.
1146                     size-=(16+20);
1147                     if(size>0) {
1148                         dprintf("skipping 0x%X bytes\n",size-(16+20));
1149                         url_fskip(pb, size);
1150                     }
1151                 }
1152             }
1153             else
1154             {
1155                 size-=16;
1156                 //Unknown size, but lets do our best and skip the rest.
1157                 dprintf("Strange size, skipping 0x%X bytes\n",size);
1158                 url_fskip(pb, size);
1159             }
1160         }
1161     }
1162
1163     if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1164         st->codec->sample_rate= sc->time_scale;
1165     }
1166
1167     return 0;
1168 }
1169
1170 static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1171 {
1172     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1173     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1174     unsigned int i, entries;
1175
1176     get_byte(pb); /* version */
1177     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1178
1179     entries = get_be32(pb);
1180
1181     if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1182         return -1;
1183
1184 #ifdef DEBUG
1185 av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1186 #endif
1187     sc->sample_to_chunk_sz = entries;
1188     sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1189     if (!sc->sample_to_chunk)
1190         return -1;
1191     for(i=0; i<entries; i++) {
1192         sc->sample_to_chunk[i].first = get_be32(pb);
1193         sc->sample_to_chunk[i].count = get_be32(pb);
1194         sc->sample_to_chunk[i].id = get_be32(pb);
1195     }
1196     return 0;
1197 }
1198
1199 static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1200 {
1201     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1202     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1203     unsigned int i, entries;
1204
1205     get_byte(pb); /* version */
1206     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1207
1208     entries = get_be32(pb);
1209
1210     if(entries >= UINT_MAX / sizeof(long))
1211         return -1;
1212
1213     sc->keyframe_count = entries;
1214 #ifdef DEBUG
1215     av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1216 #endif
1217     sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1218     if (!sc->keyframes)
1219         return -1;
1220     for(i=0; i<entries; i++) {
1221         sc->keyframes[i] = get_be32(pb);
1222 #ifdef DEBUG
1223 /*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1224 #endif
1225     }
1226     return 0;
1227 }
1228
1229 static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1230 {
1231     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1232     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1233     unsigned int i, entries;
1234
1235     get_byte(pb); /* version */
1236     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1237
1238     sc->sample_size = get_be32(pb);
1239     entries = get_be32(pb);
1240     if(entries >= UINT_MAX / sizeof(long))
1241         return -1;
1242
1243     sc->sample_count = entries;
1244 #ifdef DEBUG
1245     av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1246 #endif
1247     if(sc->sample_size)
1248         return 0; /* there isn't any table following */
1249     sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1250     if (!sc->sample_sizes)
1251         return -1;
1252     for(i=0; i<entries; i++) {
1253         sc->sample_sizes[i] = get_be32(pb);
1254 #ifdef DEBUG
1255         av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1256 #endif
1257     }
1258     return 0;
1259 }
1260
1261 static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1262 {
1263     AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1264     MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1265     unsigned int i, entries;
1266     int64_t duration=0;
1267     int64_t total_sample_count=0;
1268
1269     get_byte(pb); /* version */
1270     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1271     entries = get_be32(pb);
1272     if(entries >= UINT_MAX / sizeof(Time2Sample))
1273         return -1;
1274
1275     sc->stts_count = entries;
1276     sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1277
1278 #ifdef DEBUG
1279 av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1280 #endif
1281
1282     sc->time_rate=0;
1283
1284     for(i=0; i<entries; i++) {
1285         int sample_duration;
1286         int sample_count;
1287
1288         sample_count=get_be32(pb);
1289         sample_duration = get_be32(pb);
1290         sc->stts_data[i].count= sample_count;
1291         sc->stts_data[i].duration= sample_duration;
1292
1293         sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1294
1295         dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1296
1297         duration+=sample_duration*sample_count;
1298         total_sample_count+=sample_count;
1299     }
1300
1301     st->nb_frames= total_sample_count;
1302     if(duration)
1303         st->duration= duration;
1304     return 0;
1305 }
1306
1307 static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1308 {
1309     unsigned int i, entries;
1310
1311     get_byte(pb); /* version */
1312     get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1313     entries = get_be32(pb);
1314     if(entries >= UINT_MAX / sizeof(Time2Sample))
1315         return -1;
1316
1317     c->streams[c->fc->nb_streams-1]->ctts_count = entries;
1318     c->streams[c->fc->nb_streams-1]->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1319
1320     dprintf("track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
1321
1322     for(i=0; i<entries; i++) {
1323         c->streams[c->fc->nb_streams - 1]->ctts_data[i].count= get_be32(pb);
1324         c->streams[c->fc->nb_streams - 1]->ctts_data[i].duration= get_be32(pb);
1325     }
1326     return 0;
1327 }
1328
1329 static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1330 {
1331     AVStream *st;
1332     MOVStreamContext *sc;
1333
1334     st = av_new_stream(c->fc, c->fc->nb_streams);
1335     if (!st) return -2;
1336     sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1337     if (!sc) {
1338         av_free(st);
1339         return -1;
1340     }
1341
1342     sc->sample_to_chunk_index = -1;
1343     st->priv_data = sc;
1344     st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1345     st->start_time = 0; /* XXX: check */
1346     c->streams[c->fc->nb_streams-1] = sc;
1347
1348     return mov_read_default(c, pb, atom);
1349 }
1350
1351 static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1352 {
1353     AVStream *st;
1354
1355     st = c->fc->streams[c->fc->nb_streams-1];
1356
1357     get_byte(pb); /* version */
1358
1359     get_byte(pb); get_byte(pb);
1360     get_byte(pb); /* flags */
1361     /*
1362     MOV_TRACK_ENABLED 0x0001
1363     MOV_TRACK_IN_MOVIE 0x0002
1364     MOV_TRACK_IN_PREVIEW 0x0004
1365     MOV_TRACK_IN_POSTER 0x0008
1366     */
1367
1368     get_be32(pb); /* creation time */
1369     get_be32(pb); /* modification time */
1370     st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1371     get_be32(pb); /* reserved */
1372     st->start_time = 0; /* check */
1373     get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1374     get_be32(pb); /* reserved */
1375     get_be32(pb); /* reserved */
1376
1377     get_be16(pb); /* layer */
1378     get_be16(pb); /* alternate group */
1379     get_be16(pb); /* volume */
1380     get_be16(pb); /* reserved */
1381
1382     url_fskip(pb, 36); /* display matrix */
1383
1384     /* those are fixed-point */
1385     /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1386     /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1387
1388     return 0;
1389 }
1390
1391 /* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1392 /* like the files created with Adobe Premiere 5.0, for samples see */
1393 /* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1394 static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1395 {
1396     int err;
1397
1398     if (atom.size < 8)
1399         return 0; /* continue */
1400     if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1401         url_fskip(pb, atom.size - 4);
1402         return 0;
1403     }
1404     atom.type = get_le32(pb);
1405     atom.offset += 8;
1406     atom.size -= 8;
1407     if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1408         url_fskip(pb, atom.size);
1409         return 0;
1410     }
1411     err = mov_read_mdat(c, pb, atom);
1412     return err;
1413 }
1414
1415
1416 #ifdef CONFIG_ZLIB
1417 static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1418 {
1419     return -1;
1420 }
1421
1422 static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1423 {
1424     ByteIOContext ctx;
1425     uint8_t *cmov_data;
1426     uint8_t *moov_data; /* uncompressed data */
1427     long cmov_len, moov_len;
1428     int ret;
1429
1430     get_be32(pb); /* dcom atom */
1431     if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1432         return -1;
1433     if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1434         av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
1435         return -1;
1436     }
1437     get_be32(pb); /* cmvd atom */
1438     if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1439         return -1;
1440     moov_len = get_be32(pb); /* uncompressed size */
1441     cmov_len = atom.size - 6 * 4;
1442
1443     cmov_data = (uint8_t *) av_malloc(cmov_len);
1444     if (!cmov_data)
1445         return -1;
1446     moov_data = (uint8_t *) av_malloc(moov_len);
1447     if (!moov_data) {
1448         av_free(cmov_data);
1449         return -1;
1450     }
1451     get_buffer(pb, cmov_data, cmov_len);
1452     if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1453         return -1;
1454     if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1455         return -1;
1456     ctx.buf_end = ctx.buffer + moov_len;
1457     atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1458     atom.offset = 0;
1459     atom.size = moov_len;
1460 #ifdef DEBUG
1461 //    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1462 #endif
1463     ret = mov_read_default(c, &ctx, atom);
1464     av_free(moov_data);
1465     av_free(cmov_data);
1466
1467     return ret;
1468 }
1469 #endif
1470
1471 /* edit list atom */
1472 static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1473 {
1474   int i, edit_count;
1475
1476   get_byte(pb); /* version */
1477   get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1478   edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1479
1480   for(i=0; i<edit_count; i++){
1481     get_be32(pb); /* Track duration */
1482     get_be32(pb); /* Media time */
1483     get_be32(pb); /* Media rate */
1484   }
1485   dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1486   return 0;
1487 }
1488
1489 static const MOVParseTableEntry mov_default_parse_table[] = {
1490 /* mp4 atoms */
1491 { MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1492 { MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1493 { MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1494 { MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1495 { MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1496 { MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1497 { MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1498 { MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1499 { MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1500 { MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1501 { MKTAG( 'f', 't', 'y', 'p' ), mov_read_ftyp },
1502 { MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1503 { MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1504 { MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1505 { MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
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', 'v', 'c', 'C' ), mov_read_avcC },
1523 { MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1524 { MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1525 { MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1526 { MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1527 { MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1528 { MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1529 { MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1530 { MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1531 { MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1532 { MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1533 { MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1534 { MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1535 { MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1536 { MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1537 { MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1538 { MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1539 { MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1540 { MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1541 /* extra mp4 */
1542 { MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1543 /* QT atoms */
1544 { MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1545 { MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1546 { MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1547 { MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1548 { MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1549 { MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1550 { MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1551 { MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1552 { MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1553 { MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1554 { MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1555 { MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1556 { MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1557 { MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1558 { MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1559 { MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1560 //{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1561 #ifdef CONFIG_ZLIB
1562 { MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1563 #else
1564 { MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1565 #endif
1566 { 0L, mov_read_leaf }
1567 };
1568
1569 static void mov_free_stream_context(MOVStreamContext *sc)
1570 {
1571     if(sc) {
1572         av_freep(&sc->chunk_offsets);
1573         av_freep(&sc->sample_to_chunk);
1574         av_freep(&sc->sample_sizes);
1575         av_freep(&sc->keyframes);
1576         av_freep(&sc->stts_data);
1577         av_freep(&sc->ctts_data);
1578         av_freep(&sc);
1579     }
1580 }
1581
1582 static inline uint32_t mov_to_tag(uint8_t *buf)
1583 {
1584     return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1585 }
1586
1587 static inline uint32_t to_be32(uint8_t *buf)
1588 {
1589     return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1590 }
1591
1592 /* XXX: is it sufficient ? */
1593 static int mov_probe(AVProbeData *p)
1594 {
1595     unsigned int offset;
1596     uint32_t tag;
1597     int score = 0;
1598
1599     /* check file header */
1600     if (p->buf_size <= 12)
1601         return 0;
1602     offset = 0;
1603     for(;;) {
1604         /* ignore invalid offset */
1605         if ((offset + 8) > (unsigned int)p->buf_size)
1606             return score;
1607         tag = mov_to_tag(p->buf + offset + 4);
1608         switch(tag) {
1609         /* check for obvious tags */
1610         case MKTAG( 'm', 'o', 'o', 'v' ):
1611         case MKTAG( 'm', 'd', 'a', 't' ):
1612         case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1613         case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1614             return AVPROBE_SCORE_MAX;
1615         /* those are more common words, so rate then a bit less */
1616         case MKTAG( 'w', 'i', 'd', 'e' ):
1617         case MKTAG( 'f', 'r', 'e', 'e' ):
1618         case MKTAG( 'j', 'u', 'n', 'k' ):
1619         case MKTAG( 'p', 'i', 'c', 't' ):
1620             return AVPROBE_SCORE_MAX - 5;
1621         case MKTAG( 'f', 't', 'y', 'p' ):
1622         case MKTAG( 's', 'k', 'i', 'p' ):
1623         case MKTAG( 'u', 'u', 'i', 'd' ):
1624             offset = to_be32(p->buf+offset) + offset;
1625             /* if we only find those cause probedata is too small at least rate them */
1626             score = AVPROBE_SCORE_MAX - 50;
1627             break;
1628         default:
1629             /* unrecognized tag */
1630             return score;
1631         }
1632     }
1633     return score;
1634 }
1635
1636 static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1637 {
1638     MOVContext *mov = (MOVContext *) s->priv_data;
1639     ByteIOContext *pb = &s->pb;
1640     int i, j, nb, err;
1641     MOV_atom_t atom = { 0, 0, 0 };
1642
1643     mov->fc = s;
1644     mov->parse_table = mov_default_parse_table;
1645
1646     if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1647         atom.size = url_fsize(pb);
1648     else
1649         atom.size = 0x7FFFFFFFFFFFFFFFLL;
1650
1651     /* check MOV header */
1652     err = mov_read_default(mov, pb, atom);
1653     if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1654         av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1655                 err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1656         return -1;
1657     }
1658     dprintf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1659
1660     /* some cleanup : make sure we are on the mdat atom */
1661     if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1662         url_fseek(pb, mov->mdat_offset, SEEK_SET);
1663
1664     mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1665     mov->total_streams = nb = s->nb_streams;
1666
1667 #if 1
1668     for(i=0; i<s->nb_streams;) {
1669         if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1670             av_free(s->streams[i]);
1671             for(j=i+1; j<s->nb_streams; j++)
1672                 s->streams[j-1] = s->streams[j];
1673             s->nb_streams--;
1674         } else
1675             i++;
1676     }
1677     for(i=0; i<s->nb_streams;i++) {
1678         MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
1679
1680         if(!sc->time_rate)
1681             sc->time_rate=1;
1682         av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1683
1684         if(s->streams[i]->duration != AV_NOPTS_VALUE){
1685             assert(s->streams[i]->duration % sc->time_rate == 0);
1686             s->streams[i]->duration /= sc->time_rate;
1687         }
1688
1689         sc->ffindex = i;
1690         sc->is_ff_stream = 1;
1691     }
1692 #endif
1693     return 0;
1694 }
1695
1696 /* Yes, this is ugly... I didn't write the specs of QT :p */
1697 /* XXX:remove useless commented code sometime */
1698 static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1699 {
1700     MOVContext *mov = (MOVContext *) s->priv_data;
1701     MOVStreamContext *sc;
1702     AVStream *st;
1703     int64_t offset = INT64_MAX;
1704     int64_t best_dts = INT64_MAX;
1705     int i, a, b, m;
1706     int size;
1707     int idx;
1708     size = 0x0FFFFFFF;
1709
1710     if (mov->partial) {
1711         sc = mov->partial;
1712         idx = sc->sample_to_chunk_index;
1713
1714         if (idx < 0) return 0;
1715         dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1716         //size = sc->sample_sizes[sc->current_sample];
1717         // that ain't working...
1718         //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1719         size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1720
1721         sc->current_sample++;
1722         sc->left_in_chunk--;
1723
1724         if (sc->left_in_chunk <= 0)
1725             mov->partial = 0;
1726         offset = mov->next_chunk_offset;
1727         /* extract the sample */
1728
1729         goto readchunk;
1730     }
1731
1732 again:
1733     sc = 0;
1734     if(offset == INT64_MAX)
1735         best_dts= INT64_MAX;
1736     for(i=0; i<mov->total_streams; i++) {
1737         MOVStreamContext *msc = mov->streams[i];
1738
1739         if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1740             if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1741                 int64_t dts;
1742                 int index= msc->sample_to_time_index;
1743                 int sample= msc->sample_to_time_sample;
1744                 int time= msc->sample_to_time_time;
1745                 int duration = msc->stts_data[index].duration;
1746                 int count = msc->stts_data[index].count;
1747                 if (sample + count < msc->current_sample) {
1748                     sample += count;
1749                     time   += count*duration;
1750                     index ++;
1751                     duration = msc->stts_data[index].duration;
1752                 }
1753                 dts = time + (msc->current_sample-1 - sample) * (int64_t)duration;
1754                 dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1755                 dprintf("stream: %d dts: %Ld best_dts: %Ld offset: %Ld \n", i, dts, best_dts, offset);
1756                 if(dts < best_dts){
1757                     best_dts= dts;
1758                     sc = msc;
1759                     offset = msc->chunk_offsets[msc->next_chunk];
1760                 }
1761             }else{
1762                 if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1763                     sc = msc;
1764                     offset = msc->chunk_offsets[msc->next_chunk];
1765                 }
1766             }
1767         }
1768     }
1769     if (!sc || offset==INT64_MAX)
1770         return -1;
1771
1772     sc->next_chunk++;
1773
1774     if(mov->next_chunk_offset < offset) { /* some meta data */
1775         url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1776         mov->next_chunk_offset = offset;
1777     }
1778
1779     if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1780         url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1781         mov->next_chunk_offset = offset;
1782         offset = INT64_MAX;
1783         goto again;
1784     }
1785
1786     /* now get the chunk size... */
1787
1788     for(i=0; i<mov->total_streams; i++) {
1789         MOVStreamContext *msc = mov->streams[i];
1790         if ((msc->next_chunk < msc->chunk_count)
1791             && msc->chunk_offsets[msc->next_chunk] - offset < size
1792             && msc->chunk_offsets[msc->next_chunk] > offset)
1793             size = msc->chunk_offsets[msc->next_chunk] - offset;
1794     }
1795
1796 #ifdef MOV_MINOLTA_FIX
1797     //Make sure that size is according to sample_size (Needed by .mov files
1798     //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1799     //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1800     //but I have no such movies
1801     if (sc->sample_size > 0) {
1802         int foundsize=0;
1803         for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1804             if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1805             {
1806                 // I can't figure out why for PCM audio sample_size is always 1
1807                 // (it should actually be channels*bits_per_second/8) but it is.
1808                 AVCodecContext* cod = s->streams[sc->ffindex]->codec;
1809                 if (sc->sample_size == 1 && (cod->codec_id == CODEC_ID_PCM_S16BE || cod->codec_id == CODEC_ID_PCM_S16LE))
1810                     foundsize=(sc->sample_to_chunk[i].count*cod->channels*cod->bits_per_sample)/8;
1811                 else
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         sc->current_sample++;
1837     }else if(idx + 1 < sc->sample_to_chunk_sz){
1838         sc->current_sample += sc->sample_size * sc->sample_to_chunk[idx].count;
1839     }
1840
1841 readchunk:
1842     dprintf("chunk: %lli -> %lli (%i)\n", offset, offset + size, size);
1843     if(size == 0x0FFFFFFF)
1844         size = mov->mdat_size + mov->mdat_offset - offset;
1845     if(size < 0)
1846         return -1;
1847     if(size == 0)
1848         return -1;
1849     url_fseek(&s->pb, offset, SEEK_SET);
1850
1851     av_get_packet(&s->pb, pkt, size);
1852     pkt->stream_index = sc->ffindex;
1853
1854     // If the keyframes table exists, mark any samples that are in the table as key frames.
1855     // If no table exists, treat very sample as a key frame.
1856     if (sc->keyframes) {
1857         a = 0;
1858         b = sc->keyframe_count - 1;
1859
1860         while (a < b) {
1861             m = (a + b + 1) >> 1;
1862             if (sc->keyframes[m] > sc->current_sample) {
1863                 b = m - 1;
1864             } else {
1865                 a = m;
1866             }
1867         }
1868
1869         if (sc->keyframes[a] == sc->current_sample)
1870             pkt->flags |= PKT_FLAG_KEY;
1871     }
1872     else
1873         pkt->flags |= PKT_FLAG_KEY;
1874
1875     mov->next_chunk_offset = offset + size;
1876
1877     /* find the corresponding dts */
1878     if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1879       unsigned int count;
1880       uint64_t dts, pts;
1881       unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1882       count = sc->stts_data[sc->sample_to_time_index].count;
1883       if ((sc->sample_to_time_sample + count) < sc->current_sample) {
1884         sc->sample_to_time_sample += count;
1885         sc->sample_to_time_time   += count*duration;
1886         sc->sample_to_time_index ++;
1887         duration = sc->stts_data[sc->sample_to_time_index].duration;
1888       }
1889       dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * (int64_t)duration;
1890         /* find the corresponding pts */
1891         if (sc->sample_to_ctime_index < sc->ctts_count) {
1892             int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1893             int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1894
1895             if ((sc->sample_to_ctime_sample + count) < sc->current_sample) {
1896                 sc->sample_to_ctime_sample += count;
1897                 sc->sample_to_ctime_index ++;
1898                 duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1899             }
1900             pts = dts + duration;
1901         }else
1902             pts = dts;
1903
1904         st= s->streams[ sc->ffindex ];
1905         assert(pts % st->time_base.num == 0);
1906         assert(dts % st->time_base.num == 0);
1907
1908         pkt->pts = pts / st->time_base.num;
1909         pkt->dts = dts / st->time_base.num;
1910         dprintf("stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n"
1911                 , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1912                 , sc->sample_to_time_sample
1913                 , sc->sample_to_time_time
1914                 , sc->sample_to_time_index
1915                 , sc->stts_count
1916                 , count
1917                 , duration);
1918     }
1919
1920     return 0;
1921 }
1922
1923 #if defined(MOV_SEEK)
1924 /**
1925  * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1926  */
1927 static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1928 {
1929     MOVContext* mov = (MOVContext *) s->priv_data;
1930     MOVStreamContext* sc;
1931     int32_t i, a, b, m;
1932     int64_t start_time;
1933     int32_t seek_sample, sample;
1934     int32_t duration;
1935     int32_t count;
1936     int32_t chunk;
1937     int32_t left_in_chunk;
1938     int64_t chunk_file_offset;
1939     int64_t sample_file_offset;
1940     int32_t first_chunk_sample;
1941     int32_t sample_to_chunk_idx;
1942     int sample_to_time_index;
1943     long sample_to_time_sample = 0;
1944     uint64_t sample_to_time_time = 0;
1945     int mov_idx;
1946
1947     // Find the corresponding mov stream
1948     for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1949         if (mov->streams[mov_idx]->ffindex == stream_index)
1950             break;
1951     if (mov_idx == mov->total_streams) {
1952         av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1953         return -1;
1954     }
1955     sc = mov->streams[mov_idx];
1956
1957     sample_time *= s->streams[stream_index]->time_base.num;
1958
1959     // Step 1. Find the edit that contains the requested time (elst)
1960     if (sc->edit_count && 0) {
1961         // FIXME should handle edit list
1962         av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
1963         return -1;
1964     }
1965
1966     // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */
1967     dprintf("Searching for time %li in stream #%i (time_scale=%i)\n", (long)sample_time, mov_idx, sc->time_scale);
1968     start_time = 0; // FIXME use elst atom
1969     sample = 1; // sample are 0 based in table
1970
1971     for (i = 0; i < sc->stts_count; i++) {
1972         count = sc->stts_data[i].count;
1973         duration = sc->stts_data[i].duration;
1974         if ((start_time + count*duration) > sample_time) {
1975             sample_to_time_time = start_time;
1976             sample_to_time_index = i;
1977             sample_to_time_sample = sample;
1978             sample += (sample_time - start_time) / duration;
1979             break;
1980         }
1981         sample += count;
1982         start_time += count * duration;
1983     }
1984     sample_to_time_time = start_time;
1985     sample_to_time_index = i;
1986     /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
1987        is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
1988
1989     dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
1990     if (sample > sc->sample_count) {
1991         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);
1992         return -1;
1993     }
1994
1995     // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
1996     if (sc->keyframes) {
1997         a = 0;
1998         b = sc->keyframe_count - 1;
1999         while (a < b) {
2000             m = (a + b + 1) >> 1;
2001             if (sc->keyframes[m] > sample) {
2002                 b = m - 1;
2003             } else {
2004                 a = m;
2005             }
2006         }
2007         // for low latency prob: always use the previous keyframe, just uncomment the next line
2008         // if (a) a--;
2009         seek_sample = sc->keyframes[a];
2010     }
2011     else
2012         seek_sample = sample; // else all samples are key frames
2013     dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
2014
2015     // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2016     for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2017         b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2018         if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2019             break;
2020         first_chunk_sample += b;
2021     }
2022     chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2023     left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2024     first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2025     sample_to_chunk_idx = i;
2026     dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2027
2028     // Step 5. Find the offset of the chunk using the chunk offset atom
2029     if (!sc->chunk_offsets) {
2030         av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2031         return -1;
2032     }
2033     if (chunk > sc->chunk_count) {
2034         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);
2035         return -1;
2036     }
2037     chunk_file_offset = sc->chunk_offsets[chunk - 1];
2038     dprintf("Chunk file offset is #%llu \n", chunk_file_offset);
2039
2040     // Step 6. Find the byte offset within the chunk using the sample size atom
2041     sample_file_offset = chunk_file_offset;
2042     if (sc->sample_size)
2043         sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2044     else {
2045         for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2046         sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2047         }
2048     }
2049     dprintf("Sample file offset is #%llu \n", sample_file_offset);
2050
2051     // Step 6. Update the parser
2052     mov->partial = sc;
2053     mov->next_chunk_offset = sample_file_offset;
2054     // Update current stream state
2055     sc->current_sample = seek_sample - 1;  // zero based
2056     sc->left_in_chunk = left_in_chunk;
2057     sc->next_chunk = chunk; // +1 -1 (zero based)
2058     sc->sample_to_chunk_index = sample_to_chunk_idx;
2059
2060     // Update other streams
2061     for (i = 0; i<mov->total_streams; i++) {
2062         MOVStreamContext *msc;
2063         if (i == mov_idx) continue;
2064         // Find the nearest 'next' chunk
2065         msc = mov->streams[i];
2066         a = 0;
2067         b = msc->chunk_count - 1;
2068         while (a < b) {
2069             m = (a + b + 1) >> 1;
2070             if (msc->chunk_offsets[m] > chunk_file_offset) {
2071                 b = m - 1;
2072             } else {
2073                 a = m;
2074             }
2075         }
2076         msc->next_chunk = a;
2077         if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2078             msc->next_chunk ++;
2079         dprintf("Nearest next chunk for stream #%i is #%li @%lli\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2080
2081         // Compute sample count and index in the sample_to_chunk table (what a pity)
2082         msc->sample_to_chunk_index = 0;
2083         msc->current_sample = 0;
2084         for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2085             && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2086             msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2087             * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2088         }
2089         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;
2090         msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2091         // Find corresponding position in stts (used later to compute dts)
2092         sample = 0;
2093         start_time = 0;
2094         for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2095             count = msc->stts_data[msc->sample_to_time_index].count;
2096             duration = msc->stts_data[msc->sample_to_time_index].duration;
2097             if ((sample + count - 1) > msc->current_sample) {
2098                 msc->sample_to_time_time = start_time;
2099                 msc->sample_to_time_sample = sample;
2100                 break;
2101             }
2102             sample += count;
2103             start_time += count * duration;
2104         }
2105         sample = 0;
2106         for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2107             count = msc->ctts_data[msc->sample_to_ctime_index].count;
2108             duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2109             if ((sample + count - 1) > msc->current_sample) {
2110                 msc->sample_to_ctime_sample = sample;
2111                 break;
2112             }
2113             sample += count;
2114         }
2115         dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2116     }
2117     return 0;
2118 }
2119 #endif
2120
2121 static int mov_read_close(AVFormatContext *s)
2122 {
2123     int i;
2124     MOVContext *mov = (MOVContext *) s->priv_data;
2125     for(i=0; i<mov->total_streams; i++)
2126         mov_free_stream_context(mov->streams[i]);
2127     /* free color tabs */
2128     for(i=0; i<mov->ctab_size; i++)
2129         av_freep(&mov->ctab[i]);
2130     av_freep(&mov->ctab);
2131     return 0;
2132 }
2133
2134 static AVInputFormat mov_iformat = {
2135     "mov,mp4,m4a,3gp,3g2",
2136     "QuickTime/MPEG4 format",
2137     sizeof(MOVContext),
2138     mov_probe,
2139     mov_read_header,
2140     mov_read_packet,
2141     mov_read_close,
2142 #if defined(MOV_SEEK)
2143     mov_read_seek,
2144 #endif
2145 };
2146
2147 int mov_init(void)
2148 {
2149     av_register_input_format(&mov_iformat);
2150     return 0;
2151 }