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