VirtualBox

source: vbox/trunk/src/libs/ffmpeg-20060710/libavformat/mov.c@ 8998

最後變更 在這個檔案從8998是 5776,由 vboxsync 提交於 17 年 前

ffmpeg: exported to OSE

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette