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