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