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