cosmetics: Demplayerify indentation.
[libav.git] / libavformat / mov.c
CommitLineData
6cea494e 1/*
7fbde343 2 * MOV demuxer
19720f15 3 * Copyright (c) 2001 Fabrice Bellard.
6cea494e 4 *
b78e7197
DB
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
19720f15
FB
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
b78e7197 10 * version 2.1 of the License, or (at your option) any later version.
6cea494e 11 *
b78e7197 12 * FFmpeg is distributed in the hope that it will be useful,
6cea494e 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19720f15
FB
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
6cea494e 16 *
19720f15 17 * You should have received a copy of the GNU Lesser General Public
b78e7197 18 * License along with FFmpeg; if not, write to the Free Software
5509bffa 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6cea494e 20 */
d957696f
MN
21
22#include <limits.h>
115329f1 23
bfc2a19d 24//#define DEBUG
4e5ef14f 25
6cea494e 26#include "avformat.h"
9d9f4119 27#include "riff.h"
e40ee6a2 28#include "isom.h"
b60c0454 29#include "dv.h"
6cea494e 30
0147f198
FR
31#ifdef CONFIG_ZLIB
32#include <zlib.h>
33#endif
34
6cea494e
ZK
35/*
36 * First version by Francois Revol revol@free.fr
115329f1 37 * Seek function by Gael Chardon gael.dev@4now.net
5ca1d879 38 *
6cea494e 39 * Features and limitations:
5ca1d879 40 * - reads most of the QT files I have (at least the structure),
6cea494e 41 * Sample QuickTime files with mp3 audio can be found at: http://www.3ivx.com/showcase.html
6cea494e 42 * - the code is quite ugly... maybe I won't do it recursive next time :-)
5ca1d879 43 *
6cea494e
ZK
44 * Funny I didn't know about http://sourceforge.net/projects/qt-ffmpeg/
45 * when coding this :) (it's a writer anyway)
5ca1d879 46 *
6cea494e
ZK
47 * Reference documents:
48 * http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
49 * Apple:
baf25c9d 50 * http://developer.apple.com/documentation/QuickTime/QTFF/
15c8dbe7 51 * http://developer.apple.com/documentation/QuickTime/QTFF/qtff.pdf
6cea494e
ZK
52 * QuickTime is a trademark of Apple (AFAIK :))
53 */
54
b595afaa
MM
55#include "qtpalette.h"
56
baf25c9d 57
cd7352d5
MN
58#undef NDEBUG
59#include <assert.h>
60
6cea494e
ZK
61/* the QuickTime file format is quite convoluted...
62 * it has lots of index tables, each indexing something in another one...
63 * Here we just use what is needed to read the chunks
64 */
65
e23848a4 66typedef struct {
1c02d96f
BC
67 int first;
68 int count;
69 int id;
e23848a4 70} MOV_stsc_t;
6cea494e 71
5cd62665 72typedef struct {
5ca1d879
ZK
73 uint32_t type;
74 int64_t offset;
75 int64_t size; /* total size (excluding the size and type fields) */
76} MOV_atom_t;
77
b6a17df4
ZK
78struct MOVParseTableEntry;
79
6cea494e
ZK
80typedef struct MOVStreamContext {
81 int ffindex; /* the ffmpeg stream id */
1c02d96f 82 int next_chunk;
44d3fea5 83 unsigned int chunk_count;
0c1a9eda 84 int64_t *chunk_offsets;
44d3fea5 85 unsigned int stts_count;
e23848a4 86 MOV_stts_t *stts_data;
44d3fea5 87 unsigned int ctts_count;
e23848a4 88 MOV_stts_t *ctts_data;
44d3fea5
BC
89 unsigned int edit_count; /* number of 'edit' (elst atom) */
90 unsigned int sample_to_chunk_sz;
e23848a4 91 MOV_stsc_t *sample_to_chunk;
c4ac052b
MN
92 int sample_to_ctime_index;
93 int sample_to_ctime_sample;
44d3fea5
BC
94 unsigned int sample_size;
95 unsigned int sample_count;
1c02d96f 96 int *sample_sizes;
44d3fea5 97 unsigned int keyframe_count;
1c02d96f 98 int *keyframes;
5cd62665 99 int time_scale;
cd7352d5 100 int time_rate;
1c02d96f 101 int current_sample;
e14f79ed
BC
102 unsigned int bytes_per_frame;
103 unsigned int samples_per_frame;
b60c0454 104 int dv_audio_container;
ee6e2dbe 105 int pseudo_stream_id;
77c75437 106 int16_t audio_cid; ///< stsd audio compression id
6cea494e
ZK
107} MOVStreamContext;
108
109typedef struct MOVContext {
6cea494e 110 AVFormatContext *fc;
5cd62665 111 int time_scale;
7e815047 112 int64_t duration; /* duration of the longest track */
6cea494e
ZK
113 int found_moov; /* when both 'moov' and 'mdat' sections has been found */
114 int found_mdat; /* we suppose we have enough data to read the file */
b595afaa 115 AVPaletteControl palette_control;
b60c0454
BC
116 DVDemuxContext *dv_demux;
117 AVFormatContext *dv_fctx;
152e9a43 118 int isom; /* 1 if file is ISO Media (mp4/3gp) */
6cea494e
ZK
119} MOVContext;
120
121
6cea494e
ZK
122/* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */
123
124/* those functions parse an atom */
125/* return code:
126 1: found what I wanted, exit
127 0: continue to parse next atom
128 -1: error occured, exit
129 */
6cea494e
ZK
130/* links atom IDs to parse functions */
131typedef struct MOVParseTableEntry {
0c1a9eda 132 uint32_t type;
03dc32f6 133 int (*parse)(MOVContext *ctx, ByteIOContext *pb, MOV_atom_t atom);
6cea494e
ZK
134} MOVParseTableEntry;
135
73d07c27
BC
136static const MOVParseTableEntry mov_default_parse_table[];
137
5ca1d879 138static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
6cea494e 139{
b6a17df4 140 int64_t total_size = 0;
5ca1d879 141 MOV_atom_t a;
6cea494e
ZK
142 int i;
143 int err = 0;
5ca1d879 144
5ca1d879 145 a.offset = atom.offset;
6cea494e 146
9ed83b0a 147 if (atom.size < 0)
fa22ca22 148 atom.size = INT64_MAX;
5ca1d879 149 while(((total_size + 8) < atom.size) && !url_feof(pb) && !err) {
bb270c08 150 a.size = atom.size;
bcfe2ba0 151 a.type=0;
5ca1d879 152 if(atom.size >= 8) {
bb270c08 153 a.size = get_be32(pb);
5ca1d879 154 a.type = get_le32(pb);
6cea494e 155 }
bb270c08 156 total_size += 8;
5ca1d879 157 a.offset += 8;
29c90869
BC
158 dprintf(c->fc, "type: %08x %.4s sz: %"PRIx64" %"PRIx64" %"PRIx64"\n",
159 a.type, (char*)&a.type, a.size, atom.size, total_size);
5ca1d879 160 if (a.size == 1) { /* 64 bit extended size */
bb270c08 161 a.size = get_be64(pb) - 8;
5ca1d879
ZK
162 a.offset += 8;
163 total_size += 8;
6cea494e 164 }
bb270c08
DB
165 if (a.size == 0) {
166 a.size = atom.size - total_size;
167 if (a.size <= 8)
5cd62665 168 break;
bb270c08 169 }
bb270c08 170 a.size -= 8;
8622613d 171 if(a.size < 0)
568e18b1 172 break;
3d2308b0 173 a.size = FFMIN(a.size, atom.size - total_size);
115329f1 174
bcfe2ba0 175 for (i = 0; mov_default_parse_table[i].type != 0
73d07c27 176 && mov_default_parse_table[i].type != a.type; i++)
11979c46
BC
177 /* empty */;
178
73d07c27 179 if (mov_default_parse_table[i].type == 0) { /* skip leaf atoms data */
5ca1d879 180 url_fskip(pb, a.size);
bb270c08 181 } else {
5c72cad8
BC
182 offset_t start_pos = url_ftell(pb);
183 int64_t left;
03dc32f6 184 err = mov_default_parse_table[i].parse(c, pb, a);
687f35f3
BC
185 if (c->found_moov && c->found_mdat)
186 break;
5c72cad8
BC
187 left = a.size - url_ftell(pb) + start_pos;
188 if (left > 0) /* skip garbage at atom end */
189 url_fskip(pb, left);
bb270c08 190 }
6cea494e 191
bb270c08 192 a.offset += a.size;
5ca1d879 193 total_size += a.size;
6cea494e
ZK
194 }
195
5ca1d879 196 if (!err && total_size < atom.size && atom.size < 0x7ffff) {
5ca1d879 197 url_fskip(pb, atom.size - total_size);
5cd62665
ZK
198 }
199
6cea494e
ZK
200 return err;
201}
202
5ca1d879 203static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
6cea494e 204{
5ca1d879 205 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
0c1a9eda 206 uint32_t type;
0c1a9eda 207 uint32_t ctype;
b6a17df4 208
6cea494e
ZK
209 get_byte(pb); /* version */
210 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
211
212 /* component type */
213 ctype = get_le32(pb);
214 type = get_le32(pb); /* component subtype */
215
29c90869
BC
216 dprintf(c->fc, "ctype= %c%c%c%c (0x%08x)\n", *((char *)&ctype), ((char *)&ctype)[1],
217 ((char *)&ctype)[2], ((char *)&ctype)[3], (int) ctype);
218 dprintf(c->fc, "stype= %c%c%c%c\n",
219 *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]);
152e9a43
BC
220 if(!ctype)
221 c->isom = 1;
73920f07
BC
222 if(type == MKTAG('v', 'i', 'd', 'e'))
223 st->codec->codec_type = CODEC_TYPE_VIDEO;
224 else if(type == MKTAG('s', 'o', 'u', 'n'))
225 st->codec->codec_type = CODEC_TYPE_AUDIO;
95a07973
BC
226 else if(type == MKTAG('m', '1', 'a', ' '))
227 st->codec->codec_id = CODEC_ID_MP2;
8cb97693
BC
228 else if(type == MKTAG('s', 'u', 'b', 'p')) {
229 st->codec->codec_type = CODEC_TYPE_SUBTITLE;
8cb97693 230 }
6cea494e
ZK
231 get_be32(pb); /* component manufacture */
232 get_be32(pb); /* component flags */
233 get_be32(pb); /* component flags mask */
234
5ca1d879 235 if(atom.size <= 24)
6cea494e 236 return 0; /* nothing left to read */
5cd62665 237
3c13647a 238 url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
6cea494e
ZK
239 return 0;
240}
241
9e40addd 242static int mp4_read_descr_len(ByteIOContext *pb)
0e7eed09 243{
5cd62665 244 int len = 0;
5ca1d879
ZK
245 int count = 4;
246 while (count--) {
5cd62665 247 int c = get_byte(pb);
bb270c08
DB
248 len = (len << 7) | (c & 0x7f);
249 if (!(c & 0x80))
250 break;
0e7eed09
FB
251 }
252 return len;
253}
254
9e40addd 255static int mp4_read_descr(MOVContext *c, ByteIOContext *pb, int *tag)
0e7eed09
FB
256{
257 int len;
258 *tag = get_byte(pb);
9e40addd 259 len = mp4_read_descr_len(pb);
318c5e05 260 dprintf(c->fc, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
0e7eed09
FB
261 return len;
262}
263
0b07ac42
BC
264#define MP4ESDescrTag 0x03
265#define MP4DecConfigDescrTag 0x04
266#define MP4DecSpecificDescrTag 0x05
267
5ca1d879 268static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
5cd62665 269{
5cd62665 270 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
5cd62665 271 int tag, len;
b6a17df4 272
5cd62665 273 get_be32(pb); /* version + flags */
9e40addd 274 len = mp4_read_descr(c, pb, &tag);
5cd62665 275 if (tag == MP4ESDescrTag) {
bb270c08
DB
276 get_be16(pb); /* ID */
277 get_byte(pb); /* priority */
5cd62665 278 } else
bb270c08 279 get_be16(pb); /* ID */
5cd62665 280
9e40addd 281 len = mp4_read_descr(c, pb, &tag);
5cd62665 282 if (tag == MP4DecConfigDescrTag) {
0b07ac42
BC
283 int object_type_id = get_byte(pb);
284 get_byte(pb); /* stream type */
285 get_be24(pb); /* buffer size db */
286 get_be32(pb); /* max bitrate */
287 get_be32(pb); /* avg bitrate */
288
289 st->codec->codec_id= codec_get_id(ff_mp4_obj_type, object_type_id);
290 dprintf(c->fc, "esds object type id %d\n", object_type_id);
9e40addd 291 len = mp4_read_descr(c, pb, &tag);
bb270c08 292 if (tag == MP4DecSpecificDescrTag) {
318c5e05 293 dprintf(c->fc, "Specific MPEG4 header len=%d\n", len);
852859ff
BC
294 if((uint64_t)len > (1<<30))
295 return -1;
9a630c25 296 st->codec->extradata = av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
b014dd76
BC
297 if (!st->codec->extradata)
298 return AVERROR(ENOMEM);
17871a02
BC
299 get_buffer(pb, st->codec->extradata, len);
300 st->codec->extradata_size = len;
301 /* from mplayer */
302 if ((*st->codec->extradata >> 3) == 29) {
303 st->codec->codec_id = CODEC_ID_MP3ON4;
304 }
bb270c08 305 }
5cd62665 306 }
5cd62665
ZK
307 return 0;
308}
309
5ca1d879
ZK
310/* this atom contains actual media data */
311static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
6cea494e 312{
5ca1d879
ZK
313 if(atom.size == 0) /* wrong one (MP4) */
314 return 0;
315 c->found_mdat=1;
5ca1d879
ZK
316 if(c->found_moov)
317 return 1; /* found both, just go */
318 url_fskip(pb, atom.size);
319 return 0; /* now go for moov */
320}
321
4ea28253
BC
322static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
323{
324 uint32_t type = get_le32(pb);
325
152e9a43
BC
326 if (type != MKTAG('q','t',' ',' '))
327 c->isom = 1;
a512446e 328 av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
4ea28253
BC
329 get_be32(pb); /* minor version */
330 url_fskip(pb, atom.size - 8);
331 return 0;
332}
333
5ca1d879
ZK
334/* this atom should contain all header atoms */
335static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
336{
9cf0419b
PI
337 if (mov_read_default(c, pb, atom) < 0)
338 return -1;
5ca1d879
ZK
339 /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
340 /* so we don't parse the whole file if over a network */
341 c->found_moov=1;
342 if(c->found_mdat)
343 return 1; /* found both, just go */
344 return 0; /* now go for mdat */
345}
346
347
348static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
349{
f444b977 350 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
e4141433 351 MOVStreamContext *sc = st->priv_data;
f444b977 352 int version = get_byte(pb);
b9a87c4d 353 int lang;
5ca1d879 354
b9a87c4d
FR
355 if (version > 1)
356 return 1; /* unsupported */
5ca1d879
ZK
357
358 get_byte(pb); get_byte(pb);
359 get_byte(pb); /* flags */
360
f444b977
BC
361 if (version == 1) {
362 get_be64(pb);
363 get_be64(pb);
364 } else {
365 get_be32(pb); /* creation time */
366 get_be32(pb); /* modification time */
367 }
5ca1d879 368
f444b977
BC
369 sc->time_scale = get_be32(pb);
370 st->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
5ca1d879 371
b9a87c4d 372 lang = get_be16(pb); /* language */
f444b977 373 ff_mov_lang_to_iso639(lang, st->language);
5ca1d879
ZK
374 get_be16(pb); /* quality */
375
376 return 0;
377}
378
379static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
380{
1175561e 381 int version = get_byte(pb); /* version */
5ca1d879
ZK
382 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
383
1175561e
BC
384 if (version == 1) {
385 get_be64(pb);
386 get_be64(pb);
387 } else {
388 get_be32(pb); /* creation time */
389 get_be32(pb); /* modification time */
390 }
5ca1d879 391 c->time_scale = get_be32(pb); /* time scale */
f8c18cd7
BC
392
393 dprintf(c->fc, "time scale = %i\n", c->time_scale);
394
1175561e 395 c->duration = (version == 1) ? get_be64(pb) : get_be32(pb); /* duration */
5ca1d879
ZK
396 get_be32(pb); /* preferred scale */
397
398 get_be16(pb); /* preferred volume */
399
400 url_fskip(pb, 10); /* reserved */
401
402 url_fskip(pb, 36); /* display matrix */
403
404 get_be32(pb); /* preview time */
405 get_be32(pb); /* preview duration */
406 get_be32(pb); /* poster time */
407 get_be32(pb); /* selection time */
408 get_be32(pb); /* selection duration */
409 get_be32(pb); /* current time */
410 get_be32(pb); /* next track ID */
411
412 return 0;
413}
414
9ed83b0a
ZK
415static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
416{
417 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
418
568e18b1
MN
419 if((uint64_t)atom.size > (1<<30))
420 return -1;
115329f1 421
9ed83b0a
ZK
422 // currently SVQ3 decoder expect full STSD header - so let's fake it
423 // this should be fixed and just SMI header should be passed
01f4895c 424 av_free(st->codec->extradata);
b014dd76
BC
425 st->codec->extradata = av_mallocz(atom.size + 0x5a + FF_INPUT_BUFFER_PADDING_SIZE);
426 if (!st->codec->extradata)
427 return AVERROR(ENOMEM);
17871a02
BC
428 st->codec->extradata_size = 0x5a + atom.size;
429 memcpy(st->codec->extradata, "SVQ3", 4); // fake
430 get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
431 dprintf(c->fc, "Reading SMI %"PRId64" %s\n", atom.size, st->codec->extradata + 0x5a);
9ed83b0a
ZK
432 return 0;
433}
5ca1d879 434
de23f234
BC
435static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
436{
437 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
438 int little_endian = get_be16(pb);
439
440 if (little_endian) {
441 switch (st->codec->codec_id) {
442 case CODEC_ID_PCM_S24BE:
443 st->codec->codec_id = CODEC_ID_PCM_S24LE;
444 break;
445 case CODEC_ID_PCM_S32BE:
446 st->codec->codec_id = CODEC_ID_PCM_S32LE;
447 break;
448 default:
449 break;
450 }
451 }
452 return 0;
453}
454
014a5102
BC
455/* FIXME modify qdm2/svq3/h264 decoders to take full atom as extradata */
456static int mov_read_extradata(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
de23f234
BC
457{
458 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
68bc33fa
BC
459 uint64_t size= (uint64_t)st->codec->extradata_size + atom.size + 8 + FF_INPUT_BUFFER_PADDING_SIZE;
460 uint8_t *buf;
461 if(size > INT_MAX || (uint64_t)atom.size > INT_MAX)
014a5102 462 return -1;
68bc33fa
BC
463 buf= av_realloc(st->codec->extradata, size);
464 if(!buf)
465 return -1;
466 st->codec->extradata= buf;
467 buf+= st->codec->extradata_size;
468 st->codec->extradata_size= size - FF_INPUT_BUFFER_PADDING_SIZE;
469 AV_WB32( buf , atom.size + 8);
470 AV_WL32( buf + 4, atom.type);
471 get_buffer(pb, buf + 8, atom.size);
de23f234
BC
472 return 0;
473}
474
d9b1c197
RT
475static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
476{
477 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
478
479 if((uint64_t)atom.size > (1<<30))
480 return -1;
115329f1 481
3840147e
MN
482 if (st->codec->codec_id == CODEC_ID_QDM2) {
483 // pass all frma atom to codec, needed at least for QDM2
484 av_free(st->codec->extradata);
b014dd76
BC
485 st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
486 if (!st->codec->extradata)
487 return AVERROR(ENOMEM);
3840147e 488 st->codec->extradata_size = atom.size;
b014dd76 489 get_buffer(pb, st->codec->extradata, atom.size);
3840147e 490 } else if (atom.size > 8) { /* to read frma, esds atoms */
9cf0419b
PI
491 if (mov_read_default(c, pb, atom) < 0)
492 return -1;
5c72cad8 493 } else
bb270c08 494 url_fskip(pb, atom.size);
d9b1c197
RT
495 return 0;
496}
497
bde24601
BC
498/**
499 * This function reads atom content and puts data in extradata without tag
500 * nor size unlike mov_read_extradata.
501 */
502static int mov_read_glbl(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
169eb021
MM
503{
504 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
505
568e18b1
MN
506 if((uint64_t)atom.size > (1<<30))
507 return -1;
508
01f4895c 509 av_free(st->codec->extradata);
b014dd76
BC
510 st->codec->extradata = av_mallocz(atom.size + FF_INPUT_BUFFER_PADDING_SIZE);
511 if (!st->codec->extradata)
512 return AVERROR(ENOMEM);
01f4895c 513 st->codec->extradata_size = atom.size;
b014dd76 514 get_buffer(pb, st->codec->extradata, atom.size);
169eb021
MM
515 return 0;
516}
517
5ca1d879
ZK
518static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
519{
520 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
e4141433 521 MOVStreamContext *sc = st->priv_data;
568e18b1 522 unsigned int i, entries;
5ca1d879 523
5ca1d879
ZK
524 get_byte(pb); /* version */
525 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
526
527 entries = get_be32(pb);
115329f1 528
568e18b1
MN
529 if(entries >= UINT_MAX/sizeof(int64_t))
530 return -1;
115329f1 531
5ca1d879 532 sc->chunk_count = entries;
9a630c25 533 sc->chunk_offsets = av_malloc(entries * sizeof(int64_t));
5ca1d879
ZK
534 if (!sc->chunk_offsets)
535 return -1;
536 if (atom.type == MKTAG('s', 't', 'c', 'o')) {
537 for(i=0; i<entries; i++) {
538 sc->chunk_offsets[i] = get_be32(pb);
539 }
540 } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
541 for(i=0; i<entries; i++) {
542 sc->chunk_offsets[i] = get_be64(pb);
543 }
544 } else
545 return -1;
115329f1 546
5ca1d879
ZK
547 return 0;
548}
549
550static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
551{
552 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
e4141433 553 MOVStreamContext *sc = st->priv_data;
5ca1d879
ZK
554 int entries, frames_per_sample;
555 uint32_t format;
53ffdd14 556 uint8_t codec_name[32];
5ca1d879 557
b595afaa 558 /* for palette traversal */
8b35bd80
MM
559 unsigned int color_depth;
560 unsigned int color_start;
561 unsigned int color_count;
562 unsigned int color_end;
b595afaa
MM
563 int color_index;
564 int color_dec;
565 int color_greyscale;
1fe47470 566 const uint8_t *color_table;
ee6e2dbe 567 int j, pseudo_stream_id;
b595afaa
MM
568 unsigned char r, g, b;
569
6cea494e
ZK
570 get_byte(pb); /* version */
571 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
572
6cea494e
ZK
573 entries = get_be32(pb);
574
ee6e2dbe 575 for(pseudo_stream_id=0; pseudo_stream_id<entries; pseudo_stream_id++) { //Parsing Sample description table
b6a17df4 576 enum CodecID id;
de23f234 577 MOV_atom_t a = { 0, 0, 0 };
3840147e 578 offset_t start_pos = url_ftell(pb);
bb270c08 579 int size = get_be32(pb); /* size */
6cea494e 580 format = get_le32(pb); /* data format */
5cd62665 581
6cea494e
ZK
582 get_be32(pb); /* reserved */
583 get_be16(pb); /* reserved */
584 get_be16(pb); /* index */
0e7eed09 585
744a9c75
MN
586 if (st->codec->codec_tag &&
587 (c->fc->video_codec_id ? codec_get_id(codec_movvideo_tags, format) != c->fc->video_codec_id
588 : st->codec->codec_tag != MKTAG('j', 'p', 'e', 'g'))
589 ){
0bc4728e
MN
590 /* multiple fourcc, we skip jpeg, this isnt correct, we should export it as
591 seperate AVStream but this needs a few changes in the mov demuxer, patch
592 welcome */
e7cc4b52
BC
593 url_fskip(pb, size - (url_ftell(pb) - start_pos));
594 continue;
595 }
ee6e2dbe 596 sc->pseudo_stream_id= pseudo_stream_id;
e7cc4b52 597
bb270c08 598 st->codec->codec_tag = format;
1e5f5e3b 599 id = codec_get_id(codec_movaudio_tags, format);
bca7db35
MN
600 if (id<=0 && (format&0xFFFF) == 'm' + ('s'<<8))
601 id = codec_get_id(codec_wav_tags, bswap_32(format)&0xFFFF);
602
48855b26 603 if (st->codec->codec_type != CODEC_TYPE_VIDEO && id > 0) {
99487f42 604 st->codec->codec_type = CODEC_TYPE_AUDIO;
48855b26
BC
605 } else if (st->codec->codec_type != CODEC_TYPE_AUDIO && /* do not overwrite codec type */
606 format && format != MKTAG('m', 'p', '4', 's')) { /* skip old asf mpeg4 tag */
1e5f5e3b 607 id = codec_get_id(codec_movvideo_tags, format);
99487f42 608 if (id <= 0)
de23f234 609 id = codec_get_id(codec_bmp_tags, format);
99487f42
BC
610 if (id > 0)
611 st->codec->codec_type = CODEC_TYPE_VIDEO;
1e3c9307
MN
612 else if(st->codec->codec_type == CODEC_TYPE_DATA){
613 id = codec_get_id(ff_codec_movsubtitle_tags, format);
614 if(id > 0)
615 st->codec->codec_type = CODEC_TYPE_SUBTITLE;
616 }
99487f42
BC
617 }
618
29c90869
BC
619 dprintf(c->fc, "size=%d 4CC= %c%c%c%c codec_type=%d\n", size,
620 (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff,
621 (format >> 24) & 0xff, st->codec->codec_type);
a20da52c 622
99487f42 623 if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
01f4895c 624 st->codec->codec_id = id;
6cea494e
ZK
625 get_be16(pb); /* version */
626 get_be16(pb); /* revision level */
627 get_be32(pb); /* vendor */
628 get_be32(pb); /* temporal quality */
94472c1d 629 get_be32(pb); /* spatial quality */
3cb4ee51
BC
630
631 st->codec->width = get_be16(pb); /* width */
632 st->codec->height = get_be16(pb); /* height */
633
6cea494e
ZK
634 get_be32(pb); /* horiz resolution */
635 get_be32(pb); /* vert resolution */
636 get_be32(pb); /* data size, always 0 */
5cd62665 637 frames_per_sample = get_be16(pb); /* frames per samples */
f8c18cd7
BC
638
639 dprintf(c->fc, "frames/samples = %d\n", frames_per_sample);
640
576f1445
BC
641 get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
642 if (codec_name[0] <= 31) {
643 memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
644 st->codec->codec_name[codec_name[0]] = 0;
645 }
5cd62665 646
bb270c08 647 st->codec->bits_per_sample = get_be16(pb); /* depth */
01f4895c 648 st->codec->color_table_id = get_be16(pb); /* colortable id */
6cea494e 649
b595afaa 650 /* figure out the palette situation */
01f4895c
MN
651 color_depth = st->codec->bits_per_sample & 0x1F;
652 color_greyscale = st->codec->bits_per_sample & 0x20;
b595afaa
MM
653
654 /* if the depth is 2, 4, or 8 bpp, file is palettized */
115329f1 655 if ((color_depth == 2) || (color_depth == 4) ||
b595afaa 656 (color_depth == 8)) {
b595afaa 657 if (color_greyscale) {
b595afaa
MM
658 /* compute the greyscale palette */
659 color_count = 1 << color_depth;
660 color_index = 255;
661 color_dec = 256 / (color_count - 1);
662 for (j = 0; j < color_count; j++) {
663 r = g = b = color_index;
664 c->palette_control.palette[j] =
665 (r << 16) | (g << 8) | (b);
666 color_index -= color_dec;
667 if (color_index < 0)
668 color_index = 0;
669 }
01f4895c 670 } else if (st->codec->color_table_id & 0x08) {
b595afaa
MM
671 /* if flag bit 3 is set, use the default palette */
672 color_count = 1 << color_depth;
673 if (color_depth == 2)
a90466f7 674 color_table = ff_qt_default_palette_4;
b595afaa 675 else if (color_depth == 4)
a90466f7 676 color_table = ff_qt_default_palette_16;
b595afaa 677 else
a90466f7 678 color_table = ff_qt_default_palette_256;
b595afaa
MM
679
680 for (j = 0; j < color_count; j++) {
681 r = color_table[j * 4 + 0];
682 g = color_table[j * 4 + 1];
683 b = color_table[j * 4 + 2];
684 c->palette_control.palette[j] =
685 (r << 16) | (g << 8) | (b);
686 }
b595afaa 687 } else {
b595afaa
MM
688 /* load the palette from the file */
689 color_start = get_be32(pb);
690 color_count = get_be16(pb);
691 color_end = get_be16(pb);
8b35bd80
MM
692 if ((color_start <= 255) &&
693 (color_end <= 255)) {
9de2919c
MM
694 for (j = color_start; j <= color_end; j++) {
695 /* each R, G, or B component is 16 bits;
696 * only use the top 8 bits; skip alpha bytes
697 * up front */
698 get_byte(pb);
699 get_byte(pb);
700 r = get_byte(pb);
701 get_byte(pb);
702 g = get_byte(pb);
703 get_byte(pb);
704 b = get_byte(pb);
705 get_byte(pb);
706 c->palette_control.palette[j] =
707 (r << 16) | (g << 8) | (b);
8b35bd80 708 }
b595afaa
MM
709 }
710 }
01f4895c
MN
711 st->codec->palctrl = &c->palette_control;
712 st->codec->palctrl->palette_changed = 1;
b595afaa 713 } else
01f4895c 714 st->codec->palctrl = NULL;
de23f234 715 } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
b72708f8 716 int bits_per_sample;
de23f234 717 uint16_t version = get_be16(pb);
b595afaa 718
99487f42 719 st->codec->codec_id = id;
de23f234
BC
720 get_be16(pb); /* revision level */
721 get_be32(pb); /* vendor */
6d6d7970 722
de23f234 723 st->codec->channels = get_be16(pb); /* channel count */
318c5e05 724 dprintf(c->fc, "audio channels %d\n", st->codec->channels);
de23f234 725 st->codec->bits_per_sample = get_be16(pb); /* sample size */
de23f234 726
77c75437 727 sc->audio_cid = get_be16(pb);
de23f234
BC
728 get_be16(pb); /* packet size = 0 */
729
730 st->codec->sample_rate = ((get_be32(pb) >> 16));
731
732 switch (st->codec->codec_id) {
b72708f8
BC
733 case CODEC_ID_PCM_S8:
734 case CODEC_ID_PCM_U8:
735 if (st->codec->bits_per_sample == 16)
736 st->codec->codec_id = CODEC_ID_PCM_S16BE;
737 break;
0dd39bfe 738 case CODEC_ID_PCM_S16LE:
de23f234
BC
739 case CODEC_ID_PCM_S16BE:
740 if (st->codec->bits_per_sample == 8)
741 st->codec->codec_id = CODEC_ID_PCM_S8;
0299a87c
BC
742 else if (st->codec->bits_per_sample == 24)
743 st->codec->codec_id = CODEC_ID_PCM_S24BE;
de23f234 744 break;
53152765
BC
745 /* set values for old format before stsd version 1 appeared */
746 case CODEC_ID_MACE3:
747 sc->samples_per_frame = 6;
748 sc->bytes_per_frame = 2*st->codec->channels;
749 break;
750 case CODEC_ID_MACE6:
751 sc->samples_per_frame = 6;
752 sc->bytes_per_frame = 1*st->codec->channels;
753 break;
754 case CODEC_ID_ADPCM_IMA_QT:
755 sc->samples_per_frame = 64;
756 sc->bytes_per_frame = 34*st->codec->channels;
757 break;
de23f234
BC
758 default:
759 break;
6d6d7970 760 }
14342fd5 761
755bfeab 762 //Read QT version 1 fields. In version 0 these do not exist.
318c5e05 763 dprintf(c->fc, "version =%d, isom =%d\n",version,c->isom);
152e9a43 764 if(!c->isom) {
80c5b9a1 765 if(version==1) {
e14f79ed 766 sc->samples_per_frame = get_be32(pb);
80c5b9a1 767 get_be32(pb); /* bytes per packet */
e14f79ed 768 sc->bytes_per_frame = get_be32(pb);
80c5b9a1
BC
769 get_be32(pb); /* bytes per sample */
770 } else if(version==2) {
771 get_be32(pb); /* sizeof struct only */
772 st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */
773 st->codec->channels = get_be32(pb);
774 get_be32(pb); /* always 0x7F000000 */
775 get_be32(pb); /* bits per channel if sound is uncompressed */
776 get_be32(pb); /* lcpm format specific flag */
777 get_be32(pb); /* bytes per audio packet if constant */
778 get_be32(pb); /* lpcm frames per audio packet if constant */
779 }
152e9a43 780 }
9770089d
BC
781
782 bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
783 if (bits_per_sample) {
784 st->codec->bits_per_sample = bits_per_sample;
785 sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
786 }
cc8d87b7
MN
787 } else if(st->codec->codec_type==CODEC_TYPE_SUBTITLE){
788 st->codec->codec_id= id;
de23f234
BC
789 } else {
790 /* other codec type, just skip (rtp, mp4s, tmcd ...) */
791 url_fskip(pb, size - (url_ftell(pb) - start_pos));
6cea494e 792 }
de23f234
BC
793 /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
794 a.size = size - (url_ftell(pb) - start_pos);
9cf0419b
PI
795 if (a.size > 8) {
796 if (mov_read_default(c, pb, a) < 0)
797 return -1;
798 } else if (a.size > 0)
de23f234 799 url_fskip(pb, a.size);
6cea494e 800 }
115329f1 801
60f5c96e 802 if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1)
302c389e 803 st->codec->sample_rate= sc->time_scale;
e31bd3e3 804
d00f8e17 805 /* special codec parameters handling */
e31bd3e3 806 switch (st->codec->codec_id) {
989ac5a6 807#ifdef CONFIG_DV_DEMUXER
b60c0454
BC
808 case CODEC_ID_DVAUDIO:
809 c->dv_fctx = av_alloc_format_context();
810 c->dv_demux = dv_init_demux(c->dv_fctx);
811 if (!c->dv_demux) {
812 av_log(c->fc, AV_LOG_ERROR, "dv demux context init error\n");
813 return -1;
814 }
815 sc->dv_audio_container = 1;
816 st->codec->codec_id = CODEC_ID_PCM_S16LE;
817 break;
989ac5a6 818#endif
b95319a2
BC
819 /* no ifdef since parameters are always those */
820 case CODEC_ID_AMR_WB:
821 st->codec->sample_rate= 16000;
822 st->codec->channels= 1; /* really needed */
823 break;
824 case CODEC_ID_AMR_NB:
825 st->codec->sample_rate= 8000;
826 st->codec->channels= 1; /* really needed */
827 break;
a41104f8 828 case CODEC_ID_MP2:
c59f24e6 829 case CODEC_ID_MP3:
95a07973 830 st->codec->codec_type = CODEC_TYPE_AUDIO; /* force type after stsd for m1a hdlr */
57004ff1 831 st->need_parsing = AVSTREAM_PARSE_FULL;
a41104f8 832 break;
74e9b9ae
BC
833 case CODEC_ID_ADPCM_MS:
834 case CODEC_ID_ADPCM_IMA_WAV:
835 st->codec->block_align = sc->bytes_per_frame;
836 break;
e31bd3e3
BC
837 default:
838 break;
839 }
5cd62665 840
6cea494e
ZK
841 return 0;
842}
843
5ca1d879 844static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
6cea494e 845{
5ca1d879 846 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
e4141433 847 MOVStreamContext *sc = st->priv_data;
568e18b1 848 unsigned int i, entries;
b6a17df4 849
6cea494e
ZK
850 get_byte(pb); /* version */
851 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
852
853 entries = get_be32(pb);
115329f1 854
e23848a4 855 if(entries >= UINT_MAX / sizeof(MOV_stsc_t))
568e18b1 856 return -1;
115329f1 857
f8c18cd7
BC
858 dprintf(c->fc, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
859
6cea494e 860 sc->sample_to_chunk_sz = entries;
e23848a4 861 sc->sample_to_chunk = av_malloc(entries * sizeof(MOV_stsc_t));
b6a17df4
ZK
862 if (!sc->sample_to_chunk)
863 return -1;
6cea494e
ZK
864 for(i=0; i<entries; i++) {
865 sc->sample_to_chunk[i].first = get_be32(pb);
866 sc->sample_to_chunk[i].count = get_be32(pb);
867 sc->sample_to_chunk[i].id = get_be32(pb);
6cea494e
ZK
868 }
869 return 0;
870}
871
247d56f5
BB
872static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
873{
874 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
e4141433 875 MOVStreamContext *sc = st->priv_data;
568e18b1 876 unsigned int i, entries;
247d56f5 877
247d56f5
BB
878 get_byte(pb); /* version */
879 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
880
881 entries = get_be32(pb);
115329f1 882
1c02d96f 883 if(entries >= UINT_MAX / sizeof(int))
568e18b1 884 return -1;
115329f1 885
247d56f5 886 sc->keyframe_count = entries;
f8c18cd7
BC
887
888 dprintf(c->fc, "keyframe_count = %d\n", sc->keyframe_count);
889
1c02d96f 890 sc->keyframes = av_malloc(entries * sizeof(int));
247d56f5
BB
891 if (!sc->keyframes)
892 return -1;
893 for(i=0; i<entries; i++) {
894 sc->keyframes[i] = get_be32(pb);
f8c18cd7 895 //dprintf(c->fc, "keyframes[]=%d\n", sc->keyframes[i]);
247d56f5
BB
896 }
897 return 0;
898}
899
5ca1d879 900static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
6cea494e 901{
5ca1d879 902 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
e4141433 903 MOVStreamContext *sc = st->priv_data;
b72708f8 904 unsigned int i, entries, sample_size;
b6a17df4 905
6cea494e
ZK
906 get_byte(pb); /* version */
907 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
5cd62665 908
b72708f8
BC
909 sample_size = get_be32(pb);
910 if (!sc->sample_size) /* do not overwrite value computed in stsd */
911 sc->sample_size = sample_size;
6cea494e 912 entries = get_be32(pb);
1c02d96f 913 if(entries >= UINT_MAX / sizeof(int))
568e18b1
MN
914 return -1;
915
6cea494e 916 sc->sample_count = entries;
b72708f8
BC
917 if (sample_size)
918 return 0;
919
f8c18cd7
BC
920 dprintf(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, sc->sample_count);
921
1c02d96f 922 sc->sample_sizes = av_malloc(entries * sizeof(int));
b6a17df4
ZK
923 if (!sc->sample_sizes)
924 return -1;
6cea494e
ZK
925 for(i=0; i<entries; i++) {
926 sc->sample_sizes[i] = get_be32(pb);
f8c18cd7 927 dprintf(c->fc, "sample_sizes[]=%d\n", sc->sample_sizes[i]);
6cea494e
ZK
928 }
929 return 0;
930}
931
5ca1d879 932static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
0147f198 933{
5ca1d879 934 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
e4141433 935 MOVStreamContext *sc = st->priv_data;
568e18b1 936 unsigned int i, entries;
d957696f
MN
937 int64_t duration=0;
938 int64_t total_sample_count=0;
b6a17df4 939
0147f198
FR
940 get_byte(pb); /* version */
941 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
942 entries = get_be32(pb);
e23848a4 943 if(entries >= UINT_MAX / sizeof(MOV_stts_t))
568e18b1 944 return -1;
891f64b3 945
cd7352d5 946 sc->stts_count = entries;
e23848a4 947 sc->stts_data = av_malloc(entries * sizeof(MOV_stts_t));
c1da59fa
BC
948 if (!sc->stts_data)
949 return -1;
f8c18cd7 950 dprintf(c->fc, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
cd7352d5
MN
951
952 sc->time_rate=0;
953
0147f198 954 for(i=0; i<entries; i++) {
cd461d48
MN
955 int sample_duration;
956 int sample_count;
0147f198 957
891f64b3 958 sample_count=get_be32(pb);
0147f198 959 sample_duration = get_be32(pb);
cd7352d5
MN
960 sc->stts_data[i].count= sample_count;
961 sc->stts_data[i].duration= sample_duration;
962
963 sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
961e0ccd 964
318c5e05 965 dprintf(c->fc, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
4e5ef14f 966
7e815047 967 duration+=(int64_t)sample_duration*sample_count;
891f64b3 968 total_sample_count+=sample_count;
891f64b3 969 }
970
961e0ccd
MN
971 st->nb_frames= total_sample_count;
972 if(duration)
973 st->duration= duration;
0147f198
FR
974 return 0;
975}
976
c4ac052b
MN
977static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
978{
70a61ed4 979 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
e4141433 980 MOVStreamContext *sc = st->priv_data;
c4ac052b
MN
981 unsigned int i, entries;
982
c4ac052b
MN
983 get_byte(pb); /* version */
984 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
985 entries = get_be32(pb);
e23848a4 986 if(entries >= UINT_MAX / sizeof(MOV_stts_t))
c4ac052b
MN
987 return -1;
988
70a61ed4 989 sc->ctts_count = entries;
e23848a4 990 sc->ctts_data = av_malloc(entries * sizeof(MOV_stts_t));
c1da59fa
BC
991 if (!sc->ctts_data)
992 return -1;
318c5e05 993 dprintf(c->fc, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
4e5ef14f 994
c4ac052b 995 for(i=0; i<entries; i++) {
70a61ed4
MN
996 int count =get_be32(pb);
997 int duration =get_be32(pb);
998
b0519015
BC
999 if (duration < 0) {
1000 av_log(c->fc, AV_LOG_ERROR, "negative ctts, ignoring\n");
1001 sc->ctts_count = 0;
1002 url_fskip(pb, 8 * (entries - i - 1));
1003 break;
1004 }
70a61ed4
MN
1005 sc->ctts_data[i].count = count;
1006 sc->ctts_data[i].duration= duration;
1007
1008 sc->time_rate= ff_gcd(sc->time_rate, duration);
c4ac052b
MN
1009 }
1010 return 0;
1011}
1012
5ca1d879
ZK
1013static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1014{
1015 AVStream *st;
1016 MOVStreamContext *sc;
1017
5ca1d879
ZK
1018 st = av_new_stream(c->fc, c->fc->nb_streams);
1019 if (!st) return -2;
9a630c25 1020 sc = av_mallocz(sizeof(MOVStreamContext));
5ca1d879 1021 if (!sc) {
bb270c08 1022 av_free(st);
5ca1d879
ZK
1023 return -1;
1024 }
1025
5ca1d879 1026 st->priv_data = sc;
05edc1a7 1027 st->codec->codec_type = CODEC_TYPE_DATA;
25c4950e 1028 st->start_time = 0; /* XXX: check */
5ca1d879
ZK
1029
1030 return mov_read_default(c, pb, atom);
1031}
1032
d2ace376
BF
1033static void mov_parse_udta_string(ByteIOContext *pb, char *str, int size)
1034{
1035 uint16_t str_size = get_be16(pb); /* string length */;
1036
1037 get_be16(pb); /* skip language */
1038 get_buffer(pb, str, FFMIN(size, str_size));
1039}
1040
1041static int mov_read_udta(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1042{
1043 uint64_t end = url_ftell(pb) + atom.size;
1044
1045 while (url_ftell(pb) + 8 < end) {
1046 uint32_t tag_size = get_be32(pb);
1047 uint32_t tag = get_le32(pb);
1048 uint64_t next = url_ftell(pb) + tag_size - 8;
1049
aaac6c29
BC
1050 if (next > end) // stop if tag_size is wrong
1051 break;
1052
d2ace376
BF
1053 switch (tag) {
1054 case MKTAG(0xa9,'n','a','m'):
1055 mov_parse_udta_string(pb, c->fc->title, sizeof(c->fc->title));
1056 break;
1057 case MKTAG(0xa9,'w','r','t'):
1058 mov_parse_udta_string(pb, c->fc->author, sizeof(c->fc->author));
1059 break;
1060 case MKTAG(0xa9,'c','p','y'):
1061 mov_parse_udta_string(pb, c->fc->copyright, sizeof(c->fc->copyright));
1062 break;
1063 case MKTAG(0xa9,'i','n','f'):
1064 mov_parse_udta_string(pb, c->fc->comment, sizeof(c->fc->comment));
1065 break;
1066 default:
1067 break;
1068 }
1069
1070 url_fseek(pb, next, SEEK_SET);
1071 }
1072
1073 return 0;
1074}
1075
5ca1d879
ZK
1076static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1077{
f444b977
BC
1078 AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1079 int version = get_byte(pb);
5ca1d879
ZK
1080
1081 get_byte(pb); get_byte(pb);
1082 get_byte(pb); /* flags */
1083 /*
1084 MOV_TRACK_ENABLED 0x0001
1085 MOV_TRACK_IN_MOVIE 0x0002
1086 MOV_TRACK_IN_PREVIEW 0x0004
1087 MOV_TRACK_IN_POSTER 0x0008
1088 */
1089
1175561e
BC
1090 if (version == 1) {
1091 get_be64(pb);
1092 get_be64(pb);
1093 } else {
1094 get_be32(pb); /* creation time */
1095 get_be32(pb); /* modification time */
1096 }
5ca1d879
ZK
1097 st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1098 get_be32(pb); /* reserved */
25c4950e 1099 st->start_time = 0; /* check */
1175561e 1100 (version == 1) ? get_be64(pb) : get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
5ca1d879
ZK
1101 get_be32(pb); /* reserved */
1102 get_be32(pb); /* reserved */
1103
1104 get_be16(pb); /* layer */
1105 get_be16(pb); /* alternate group */
1106 get_be16(pb); /* volume */
1107 get_be16(pb); /* reserved */
1108
1109 url_fskip(pb, 36); /* display matrix */
1110
1111 /* those are fixed-point */
c3daf8d8
BC
1112 get_be32(pb); /* track width */
1113 get_be32(pb); /* track height */
5ca1d879
ZK
1114
1115 return 0;
1116}
1117
1118/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1119/* like the files created with Adobe Premiere 5.0, for samples see */
1120/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1121static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1122{
1123 int err;
5ca1d879 1124
5ca1d879
ZK
1125 if (atom.size < 8)
1126 return 0; /* continue */
1127 if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1128 url_fskip(pb, atom.size - 4);
1129 return 0;
1130 }
1131 atom.type = get_le32(pb);
1132 atom.offset += 8;
1133 atom.size -= 8;
fd6e513e 1134 if (atom.type != MKTAG('m', 'd', 'a', 't')) {
5ca1d879
ZK
1135 url_fskip(pb, atom.size);
1136 return 0;
1137 }
1138 err = mov_read_mdat(c, pb, atom);
5ca1d879
ZK
1139 return err;
1140}
1141
5ca1d879 1142static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
0147f198 1143{
d966b2f0 1144#ifdef CONFIG_ZLIB
0147f198 1145 ByteIOContext ctx;
b6a17df4
ZK
1146 uint8_t *cmov_data;
1147 uint8_t *moov_data; /* uncompressed data */
0147f198
FR
1148 long cmov_len, moov_len;
1149 int ret;
b6a17df4 1150
0147f198
FR
1151 get_be32(pb); /* dcom atom */
1152 if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1153 return -1;
1154 if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
4e5ef14f 1155 av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
0147f198
FR
1156 return -1;
1157 }
1158 get_be32(pb); /* cmvd atom */
1159 if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1160 return -1;
1161 moov_len = get_be32(pb); /* uncompressed size */
5ca1d879 1162 cmov_len = atom.size - 6 * 4;
5cd62665 1163
9a630c25 1164 cmov_data = av_malloc(cmov_len);
0147f198
FR
1165 if (!cmov_data)
1166 return -1;
9a630c25 1167 moov_data = av_malloc(moov_len);
0147f198
FR
1168 if (!moov_data) {
1169 av_free(cmov_data);
1170 return -1;
1171 }
1172 get_buffer(pb, cmov_data, cmov_len);
b6a17df4 1173 if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
0147f198 1174 return -1;
942f3bb5 1175 if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0)
0147f198 1176 return -1;
5ca1d879
ZK
1177 atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1178 atom.offset = 0;
1179 atom.size = moov_len;
9ed83b0a 1180#ifdef DEBUG
dbb4f00a 1181// { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
9ed83b0a 1182#endif
5ca1d879 1183 ret = mov_read_default(c, &ctx, atom);
0147f198
FR
1184 av_free(moov_data);
1185 av_free(cmov_data);
1186 return ret;
d966b2f0
BC
1187#else
1188 av_log(c->fc, AV_LOG_ERROR, "this file requires zlib support compiled in\n");
1189 return -1;
0147f198 1190#endif
d966b2f0 1191}
0147f198 1192
baf25c9d
GC
1193/* edit list atom */
1194static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1195{
7c622eed 1196 MOVStreamContext *sc = c->fc->streams[c->fc->nb_streams-1]->priv_data;
e0977c80
BC
1197 int i, edit_count;
1198
1199 get_byte(pb); /* version */
1200 get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
7c622eed 1201 edit_count= sc->edit_count = get_be32(pb); /* entries */
e0977c80
BC
1202
1203 for(i=0; i<edit_count; i++){
d435e520 1204 int time;
e0977c80 1205 get_be32(pb); /* Track duration */
d435e520 1206 time = get_be32(pb); /* Media time */
e0977c80 1207 get_be32(pb); /* Media rate */
d435e520
BC
1208 if (time != 0)
1209 av_log(c->fc, AV_LOG_WARNING, "edit list not starting at 0, "
1210 "a/v desync might occur, patch welcome\n");
e0977c80 1211 }
7c622eed 1212 dprintf(c->fc, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, sc->edit_count);
e0977c80 1213 return 0;
baf25c9d
GC
1214}
1215
6cea494e
ZK
1216static const MOVParseTableEntry mov_default_parse_table[] = {
1217/* mp4 atoms */
5ca1d879 1218{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
c4ac052b 1219{ MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
5ca1d879 1220{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
58e555d4 1221{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
de23f234 1222{ MKTAG( 'e', 'n', 'd', 'a' ), mov_read_enda },
9a63497b 1223{ MKTAG( 'f', 'i', 'e', 'l' ), mov_read_extradata },
4ea28253 1224{ MKTAG( 'f', 't', 'y', 'p' ), mov_read_ftyp },
bde24601 1225{ MKTAG( 'g', 'l', 'b', 'l' ), mov_read_glbl },
5ca1d879 1226{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
014a5102 1227{ MKTAG( 'j', 'p', '2', 'h' ), mov_read_extradata },
5ca1d879
ZK
1228{ MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1229{ MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1230{ MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1231{ MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1232{ MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
5ca1d879 1233{ MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
169eb021 1234{ MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
014a5102 1235{ MKTAG( 'a', 'l', 'a', 'c' ), mov_read_extradata }, /* alac specific atom */
bde24601 1236{ MKTAG( 'a', 'v', 'c', 'C' ), mov_read_glbl },
5ca1d879
ZK
1237{ MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1238{ MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
5ca1d879
ZK
1239{ MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1240{ MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
247d56f5 1241{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
5ca1d879
ZK
1242{ MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1243{ MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1244{ MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1245{ MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
d2ace376 1246{ MKTAG( 'u', 'd', 't', 'a' ), mov_read_udta },
d9b1c197 1247{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
5ca1d879 1248{ MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
5ca1d879 1249{ MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
5ca1d879 1250{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
bcfe2ba0 1251{ 0, NULL }
6cea494e
ZK
1252};
1253
b6a17df4 1254/* XXX: is it sufficient ? */
c9a65ca8
FB
1255static int mov_probe(AVProbeData *p)
1256{
0e7eed09
FB
1257 unsigned int offset;
1258 uint32_t tag;
2497479f 1259 int score = 0;
3ffe3793 1260
c9a65ca8 1261 /* check file header */
0e7eed09
FB
1262 offset = 0;
1263 for(;;) {
1264 /* ignore invalid offset */
1265 if ((offset + 8) > (unsigned int)p->buf_size)
2497479f 1266 return score;
fead30d4 1267 tag = AV_RL32(p->buf + offset + 4);
0e7eed09 1268 switch(tag) {
2497479f 1269 /* check for obvious tags */
fc5188f3 1270 case MKTAG( 'j', 'P', ' ', ' ' ): /* jpeg 2000 signature */
0e7eed09 1271 case MKTAG( 'm', 'o', 'o', 'v' ):
8b879f18
FR
1272 case MKTAG( 'm', 'd', 'a', 't' ):
1273 case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
bc634f6f 1274 case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
3ffe3793 1275 return AVPROBE_SCORE_MAX;
2497479f 1276 /* those are more common words, so rate then a bit less */
263a93ec 1277 case MKTAG( 'e', 'd', 'i', 'w' ): /* xdcam files have reverted first tags */
2497479f
FR
1278 case MKTAG( 'w', 'i', 'd', 'e' ):
1279 case MKTAG( 'f', 'r', 'e', 'e' ):
1280 case MKTAG( 'j', 'u', 'n', 'k' ):
1281 case MKTAG( 'p', 'i', 'c', 't' ):
1282 return AVPROBE_SCORE_MAX - 5;
0e7eed09 1283 case MKTAG( 'f', 't', 'y', 'p' ):
5ca1d879 1284 case MKTAG( 's', 'k', 'i', 'p' ):
0d23cb84 1285 case MKTAG( 'u', 'u', 'i', 'd' ):
fead30d4 1286 offset = AV_RB32(p->buf+offset) + offset;
2497479f
FR
1287 /* if we only find those cause probedata is too small at least rate them */
1288 score = AVPROBE_SCORE_MAX - 50;
0e7eed09
FB
1289 break;
1290 default:
1291 /* unrecognized tag */
2497479f 1292 return score;
0e7eed09 1293 }
3ffe3793 1294 }
2497479f 1295 return score;
c9a65ca8
FB
1296}
1297
b72708f8
BC
1298static void mov_build_index(MOVContext *mov, AVStream *st)
1299{
1300 MOVStreamContext *sc = st->priv_data;
1301 offset_t current_offset;
1302 int64_t current_dts = 0;
01aa1937
BC
1303 unsigned int stts_index = 0;
1304 unsigned int stsc_index = 0;
1305 unsigned int stss_index = 0;
53152765 1306 unsigned int i, j;
b72708f8 1307
77c75437
BC
1308 if (sc->sample_sizes || st->codec->codec_type == CODEC_TYPE_VIDEO ||
1309 sc->audio_cid == -2) {
01aa1937
BC
1310 unsigned int current_sample = 0;
1311 unsigned int stts_sample = 0;
1312 unsigned int keyframe, sample_size;
1313 unsigned int distance = 0;
b72708f8
BC
1314
1315 st->nb_frames = sc->sample_count;
1316 for (i = 0; i < sc->chunk_count; i++) {
1317 current_offset = sc->chunk_offsets[i];
29c90869
BC
1318 if (stsc_index + 1 < sc->sample_to_chunk_sz &&
1319 i + 1 == sc->sample_to_chunk[stsc_index + 1].first)
b72708f8
BC
1320 stsc_index++;
1321 for (j = 0; j < sc->sample_to_chunk[stsc_index].count; j++) {
64934877
BC
1322 if (current_sample >= sc->sample_count) {
1323 av_log(mov->fc, AV_LOG_ERROR, "wrong sample count\n");
1324 goto out;
1325 }
b72708f8
BC
1326 keyframe = !sc->keyframe_count || current_sample + 1 == sc->keyframes[stss_index];
1327 if (keyframe) {
1328 distance = 0;
1329 if (stss_index + 1 < sc->keyframe_count)
1330 stss_index++;
1331 }
1332 sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
29c90869
BC
1333 dprintf(mov->fc, "AVIndex stream %d, sample %d, offset %"PRIx64", dts %"PRId64", "
1334 "size %d, distance %d, keyframe %d\n", st->index, current_sample,
1335 current_offset, current_dts, sample_size, distance, keyframe);
ee6e2dbe 1336 if(sc->sample_to_chunk[stsc_index].id - 1 == sc->pseudo_stream_id)
41e19673
MN
1337 av_add_index_entry(st, current_offset, current_dts, sample_size, distance,
1338 keyframe ? AVINDEX_KEYFRAME : 0);
b72708f8
BC
1339 current_offset += sample_size;
1340 assert(sc->stts_data[stts_index].duration % sc->time_rate == 0);
1341 current_dts += sc->stts_data[stts_index].duration / sc->time_rate;
1342 distance++;
1343 stts_sample++;
64934877 1344 current_sample++;
b72708f8
BC
1345 if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
1346 stts_sample = 0;
1347 stts_index++;
1348 }
1349 }
1350 }
1351 } else { /* read whole chunk */
01aa1937 1352 unsigned int chunk_samples, chunk_size, chunk_duration;
8cb66fd8 1353 unsigned int frames = 1;
b72708f8
BC
1354 for (i = 0; i < sc->chunk_count; i++) {
1355 current_offset = sc->chunk_offsets[i];
29c90869
BC
1356 if (stsc_index + 1 < sc->sample_to_chunk_sz &&
1357 i + 1 == sc->sample_to_chunk[stsc_index + 1].first)
b72708f8
BC
1358 stsc_index++;
1359 chunk_samples = sc->sample_to_chunk[stsc_index].count;
501f162f
BC
1360 /* get chunk size, beware of alaw/ulaw/mace */
1361 if (sc->samples_per_frame > 0 &&
1362 (chunk_samples * sc->bytes_per_frame % sc->samples_per_frame == 0)) {
311490cc
BC
1363 if (sc->samples_per_frame < 1024)
1364 chunk_size = chunk_samples * sc->bytes_per_frame / sc->samples_per_frame;
1365 else {
1366 chunk_size = sc->bytes_per_frame;
1367 frames = chunk_samples / sc->samples_per_frame;
1368 chunk_samples = sc->samples_per_frame;
8cb66fd8 1369 }
501f162f
BC
1370 } else if (sc->sample_size > 1 || st->codec->bits_per_sample == 8) {
1371 chunk_size = chunk_samples * sc->sample_size;
53152765
BC
1372 } else {
1373 av_log(mov->fc, AV_LOG_ERROR, "could not determine chunk size, report problem\n");
1374 goto out;
b72708f8 1375 }
8cb66fd8 1376 for (j = 0; j < frames; j++) {
18978a49
BC
1377 av_add_index_entry(st, current_offset, current_dts, chunk_size, 0, AVINDEX_KEYFRAME);
1378 /* get chunk duration */
1379 chunk_duration = 0;
1380 while (chunk_samples > 0) {
1381 if (chunk_samples < sc->stts_data[stts_index].count) {
1382 chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;
1383 sc->stts_data[stts_index].count -= chunk_samples;
1384 break;
1385 } else {
1386 chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;
1387 chunk_samples -= sc->stts_data[stts_index].count;
1388 if (stts_index + 1 < sc->stts_count)
1389 stts_index++;
1390 }
b72708f8 1391 }
18978a49
BC
1392 current_offset += sc->bytes_per_frame;
1393 dprintf(mov->fc, "AVIndex stream %d, chunk %d, offset %"PRIx64", dts %"PRId64", size %d, "
1394 "duration %d\n", st->index, i, current_offset, current_dts, chunk_size, chunk_duration);
1395 assert(chunk_duration % sc->time_rate == 0);
1396 current_dts += chunk_duration / sc->time_rate;
8cb66fd8 1397 }
b72708f8 1398 }
b72708f8 1399 }
64934877 1400 out:
1f1890c7
BC
1401 /* adjust sample count to avindex entries */
1402 sc->sample_count = st->nb_index_entries;
b72708f8
BC
1403}
1404
a266644f 1405static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
6cea494e 1406{
e4141433 1407 MOVContext *mov = s->priv_data;
899681cd 1408 ByteIOContext *pb = s->pb;
05edc1a7 1409 int i, err;
5ca1d879 1410 MOV_atom_t atom = { 0, 0, 0 };
6cea494e 1411
6cea494e 1412 mov->fc = s;
3253c51f 1413
6cea494e 1414 if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
bb270c08 1415 atom.size = url_fsize(pb);
6cea494e 1416 else
fa22ca22 1417 atom.size = INT64_MAX;
6cea494e 1418
6cea494e 1419 /* check MOV header */
5ca1d879 1420 err = mov_read_default(mov, pb, atom);
25fa62e1 1421 if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
bb270c08
DB
1422 av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1423 err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1424 return -1;
6cea494e 1425 }
318c5e05 1426 dprintf(mov->fc, "on_parse_exit_offset=%d\n", (int) url_ftell(pb));
4e5ef14f 1427
11f16b66 1428 for(i=0; i<s->nb_streams; i++) {
2d2432b7 1429 AVStream *st = s->streams[i];
7c622eed 1430 MOVStreamContext *sc = st->priv_data;
dfcf8d57
BC
1431 /* sanity checks */
1432 if(!sc->stts_count || !sc->chunk_count || !sc->sample_to_chunk_sz ||
1433 (!sc->sample_size && !sc->sample_count)){
1434 av_log(s, AV_LOG_ERROR, "missing mandatory atoms, broken header\n");
a097e559 1435 sc->sample_count = 0; //ignore track
b0c17f77 1436 continue;
dfcf8d57 1437 }
05edc1a7
BC
1438 if(!sc->time_rate)
1439 sc->time_rate=1;
1440 if(!sc->time_scale)
1441 sc->time_scale= mov->time_scale;
638fd2fc 1442 av_set_pts_info(st, 64, sc->time_rate, sc->time_scale);
05edc1a7 1443
2d2432b7 1444 if (st->codec->codec_type == CODEC_TYPE_AUDIO && sc->stts_count == 1)
6d680e1b 1445 st->codec->frame_size = av_rescale(sc->time_rate, st->codec->sample_rate, sc->time_scale);
2d2432b7 1446
638fd2fc
BC
1447 if(st->duration != AV_NOPTS_VALUE){
1448 assert(st->duration % sc->time_rate == 0);
1449 st->duration /= sc->time_rate;
75b5b631 1450 }
05edc1a7 1451 sc->ffindex = i;
638fd2fc 1452 mov_build_index(mov, st);
f296563e
BC
1453
1454 switch (st->codec->codec_id) {
1455#ifdef CONFIG_H261_DECODER
1456 case CODEC_ID_H261:
1457#endif
1458#ifdef CONFIG_H263_DECODER
1459 case CODEC_ID_H263:
1460#endif
1461#ifdef CONFIG_MPEG4_DECODER
1462 case CODEC_ID_MPEG4:
1463#endif
1464 st->codec->width= 0; /* let decoder init width/height */
1465 st->codec->height= 0;
1466 break;
1467#ifdef CONFIG_LIBFAAD
1468 case CODEC_ID_AAC:
1469#endif
1470#ifdef CONFIG_VORBIS_DECODER
1471 case CODEC_ID_VORBIS:
1472#endif
1473 case CODEC_ID_MP3ON4:
1474 st->codec->sample_rate= 0; /* let decoder init parameters properly */
1475 break;
1476 }
6cea494e 1477 }
a2fe3b58 1478
11f16b66 1479 for(i=0; i<s->nb_streams; i++) {
7c622eed 1480 MOVStreamContext *sc = s->streams[i]->priv_data;
755bfeab 1481 /* Do not need those anymore. */
7c622eed
BC
1482 av_freep(&sc->chunk_offsets);
1483 av_freep(&sc->sample_to_chunk);
1484 av_freep(&sc->sample_sizes);
1485 av_freep(&sc->keyframes);
1486 av_freep(&sc->stts_data);
b72708f8 1487 }
6cea494e
ZK
1488 return 0;
1489}
1490
a266644f 1491static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
6cea494e 1492{
b72708f8
BC
1493 MOVContext *mov = s->priv_data;
1494 MOVStreamContext *sc = 0;
1495 AVIndexEntry *sample = 0;
86d8602f 1496 int64_t best_dts = INT64_MAX;
b72708f8 1497 int i;
3ffe3793 1498
11f16b66 1499 for (i = 0; i < s->nb_streams; i++) {
7c622eed
BC
1500 AVStream *st = s->streams[i];
1501 MOVStreamContext *msc = st->priv_data;
1502 if (st->discard != AVDISCARD_ALL && msc->current_sample < msc->sample_count) {
1503 AVIndexEntry *current_sample = &st->index_entries[msc->current_sample];
29c90869
BC
1504 int64_t dts = av_rescale(current_sample->timestamp * (int64_t)msc->time_rate,
1505 AV_TIME_BASE, msc->time_scale);
1c02d96f 1506 dprintf(s, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts);
687f35f3
BC
1507 if (!sample || (url_is_streamed(s->pb) && current_sample->pos < sample->pos) ||
1508 (!url_is_streamed(s->pb) &&
1509 ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) ||
1510 (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))) {
b72708f8
BC
1511 sample = current_sample;
1512 best_dts = dts;
1513 sc = msc;
86d8602f 1514 }
6cea494e 1515 }
6cea494e 1516 }
b72708f8
BC
1517 if (!sample)
1518 return -1;
1519 /* must be done just before reading, to avoid infinite loop on sample */
1520 sc->current_sample++;
687f35f3 1521 if (url_fseek(s->pb, sample->pos, SEEK_SET) != sample->pos) {
29c90869
BC
1522 av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%"PRIx64": partial file\n",
1523 sc->ffindex, sample->pos);
bb270c08 1524 return -1;
6cea494e 1525 }
56ea717b 1526 av_get_packet(s->pb, pkt, sample->size);
312954f0 1527#ifdef CONFIG_DV_DEMUXER
56ea717b
BC
1528 if (mov->dv_demux && sc->dv_audio_container) {
1529 dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size);
1530 av_free(pkt->data);
300aa2b0
BC
1531 pkt->size = 0;
1532 if (dv_get_packet(mov->dv_demux, pkt) < 0)
1533 return -1;
56ea717b 1534 }
312954f0 1535#endif
b72708f8
BC
1536 pkt->stream_index = sc->ffindex;
1537 pkt->dts = sample->timestamp;
1538 if (sc->ctts_data) {
1539 assert(sc->ctts_data[sc->sample_to_ctime_index].duration % sc->time_rate == 0);
1540 pkt->pts = pkt->dts + sc->ctts_data[sc->sample_to_ctime_index].duration / sc->time_rate;
1541 /* update ctts context */
1542 sc->sample_to_ctime_sample++;
29c90869
BC
1543 if (sc->sample_to_ctime_index < sc->ctts_count &&
1544 sc->ctts_data[sc->sample_to_ctime_index].count == sc->sample_to_ctime_sample) {
b72708f8
BC
1545 sc->sample_to_ctime_index++;
1546 sc->sample_to_ctime_sample = 0;
b565ea09 1547 }
b72708f8
BC
1548 } else {
1549 pkt->pts = pkt->dts;
b565ea09 1550 }
b72708f8
BC
1551 pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? PKT_FLAG_KEY : 0;
1552 pkt->pos = sample->pos;
29c90869
BC
1553 dprintf(s, "stream %d, pts %"PRId64", dts %"PRId64", pos 0x%"PRIx64", duration %d\n",
1554 pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration);
b72708f8
BC
1555 return 0;
1556}
3ffe3793 1557
b72708f8
BC
1558static int mov_seek_stream(AVStream *st, int64_t timestamp, int flags)
1559{
1560 MOVStreamContext *sc = st->priv_data;
1561 int sample, time_sample;
1562 int i;
115329f1 1563
b72708f8 1564 sample = av_index_search_timestamp(st, timestamp, flags);
318c5e05 1565 dprintf(st->codec, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample);
b72708f8
BC
1566 if (sample < 0) /* not sure what to do */
1567 return -1;
1568 sc->current_sample = sample;
1c02d96f 1569 dprintf(st->codec, "stream %d, found sample %d\n", st->index, sc->current_sample);
b72708f8
BC
1570 /* adjust ctts index */
1571 if (sc->ctts_data) {
1572 time_sample = 0;
1573 for (i = 0; i < sc->ctts_count; i++) {
54a5c719
BC
1574 int next = time_sample + sc->ctts_data[i].count;
1575 if (next > sc->current_sample) {
b72708f8 1576 sc->sample_to_ctime_index = i;
54a5c719 1577 sc->sample_to_ctime_sample = sc->current_sample - time_sample;
b72708f8 1578 break;
115329f1 1579 }
54a5c719 1580 time_sample = next;
247d56f5 1581 }
247d56f5 1582 }
b72708f8 1583 return sample;
6cea494e
ZK
1584}
1585
961e0ccd 1586static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
baf25c9d 1587{
b72708f8
BC
1588 AVStream *st;
1589 int64_t seek_timestamp, timestamp;
1590 int sample;
1591 int i;
baf25c9d 1592
b72708f8 1593 if (stream_index >= s->nb_streams)
baf25c9d 1594 return -1;
baf25c9d 1595
b72708f8
BC
1596 st = s->streams[stream_index];
1597 sample = mov_seek_stream(st, sample_time, flags);
1598 if (sample < 0)
baf25c9d 1599 return -1;
baf25c9d 1600
b72708f8
BC
1601 /* adjust seek timestamp to found sample timestamp */
1602 seek_timestamp = st->index_entries[sample].timestamp;
baf25c9d 1603
b72708f8
BC
1604 for (i = 0; i < s->nb_streams; i++) {
1605 st = s->streams[i];
1606 if (stream_index == i || st->discard == AVDISCARD_ALL)
1607 continue;
baf25c9d 1608
b72708f8
BC
1609 timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
1610 mov_seek_stream(st, timestamp, flags);
115329f1 1611 }
baf25c9d
GC
1612 return 0;
1613}
baf25c9d 1614
a266644f 1615static int mov_read_close(AVFormatContext *s)
6cea494e
ZK
1616{
1617 int i;
e4141433 1618 MOVContext *mov = s->priv_data;
11f16b66 1619 for(i=0; i<s->nb_streams; i++) {
7c622eed
BC
1620 MOVStreamContext *sc = s->streams[i]->priv_data;
1621 av_freep(&sc->ctts_data);
4440b118 1622 }
b60c0454
BC
1623 if(mov->dv_demux){
1624 for(i=0; i<mov->dv_fctx->nb_streams; i++){
1625 av_freep(&mov->dv_fctx->streams[i]->codec);
1626 av_freep(&mov->dv_fctx->streams[i]);
1627 }
1628 av_freep(&mov->dv_fctx);
1629 av_freep(&mov->dv_demux);
1630 }
6cea494e
ZK
1631 return 0;
1632}
1633
ff70e601 1634AVInputFormat mov_demuxer = {
fc5188f3
BC
1635 "mov,mp4,m4a,3gp,3g2,mj2",
1636 "QuickTime/MPEG4/Motion JPEG 2000 format",
c9a65ca8
FB
1637 sizeof(MOVContext),
1638 mov_probe,
6cea494e
ZK
1639 mov_read_header,
1640 mov_read_packet,
1641 mov_read_close,
baf25c9d 1642 mov_read_seek,
6cea494e 1643};