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