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