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