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