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