Statistics
| Branch: | Revision:

ffmpeg / libavformat / mov.c @ 5509bffa

History | View | Annotate | Download (83.4 KB)

1 6cea494e Zdenek Kabelac
/*
2
 * MOV decoder.
3 19720f15 Fabrice Bellard
 * Copyright (c) 2001 Fabrice Bellard.
4 6cea494e Zdenek Kabelac
 *
5 19720f15 Fabrice Bellard
 * 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 6cea494e Zdenek Kabelac
 *
10 19720f15 Fabrice Bellard
 * This library is distributed in the hope that it will be useful,
11 6cea494e Zdenek Kabelac
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 19720f15 Fabrice Bellard
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14 6cea494e Zdenek Kabelac
 *
15 19720f15 Fabrice Bellard
 * 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 5509bffa Diego Biurrun
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 6cea494e Zdenek Kabelac
 */
19 d957696f Michael Niedermayer
20
#include <limits.h>
21 115329f1 Diego Biurrun
22 6cea494e Zdenek Kabelac
#include "avformat.h"
23
#include "avi.h"
24
25 0147f198 François Revol
#ifdef CONFIG_ZLIB
26
#include <zlib.h>
27
#endif
28
29 6cea494e Zdenek Kabelac
/*
30
 * First version by Francois Revol revol@free.fr
31 115329f1 Diego Biurrun
 * Seek function by Gael Chardon gael.dev@4now.net
32 5ca1d879 Zdenek Kabelac
 *
33 6cea494e Zdenek Kabelac
 * Features and limitations:
34 5ca1d879 Zdenek Kabelac
 * - reads most of the QT files I have (at least the structure),
35 6cea494e Zdenek Kabelac
 *   the exceptions are .mov with zlib compressed headers ('cmov' section). It shouldn't be hard to implement.
36 0147f198 François Revol
 *   FIXED, Francois Revol, 07/17/2002
37 6cea494e Zdenek Kabelac
 * - ffmpeg has nearly none of the usual QuickTime codecs,
38
 *   although I succesfully dumped raw and mp3 audio tracks off .mov files.
39
 *   Sample QuickTime files with mp3 audio can be found at: http://www.3ivx.com/showcase.html
40
 * - .mp4 parsing is still hazardous, although the format really is QuickTime with some minor changes
41
 *   (to make .mov parser crash maybe ?), despite what they say in the MPEG FAQ at
42
 *   http://mpeg.telecomitalialab.com/faq.htm
43
 * - the code is quite ugly... maybe I won't do it recursive next time :-)
44 baf25c9d Gael Chardon
 * - seek is not supported with files that contain edit list
45 5ca1d879 Zdenek Kabelac
 *
46 6cea494e Zdenek Kabelac
 * Funny I didn't know about http://sourceforge.net/projects/qt-ffmpeg/
47
 * when coding this :) (it's a writer anyway)
48 5ca1d879 Zdenek Kabelac
 *
49 6cea494e Zdenek Kabelac
 * Reference documents:
50
 * http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
51
 * Apple:
52 baf25c9d Gael Chardon
 *  http://developer.apple.com/documentation/QuickTime/QTFF/
53 15c8dbe7 Sebastien Bechet
 *  http://developer.apple.com/documentation/QuickTime/QTFF/qtff.pdf
54 6cea494e Zdenek Kabelac
 * QuickTime is a trademark of Apple (AFAIK :))
55
 */
56
57 c9a65ca8 Fabrice Bellard
//#define DEBUG
58 9ed83b0a Zdenek Kabelac
#ifdef DEBUG
59
#include <stdio.h>
60
#include <fcntl.h>
61
#endif
62 6cea494e Zdenek Kabelac
63 b595afaa Mike Melanson
#include "qtpalette.h"
64
65 baf25c9d Gael Chardon
66
/* Allows seeking (MOV_SPLIT_CHUNKS should also be defined) */
67
#define MOV_SEEK
68
69 3ffe3793 François Revol
/* allows chunk splitting - should work now... */
70
/* in case you can't read a file, try commenting */
71
#define MOV_SPLIT_CHUNKS
72
73 14342fd5 Johannes Carlsson
/* Special handling for movies created with Minolta Dimaxe Xi*/
74
/* this fix should not interfere with other .mov files, but just in case*/
75
#define MOV_MINOLTA_FIX
76
77 6cea494e Zdenek Kabelac
/* some streams in QT (and in MP4 mostly) aren't either video nor audio */
78
/* so we first list them as this, then clean up the list of streams we give back, */
79
/* getting rid of these */
80 bb270c08 Diego Biurrun
#define CODEC_TYPE_MOV_OTHER    (enum CodecType) 2
81 6cea494e Zdenek Kabelac
82 a266644f Zdenek Kabelac
static const CodecTag mov_video_tags[] = {
83 6cea494e Zdenek Kabelac
/*  { CODEC_ID_, MKTAG('c', 'v', 'i', 'd') }, *//* Cinepak */
84 0147f198 François Revol
/*  { CODEC_ID_H263, MKTAG('r', 'a', 'w', ' ') }, *//* Uncompressed RGB */
85
/*  { CODEC_ID_H263, MKTAG('Y', 'u', 'v', '2') }, *//* Uncompressed YUV422 */
86 53e27dd5 Sebastien Bechet
/*    { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'U', 'I') }, *//* YUV with alpha-channel (AVID Uncompressed) */
87 6cea494e Zdenek Kabelac
/* Graphics */
88
/* Animation */
89
/* Apple video */
90
/* Kodak Photo CD */
91 3ffe3793 François Revol
    { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */
92 6cea494e Zdenek Kabelac
    { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
93 3ffe3793 François Revol
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */
94 6cea494e Zdenek Kabelac
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */
95 53e27dd5 Sebastien Bechet
    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */
96
/*    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */
97 6cea494e Zdenek Kabelac
/*    { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, *//* embedded gif files as frames (usually one "click to play movie" frame) */
98
/* Sorenson video */
99 0147f198 François Revol
    { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */
100
    { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */
101 3ffe3793 François Revol
    { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/
102 8b82a956 Michael Niedermayer
    { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */
103 0e7eed09 Fabrice Bellard
    { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
104 6cea494e Zdenek Kabelac
    { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
105 8dafdb88 Mike Melanson
    { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
106 fcc87242 François Revol
    { CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, /* experimental: 3IVX files before ivx D4 4.5.1 */
107 6cea494e Zdenek Kabelac
/*    { CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */
108 0147f198 François Revol
    { CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H263 */
109 25fa62e1 Zdenek Kabelac
    { CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H263 ?? works */
110 e1687cc0 Fabrice Bellard
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */
111
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */
112 53e27dd5 Sebastien Bechet
/*    { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, *//* AVID dv */
113 d86053a4 Mike Melanson
    { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */
114 2fdf638b Mike Melanson
    { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */
115
    { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */
116 1dc1ed99 Roberto Togni
    { CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */
117 b595afaa Mike Melanson
    { CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */
118 070ed1bc Mike Melanson
    { CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */
119 d08d7142 Mike Melanson
    { CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */
120 169eb021 Mike Melanson
    { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */
121 a3075830 Aurelien Jacobs
    { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 produced by Sony HD camera */
122 5ca1d879 Zdenek Kabelac
    { CODEC_ID_NONE, 0 },
123 6cea494e Zdenek Kabelac
};
124
125 a266644f Zdenek Kabelac
static const CodecTag mov_audio_tags[] = {
126 6cea494e Zdenek Kabelac
/*    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */
127
    { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
128 5ca1d879 Zdenek Kabelac
    /* { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') },*/ /* 8 bits */
129 5cd62665 Zdenek Kabelac
    { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
130 6cea494e Zdenek Kabelac
    { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /*  */
131
    { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /*  */
132
    { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /*  */
133 0147f198 François Revol
    { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */
134 3f95e843 François Revol
    { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */
135
    { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */
136 6cea494e Zdenek Kabelac
137
    { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */
138
    { CODEC_ID_MP2, 0x6D730055 }, /* MPEG layer 3 */
139
    { CODEC_ID_MP2, 0x5500736D }, /* MPEG layer 3 *//* XXX: check endianness */
140
/*    { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
141
/* MP4 tags */
142 f2196640 François Revol
    { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, /* MPEG-4 AAC */
143 5ca1d879 Zdenek Kabelac
    /* The standard for mpeg4 audio is still not normalised AFAIK anyway */
144 891f64b3 joca@rixmail.se
    { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */
145 d663a1fd Michael Niedermayer
    { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */
146 8dafdb88 Mike Melanson
    { CODEC_ID_AC3, MKTAG('m', 's', 0x20, 0x00) }, /* Dolby AC-3 */
147 6d6d7970 Mike Melanson
    { CODEC_ID_ALAC,MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */
148 d9b1c197 Roberto Togni
    { CODEC_ID_QDM2,MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */
149 5ca1d879 Zdenek Kabelac
    { CODEC_ID_NONE, 0 },
150 6cea494e Zdenek Kabelac
};
151
152 b9a87c4d François Revol
/* map numeric codes from mdhd atom to ISO 639 */
153
/* cf. QTFileFormat.pdf p253, qtff.pdf p205 */
154 ab561df9 François Revol
/* http://developer.apple.com/documentation/mac/Text/Text-368.html */
155
/* deprecated by putting the code as 3*5bit ascii */
156 b9a87c4d François Revol
static const char *mov_mdhd_language_map[] = { 
157
/* 0-9 */
158
"eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor", 
159
"heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/, 
160
"urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav",  NULL, 
161
"fo ",  NULL, "rus", "chi",  NULL, "iri", "alb", "ron", "ces", "slk", 
162
"slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
163
/*?*/ 
164
"aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon",  NULL, "pus",
165
"kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
166
"pa ", "ori", "mal", "kan", "tam", "tel",  NULL, "bur", "khm", "lao",
167
/*                   roman? arabic? */
168
"vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
169
/*==rundi?*/
170
 NULL, "run",  NULL, "mlg", "epo",  NULL,  NULL,  NULL,  NULL,  NULL, 
171
/* 100 */
172
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, 
173
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, 
174
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, "wel", "baq",
175
"cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
176
};
177
178 6cea494e Zdenek Kabelac
/* the QuickTime file format is quite convoluted...
179
 * it has lots of index tables, each indexing something in another one...
180
 * Here we just use what is needed to read the chunks
181
 */
182
183
typedef struct MOV_sample_to_chunk_tbl {
184
    long first;
185
    long count;
186
    long id;
187
} MOV_sample_to_chunk_tbl;
188
189 5cd62665 Zdenek Kabelac
typedef struct {
190 5ca1d879 Zdenek Kabelac
    uint32_t type;
191
    int64_t offset;
192
    int64_t size; /* total size (excluding the size and type fields) */
193
} MOV_atom_t;
194
195
typedef struct {
196
    int seed;
197
    int flags;
198
    int size;
199
    void* clrs;
200
} MOV_ctab_t;
201
202
typedef struct {
203 5cd62665 Zdenek Kabelac
    uint8_t  version;
204
    uint32_t flags; // 24bit
205
206
    /* 0x03 ESDescrTag */
207
    uint16_t es_id;
208 bb270c08 Diego Biurrun
#define MP4ODescrTag                    0x01
209
#define MP4IODescrTag                   0x02
210
#define MP4ESDescrTag                   0x03
211
#define MP4DecConfigDescrTag            0x04
212
#define MP4DecSpecificDescrTag          0x05
213
#define MP4SLConfigDescrTag             0x06
214
#define MP4ContentIdDescrTag            0x07
215
#define MP4SupplContentIdDescrTag       0x08
216
#define MP4IPIPtrDescrTag               0x09
217
#define MP4IPMPPtrDescrTag              0x0A
218
#define MP4IPMPDescrTag                 0x0B
219
#define MP4RegistrationDescrTag         0x0D
220
#define MP4ESIDIncDescrTag              0x0E
221
#define MP4ESIDRefDescrTag              0x0F
222
#define MP4FileIODescrTag               0x10
223
#define MP4FileODescrTag                0x11
224
#define MP4ExtProfileLevelDescrTag      0x13
225
#define MP4ExtDescrTagsStart            0x80
226
#define MP4ExtDescrTagsEnd              0xFE
227 5cd62665 Zdenek Kabelac
    uint8_t  stream_priority;
228
229
    /* 0x04 DecConfigDescrTag */
230
    uint8_t  object_type_id;
231
    uint8_t  stream_type;
232
    /* XXX: really streamType is
233
     * only 6bit, followed by:
234
     * 1bit  upStream
235
     * 1bit  reserved
236
     */
237
    uint32_t buffer_size_db; // 24
238
    uint32_t max_bitrate;
239
    uint32_t avg_bitrate;
240
241
    /* 0x05 DecSpecificDescrTag */
242
    uint8_t  decoder_cfg_len;
243
    uint8_t *decoder_cfg;
244
245
    /* 0x06 SLConfigDescrTag */
246
    uint8_t  sl_config_len;
247
    uint8_t *sl_config;
248
} MOV_esds_t;
249
250 b6a17df4 Zdenek Kabelac
struct MOVParseTableEntry;
251
252 cd461d48 Michael Niedermayer
typedef struct Time2Sample{
253
    int count;
254
    int duration;
255
}Time2Sample;
256
257 6cea494e Zdenek Kabelac
typedef struct MOVStreamContext {
258
    int ffindex; /* the ffmpeg stream id */
259
    int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */
260
    long next_chunk;
261
    long chunk_count;
262 0c1a9eda Zdenek Kabelac
    int64_t *chunk_offsets;
263 cd461d48 Michael Niedermayer
    int stts_count;
264
    Time2Sample *stts_data;
265 c4ac052b Michael Niedermayer
    int ctts_count;
266
    Time2Sample *ctts_data;
267 cd461d48 Michael Niedermayer
    int edit_count;             /* number of 'edit' (elst atom) */
268 6cea494e Zdenek Kabelac
    long sample_to_chunk_sz;
269
    MOV_sample_to_chunk_tbl *sample_to_chunk;
270 3ffe3793 François Revol
    long sample_to_chunk_index;
271 115329f1 Diego Biurrun
    int sample_to_time_index;
272
    long sample_to_time_sample;
273
    uint64_t sample_to_time_time;
274 c4ac052b Michael Niedermayer
    int sample_to_ctime_index;
275
    int sample_to_ctime_sample;
276 6cea494e Zdenek Kabelac
    long sample_size;
277
    long sample_count;
278
    long *sample_sizes;
279 247d56f5 Brian Becker
    long keyframe_count;
280
    long *keyframes;
281 5cd62665 Zdenek Kabelac
    int time_scale;
282 3ffe3793 François Revol
    long current_sample;
283
    long left_in_chunk; /* how many samples before next chunk */
284 5ca1d879 Zdenek Kabelac
    MOV_esds_t esds;
285 6cea494e Zdenek Kabelac
} MOVStreamContext;
286
287
typedef struct MOVContext {
288
    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) */
289
    AVFormatContext *fc;
290 5cd62665 Zdenek Kabelac
    int time_scale;
291
    int duration; /* duration of the longest track */
292 6cea494e Zdenek Kabelac
    int found_moov; /* when both 'moov' and 'mdat' sections has been found */
293
    int found_mdat; /* we suppose we have enough data to read the file */
294 0c1a9eda Zdenek Kabelac
    int64_t mdat_size;
295
    int64_t mdat_offset;
296 86d8602f Michael Niedermayer
    int ni;                                         ///< non interleaved mode
297 6cea494e Zdenek Kabelac
    int total_streams;
298
    /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio
299
     * but we need the info to be able to skip data from those streams in the 'mdat' section
300
     */
301
    MOVStreamContext *streams[MAX_STREAMS];
302 5cd62665 Zdenek Kabelac
303 0c1a9eda Zdenek Kabelac
    int64_t next_chunk_offset;
304 5cd62665 Zdenek Kabelac
    MOVStreamContext *partial; /* != 0 : there is still to read in the current chunk */
305 5ca1d879 Zdenek Kabelac
    int ctab_size;
306
    MOV_ctab_t **ctab;           /* color tables */
307 b6a17df4 Zdenek Kabelac
    const struct MOVParseTableEntry *parse_table; /* could be eventually used to change the table */
308
    /* NOTE: for recursion save to/ restore from local variable! */
309 b595afaa Mike Melanson
310
    AVPaletteControl palette_control;
311 6cea494e Zdenek Kabelac
} MOVContext;
312
313
314
/* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */
315
316
/* those functions parse an atom */
317
/* return code:
318
 1: found what I wanted, exit
319
 0: continue to parse next atom
320
 -1: error occured, exit
321
 */
322 5ca1d879 Zdenek Kabelac
typedef int (*mov_parse_function)(MOVContext *ctx, ByteIOContext *pb, MOV_atom_t atom);
323 6cea494e Zdenek Kabelac
324
/* links atom IDs to parse functions */
325
typedef struct MOVParseTableEntry {
326 0c1a9eda Zdenek Kabelac
    uint32_t type;
327 6cea494e Zdenek Kabelac
    mov_parse_function func;
328
} MOVParseTableEntry;
329
330 5ca1d879 Zdenek Kabelac
#ifdef DEBUG
331
/*
332
 * XXX: static sux, even more in a multithreaded environment...
333
 * Avoid them. This is here just to help debugging.
334
 */
335
static int debug_indent = 0;
336
void print_atom(const char *str, MOV_atom_t atom)
337
{
338
    unsigned int tag, i;
339
    tag = (unsigned int) atom.type;
340
    i=debug_indent;
341
    if(tag == 0) tag = MKTAG('N', 'U', 'L', 'L');
342
    while(i--)
343 baf25c9d Gael Chardon
        av_log(NULL, AV_LOG_DEBUG, "|");
344
    av_log(NULL, AV_LOG_DEBUG, "parse:");
345
    av_log(NULL, AV_LOG_DEBUG, " %s: tag=%c%c%c%c offset=0x%x size=0x%x\n",
346 5ca1d879 Zdenek Kabelac
           str, tag & 0xff,
347
           (tag >> 8) & 0xff,
348
           (tag >> 16) & 0xff,
349
           (tag >> 24) & 0xff,
350
           (unsigned int)atom.offset,
351 bb270c08 Diego Biurrun
           (unsigned int)atom.size);
352 5ca1d879 Zdenek Kabelac
    assert((unsigned int)atom.size < 0x7fffffff);// catching errors
353
}
354
#else
355
#define print_atom(a,b)
356
#endif
357
358 ab561df9 François Revol
static int ff_mov_lang_to_iso639(int code, char *to)
359 b9a87c4d François Revol
{
360 ab561df9 François Revol
    int i;
361
    /* is it the mangled iso code? */
362
    /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */
363
    if (code > 138) {
364
        for (i = 2; i >= 0; i--) {
365
            to[i] = 0x60 + (code & 0x1f);
366
            code >>= 5;
367
        }
368
        return 1;
369
    }
370
    /* old fashion apple lang code */
371 b9a87c4d François Revol
    if (code >= (sizeof(mov_mdhd_language_map)/sizeof(char *)))
372 ab561df9 François Revol
        return 0;
373 b9a87c4d François Revol
    if (!mov_mdhd_language_map[code])
374 ab561df9 François Revol
        return 0;
375
    strncpy(to, mov_mdhd_language_map[code], 4);
376
    return 1;
377 b9a87c4d François Revol
}
378
379 ab561df9 François Revol
extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */
380
int ff_mov_iso639_to_lang(const char *lang, int mp4)
381 b9a87c4d François Revol
{
382 ab561df9 François Revol
    int i, code = 0;
383
    
384
    /* old way, only for QT? */
385
    for (i = 0; !mp4 && (i < (sizeof(mov_mdhd_language_map)/sizeof(char *))); i++) {
386 b9a87c4d François Revol
        if (mov_mdhd_language_map[i] && !strcmp(lang, mov_mdhd_language_map[i]))
387
            return i;
388
    }
389 ab561df9 François Revol
    /* XXX:can we do that in mov too? */
390
    if (!mp4)
391
        return 0;
392
    /* handle undefined as such */
393
    if (lang[0] == '\0')
394
        lang = "und";
395
    /* 5bit ascii */
396
    for (i = 0; i < 3; i++) {
397
        unsigned char c = (unsigned char)lang[i];
398
        if (c < 0x60)
399
            return 0;
400
        if (c > 0x60 + 0x1f)
401
            return 0;
402
        code <<= 5;
403
        code |= (c - 0x60);
404
    }
405
    return code;
406 b9a87c4d François Revol
}
407 5ca1d879 Zdenek Kabelac
408
static int mov_read_leaf(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
409 6cea494e Zdenek Kabelac
{
410 5ca1d879 Zdenek Kabelac
    print_atom("leaf", atom);
411 b6a17df4 Zdenek Kabelac
412 5ca1d879 Zdenek Kabelac
    if (atom.size>1)
413
        url_fskip(pb, atom.size);
414
/*        url_seek(pb, atom_offset+atom.size, SEEK_SET); */
415 6cea494e Zdenek Kabelac
    return 0;
416
}
417
418 5ca1d879 Zdenek Kabelac
static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
419 6cea494e Zdenek Kabelac
{
420 b6a17df4 Zdenek Kabelac
    int64_t total_size = 0;
421 5ca1d879 Zdenek Kabelac
    MOV_atom_t a;
422 6cea494e Zdenek Kabelac
    int i;
423
    int err = 0;
424 5ca1d879 Zdenek Kabelac
425 6cea494e Zdenek Kabelac
#ifdef DEBUG
426 5ca1d879 Zdenek Kabelac
    print_atom("default", atom);
427 6cea494e Zdenek Kabelac
    debug_indent++;
428
#endif
429 5cd62665 Zdenek Kabelac
430 5ca1d879 Zdenek Kabelac
    a.offset = atom.offset;
431 6cea494e Zdenek Kabelac
432 9ed83b0a Zdenek Kabelac
    if (atom.size < 0)
433 bb270c08 Diego Biurrun
        atom.size = 0x7fffffffffffffffLL;
434 5ca1d879 Zdenek Kabelac
    while(((total_size + 8) < atom.size) && !url_feof(pb) && !err) {
435 bb270c08 Diego Biurrun
        a.size = atom.size;
436
        a.type=0L;
437 5ca1d879 Zdenek Kabelac
        if(atom.size >= 8) {
438 bb270c08 Diego Biurrun
            a.size = get_be32(pb);
439 5ca1d879 Zdenek Kabelac
            a.type = get_le32(pb);
440 6cea494e Zdenek Kabelac
        }
441 bb270c08 Diego Biurrun
        total_size += 8;
442 5ca1d879 Zdenek Kabelac
        a.offset += 8;
443 bb270c08 Diego Biurrun
        //av_log(NULL, AV_LOG_DEBUG, "type: %08x  %.4s  sz: %Lx  %Lx   %Lx\n", type, (char*)&type, size, atom.size, total_size);
444 5ca1d879 Zdenek Kabelac
        if (a.size == 1) { /* 64 bit extended size */
445 bb270c08 Diego Biurrun
            a.size = get_be64(pb) - 8;
446 5ca1d879 Zdenek Kabelac
            a.offset += 8;
447
            total_size += 8;
448 6cea494e Zdenek Kabelac
        }
449 bb270c08 Diego Biurrun
        if (a.size == 0) {
450
            a.size = atom.size - total_size;
451
            if (a.size <= 8)
452 5cd62665 Zdenek Kabelac
                break;
453 bb270c08 Diego Biurrun
        }
454
        for (i = 0; c->parse_table[i].type != 0L
455
             && c->parse_table[i].type != a.type; i++)
456
            /* empty */;
457 5cd62665 Zdenek Kabelac
458 bb270c08 Diego Biurrun
        a.size -= 8;
459 115329f1 Diego Biurrun
460 568e18b1 Michael Niedermayer
        if(a.size < 0)
461
            break;
462 115329f1 Diego Biurrun
463 baf25c9d Gael Chardon
//        av_log(NULL, AV_LOG_DEBUG, " i=%ld\n", i);
464 bb270c08 Diego Biurrun
        if (c->parse_table[i].type == 0) { /* skip leaf atoms data */
465 5ca1d879 Zdenek Kabelac
//            url_seek(pb, atom.offset+atom.size, SEEK_SET);
466 6cea494e Zdenek Kabelac
#ifdef DEBUG
467 5ca1d879 Zdenek Kabelac
            print_atom("unknown", a);
468 6cea494e Zdenek Kabelac
#endif
469 5ca1d879 Zdenek Kabelac
            url_fskip(pb, a.size);
470 bb270c08 Diego Biurrun
        } else {
471 b6a17df4 Zdenek Kabelac
#ifdef DEBUG
472 bb270c08 Diego Biurrun
            //char b[5] = { type & 0xff, (type >> 8) & 0xff, (type >> 16) & 0xff, (type >> 24) & 0xff, 0 };
473
            //print_atom(b, type, offset, size);
474 b6a17df4 Zdenek Kabelac
#endif
475 bb270c08 Diego Biurrun
            err = (c->parse_table[i].func)(c, pb, a);
476
        }
477 6cea494e Zdenek Kabelac
478 bb270c08 Diego Biurrun
        a.offset += a.size;
479 5ca1d879 Zdenek Kabelac
        total_size += a.size;
480 6cea494e Zdenek Kabelac
    }
481
482 5ca1d879 Zdenek Kabelac
    if (!err && total_size < atom.size && atom.size < 0x7ffff) {
483 bb270c08 Diego Biurrun
        //av_log(NULL, AV_LOG_DEBUG, "RESET  %Ld  %Ld  err:%d\n", atom.size, total_size, err);
484 5ca1d879 Zdenek Kabelac
        url_fskip(pb, atom.size - total_size);
485 5cd62665 Zdenek Kabelac
    }
486
487 6cea494e Zdenek Kabelac
#ifdef DEBUG
488
    debug_indent--;
489
#endif
490
    return err;
491
}
492
493 5ca1d879 Zdenek Kabelac
static int mov_read_ctab(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
494 6cea494e Zdenek Kabelac
{
495 568e18b1 Michael Niedermayer
#if 1
496
    url_fskip(pb, atom.size); // for now
497
#else
498
    VERY VERY BROKEN, NEVER execute this, needs rewrite
499 88730be6 Måns Rullgård
    unsigned int len;
500
    MOV_ctab_t *t;
501 5ca1d879 Zdenek Kabelac
    c->ctab = av_realloc(c->ctab, ++c->ctab_size);
502
    t = c->ctab[c->ctab_size];
503
    t->seed = get_be32(pb);
504
    t->flags = get_be16(pb);
505
    t->size = get_be16(pb) + 1;
506
    len = 2 * t->size * 4;
507
    if (len > 0) {
508 bb270c08 Diego Biurrun
        t->clrs = av_malloc(len); // 16bit A R G B
509
        if (t->clrs)
510
            get_buffer(pb, t->clrs, len);
511 3ffe3793 François Revol
    }
512 568e18b1 Michael Niedermayer
#endif
513 5cd62665 Zdenek Kabelac
514 0147f198 François Revol
    return 0;
515
}
516
517 5ca1d879 Zdenek Kabelac
static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
518 6cea494e Zdenek Kabelac
{
519 5ca1d879 Zdenek Kabelac
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
520 3ffe3793 François Revol
    int len = 0;
521 0c1a9eda Zdenek Kabelac
    uint32_t type;
522
    uint32_t ctype;
523 b6a17df4 Zdenek Kabelac
524 5ca1d879 Zdenek Kabelac
    print_atom("hdlr", atom);
525 6cea494e Zdenek Kabelac
526
    get_byte(pb); /* version */
527
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
528
529
    /* component type */
530
    ctype = get_le32(pb);
531
    type = get_le32(pb); /* component subtype */
532
533
#ifdef DEBUG
534 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "ctype= %c%c%c%c (0x%08lx)\n", *((char *)&ctype), ((char *)&ctype)[1], ((char *)&ctype)[2], ((char *)&ctype)[3], (long) ctype);
535
    av_log(NULL, AV_LOG_DEBUG, "stype= %c%c%c%c\n", *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]);
536 6cea494e Zdenek Kabelac
#endif
537
#ifdef DEBUG
538
/* XXX: yeah this is ugly... */
539
    if(ctype == MKTAG('m', 'h', 'l', 'r')) { /* MOV */
540
        if(type == MKTAG('v', 'i', 'd', 'e'))
541
            puts("hdlr: vide");
542
        else if(type == MKTAG('s', 'o', 'u', 'n'))
543
            puts("hdlr: soun");
544
    } else if(ctype == 0) { /* MP4 */
545
        if(type == MKTAG('v', 'i', 'd', 'e'))
546
            puts("hdlr: vide");
547
        else if(type == MKTAG('s', 'o', 'u', 'n'))
548
            puts("hdlr: soun");
549
        else if(type == MKTAG('o', 'd', 's', 'm'))
550
            puts("hdlr: odsm");
551
        else if(type == MKTAG('s', 'd', 's', 'm'))
552
            puts("hdlr: sdsm");
553
    } else puts("hdlr: meta");
554
#endif
555
556
    if(ctype == MKTAG('m', 'h', 'l', 'r')) { /* MOV */
557 0147f198 François Revol
        /* helps parsing the string hereafter... */
558
        c->mp4 = 0;
559 6cea494e Zdenek Kabelac
        if(type == MKTAG('v', 'i', 'd', 'e'))
560 01f4895c Michael Niedermayer
            st->codec->codec_type = CODEC_TYPE_VIDEO;
561 6cea494e Zdenek Kabelac
        else if(type == MKTAG('s', 'o', 'u', 'n'))
562 01f4895c Michael Niedermayer
            st->codec->codec_type = CODEC_TYPE_AUDIO;
563 6cea494e Zdenek Kabelac
    } else if(ctype == 0) { /* MP4 */
564 0147f198 François Revol
        /* helps parsing the string hereafter... */
565
        c->mp4 = 1;
566 6cea494e Zdenek Kabelac
        if(type == MKTAG('v', 'i', 'd', 'e'))
567 01f4895c Michael Niedermayer
            st->codec->codec_type = CODEC_TYPE_VIDEO;
568 6cea494e Zdenek Kabelac
        else if(type == MKTAG('s', 'o', 'u', 'n'))
569 01f4895c Michael Niedermayer
            st->codec->codec_type = CODEC_TYPE_AUDIO;
570 6cea494e Zdenek Kabelac
    }
571
    get_be32(pb); /* component  manufacture */
572
    get_be32(pb); /* component flags */
573
    get_be32(pb); /* component flags mask */
574
575 5ca1d879 Zdenek Kabelac
    if(atom.size <= 24)
576 6cea494e Zdenek Kabelac
        return 0; /* nothing left to read */
577
    /* XXX: MP4 uses a C string, not a pascal one */
578
    /* component name */
579 0147f198 François Revol
580
    if(c->mp4) {
581
        /* .mp4: C string */
582 5ca1d879 Zdenek Kabelac
        while(get_byte(pb) && (++len < (atom.size - 24)));
583 0147f198 François Revol
    } else {
584
        /* .mov: PASCAL string */
585 9ed83b0a Zdenek Kabelac
#ifdef DEBUG
586
        char* buf;
587
#endif
588 0147f198 François Revol
        len = get_byte(pb);
589 5ca1d879 Zdenek Kabelac
#ifdef DEBUG
590 bb270c08 Diego Biurrun
        buf = (uint8_t*) av_malloc(len+1);
591
        if (buf) {
592
            get_buffer(pb, buf, len);
593
            buf[len] = '\0';
594
            av_log(NULL, AV_LOG_DEBUG, "**buf='%s'\n", buf);
595
            av_free(buf);
596
        } else
597
#endif
598
            url_fskip(pb, len);
599 6cea494e Zdenek Kabelac
    }
600 5cd62665 Zdenek Kabelac
601 3c13647a Cedric Vincent
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
602 6cea494e Zdenek Kabelac
    return 0;
603
}
604
605 5ca1d879 Zdenek Kabelac
static int mov_mp4_read_descr_len(ByteIOContext *pb)
606 0e7eed09 Fabrice Bellard
{
607 5cd62665 Zdenek Kabelac
    int len = 0;
608 5ca1d879 Zdenek Kabelac
    int count = 4;
609
    while (count--) {
610 5cd62665 Zdenek Kabelac
        int c = get_byte(pb);
611 bb270c08 Diego Biurrun
        len = (len << 7) | (c & 0x7f);
612
        if (!(c & 0x80))
613
            break;
614 0e7eed09 Fabrice Bellard
    }
615
    return len;
616
}
617
618 5ca1d879 Zdenek Kabelac
static int mov_mp4_read_descr(ByteIOContext *pb, int *tag)
619 0e7eed09 Fabrice Bellard
{
620
    int len;
621
    *tag = get_byte(pb);
622 5ca1d879 Zdenek Kabelac
    len = mov_mp4_read_descr_len(pb);
623 0e7eed09 Fabrice Bellard
#ifdef DEBUG
624 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
625 0e7eed09 Fabrice Bellard
#endif
626
    return len;
627
}
628
629 5ca1d879 Zdenek Kabelac
static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
630 5cd62665 Zdenek Kabelac
{
631
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
632
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
633 5ca1d879 Zdenek Kabelac
    int64_t start_pos = url_ftell(pb);
634 5cd62665 Zdenek Kabelac
    int tag, len;
635 b6a17df4 Zdenek Kabelac
636 5ca1d879 Zdenek Kabelac
    print_atom("esds", atom);
637 5cd62665 Zdenek Kabelac
638
    /* Well, broken but suffisant for some MP4 streams */
639
    get_be32(pb); /* version + flags */
640 5ca1d879 Zdenek Kabelac
    len = mov_mp4_read_descr(pb, &tag);
641 5cd62665 Zdenek Kabelac
    if (tag == MP4ESDescrTag) {
642 bb270c08 Diego Biurrun
        get_be16(pb); /* ID */
643
        get_byte(pb); /* priority */
644 5cd62665 Zdenek Kabelac
    } else
645 bb270c08 Diego Biurrun
        get_be16(pb); /* ID */
646 5cd62665 Zdenek Kabelac
647 5ca1d879 Zdenek Kabelac
    len = mov_mp4_read_descr(pb, &tag);
648 5cd62665 Zdenek Kabelac
    if (tag == MP4DecConfigDescrTag) {
649 bb270c08 Diego Biurrun
        sc->esds.object_type_id = get_byte(pb);
650
        sc->esds.stream_type = get_byte(pb);
651
        sc->esds.buffer_size_db = get_be24(pb);
652
        sc->esds.max_bitrate = get_be32(pb);
653
        sc->esds.avg_bitrate = get_be32(pb);
654
655
        len = mov_mp4_read_descr(pb, &tag);
656
        //av_log(NULL, AV_LOG_DEBUG, "LEN %d  TAG %d  m:%d a:%d\n", len, tag, sc->esds.max_bitrate, sc->esds.avg_bitrate);
657
        if (tag == MP4DecSpecificDescrTag) {
658 5cd62665 Zdenek Kabelac
#ifdef DEBUG
659 bb270c08 Diego Biurrun
            av_log(NULL, AV_LOG_DEBUG, "Specific MPEG4 header len=%d\n", len);
660
#endif
661
            st->codec->extradata = (uint8_t*) av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
662
            if (st->codec->extradata) {
663
                get_buffer(pb, st->codec->extradata, len);
664
                st->codec->extradata_size = len;
665
            }
666
        }
667 5cd62665 Zdenek Kabelac
    }
668
    /* in any case, skip garbage */
669 5ca1d879 Zdenek Kabelac
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
670 5cd62665 Zdenek Kabelac
    return 0;
671
}
672
673 5ca1d879 Zdenek Kabelac
/* this atom contains actual media data */
674
static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
675 6cea494e Zdenek Kabelac
{
676 5ca1d879 Zdenek Kabelac
    print_atom("mdat", atom);
677
678
    if(atom.size == 0) /* wrong one (MP4) */
679
        return 0;
680
    c->found_mdat=1;
681
    c->mdat_offset = atom.offset;
682
    c->mdat_size = atom.size;
683
    if(c->found_moov)
684
        return 1; /* found both, just go */
685
    url_fskip(pb, atom.size);
686
    return 0; /* now go for moov */
687
}
688
689
/* this atom should contain all header atoms */
690
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
691
{
692
    int err;
693 b6a17df4 Zdenek Kabelac
694 5ca1d879 Zdenek Kabelac
    print_atom("moov", atom);
695 b6a17df4 Zdenek Kabelac
696 5ca1d879 Zdenek Kabelac
    err = mov_read_default(c, pb, atom);
697
    /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
698
    /* so we don't parse the whole file if over a network */
699
    c->found_moov=1;
700
    if(c->found_mdat)
701
        return 1; /* found both, just go */
702
    return 0; /* now go for mdat */
703
}
704
705
706
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
707
{
708 b9a87c4d François Revol
    int version;
709
    int lang;
710 5ca1d879 Zdenek Kabelac
    print_atom("mdhd", atom);
711
712 b9a87c4d François Revol
    version = get_byte(pb); /* version */
713
    if (version > 1)
714
        return 1; /* unsupported */
715 5ca1d879 Zdenek Kabelac
716
    get_byte(pb); get_byte(pb);
717
    get_byte(pb); /* flags */
718
719 b9a87c4d François Revol
    (version==1)?get_be64(pb):get_be32(pb); /* creation time */
720
    (version==1)?get_be64(pb):get_be32(pb); /* modification time */
721 5ca1d879 Zdenek Kabelac
722 baf25c9d Gael Chardon
    c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb);
723 da7272b3 Michael Niedermayer
    av_set_pts_info(c->fc->streams[c->fc->nb_streams-1], 64, 1, c->streams[c->fc->nb_streams-1]->time_scale);
724 5ca1d879 Zdenek Kabelac
725
#ifdef DEBUG
726 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "track[%i].time_scale = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->time_scale); /* time scale */
727 5ca1d879 Zdenek Kabelac
#endif
728 b9a87c4d François Revol
    c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
729 5ca1d879 Zdenek Kabelac
730 b9a87c4d François Revol
    lang = get_be16(pb); /* language */
731 ab561df9 François Revol
    ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
732 5ca1d879 Zdenek Kabelac
    get_be16(pb); /* quality */
733
734
    return 0;
735
}
736
737
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
738
{
739
    print_atom("mvhd", atom);
740
741
    get_byte(pb); /* version */
742
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
743
744
    get_be32(pb); /* creation time */
745
    get_be32(pb); /* modification time */
746
    c->time_scale = get_be32(pb); /* time scale */
747
#ifdef DEBUG
748 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);
749 5ca1d879 Zdenek Kabelac
#endif
750
    c->duration = get_be32(pb); /* duration */
751
    get_be32(pb); /* preferred scale */
752
753
    get_be16(pb); /* preferred volume */
754
755
    url_fskip(pb, 10); /* reserved */
756
757
    url_fskip(pb, 36); /* display matrix */
758
759
    get_be32(pb); /* preview time */
760
    get_be32(pb); /* preview duration */
761
    get_be32(pb); /* poster time */
762
    get_be32(pb); /* selection time */
763
    get_be32(pb); /* selection duration */
764
    get_be32(pb); /* current time */
765
    get_be32(pb); /* next track ID */
766
767
    return 0;
768
}
769
770 9ed83b0a Zdenek Kabelac
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
771
{
772
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
773
774 568e18b1 Michael Niedermayer
    if((uint64_t)atom.size > (1<<30))
775
        return -1;
776 115329f1 Diego Biurrun
777 9ed83b0a Zdenek Kabelac
    // currently SVQ3 decoder expect full STSD header - so let's fake it
778
    // this should be fixed and just SMI header should be passed
779 01f4895c Michael Niedermayer
    av_free(st->codec->extradata);
780
    st->codec->extradata_size = 0x5a + atom.size;
781
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
782
783
    if (st->codec->extradata) {
784 bb270c08 Diego Biurrun
        strcpy(st->codec->extradata, "SVQ3"); // fake
785
        get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
786
        //av_log(NULL, AV_LOG_DEBUG, "Reading SMI %Ld  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
787 9ed83b0a Zdenek Kabelac
    } else
788 bb270c08 Diego Biurrun
        url_fskip(pb, atom.size);
789 9ed83b0a Zdenek Kabelac
790
    return 0;
791
}
792 5ca1d879 Zdenek Kabelac
793 d9b1c197 Roberto Togni
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
794
{
795
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
796
797
    if((uint64_t)atom.size > (1<<30))
798
        return -1;
799 115329f1 Diego Biurrun
800 d9b1c197 Roberto Togni
    // pass all frma atom to codec, needed at least for QDM2
801
    av_free(st->codec->extradata);
802
    st->codec->extradata_size = atom.size;
803
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
804
805
    if (st->codec->extradata) {
806 bb270c08 Diego Biurrun
        get_buffer(pb, st->codec->extradata, atom.size);
807
        //av_log(NULL, AV_LOG_DEBUG, "Reading frma %Ld  %s\n", atom.size, (char*)st->codec->extradata);
808 d9b1c197 Roberto Togni
    } else
809 bb270c08 Diego Biurrun
        url_fskip(pb, atom.size);
810 d9b1c197 Roberto Togni
811
    return 0;
812
}
813
814 169eb021 Mike Melanson
static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
815
{
816
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
817
818 568e18b1 Michael Niedermayer
    if((uint64_t)atom.size > (1<<30))
819
        return -1;
820
821 01f4895c Michael Niedermayer
    av_free(st->codec->extradata);
822 169eb021 Mike Melanson
823 01f4895c Michael Niedermayer
    st->codec->extradata_size = atom.size;
824
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
825 169eb021 Mike Melanson
826 01f4895c Michael Niedermayer
    if (st->codec->extradata) {
827 bb270c08 Diego Biurrun
        get_buffer(pb, st->codec->extradata, atom.size);
828 169eb021 Mike Melanson
    } else
829 bb270c08 Diego Biurrun
        url_fskip(pb, atom.size);
830 169eb021 Mike Melanson
831
    return 0;
832
}
833
834 5ca1d879 Zdenek Kabelac
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
835
{
836
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
837
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
838 568e18b1 Michael Niedermayer
    unsigned int i, entries;
839 5ca1d879 Zdenek Kabelac
840
    print_atom("stco", atom);
841
842
    get_byte(pb); /* version */
843
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
844
845
    entries = get_be32(pb);
846 115329f1 Diego Biurrun
847 568e18b1 Michael Niedermayer
    if(entries >= UINT_MAX/sizeof(int64_t))
848
        return -1;
849 115329f1 Diego Biurrun
850 5ca1d879 Zdenek Kabelac
    sc->chunk_count = entries;
851
    sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t));
852
    if (!sc->chunk_offsets)
853
        return -1;
854
    if (atom.type == MKTAG('s', 't', 'c', 'o')) {
855
        for(i=0; i<entries; i++) {
856
            sc->chunk_offsets[i] = get_be32(pb);
857
        }
858
    } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
859
        for(i=0; i<entries; i++) {
860
            sc->chunk_offsets[i] = get_be64(pb);
861
        }
862
    } else
863
        return -1;
864 115329f1 Diego Biurrun
865 86d8602f Michael Niedermayer
    for(i=0; i<c->fc->nb_streams; i++){
866
        MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
867 45139adf Michael Niedermayer
        if(sc2 && sc2->chunk_offsets){
868
            int64_t first= sc2->chunk_offsets[0];
869
            int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
870
            if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
871
                c->ni=1;
872
        }
873 86d8602f Michael Niedermayer
    }
874 5ca1d879 Zdenek Kabelac
#ifdef DEBUG
875
/*
876
    for(i=0; i<entries; i++) {
877 baf25c9d Gael Chardon
        av_log(NULL, AV_LOG_DEBUG, "chunk offset=0x%Lx\n", sc->chunk_offsets[i]);
878 5ca1d879 Zdenek Kabelac
    }
879
*/
880
#endif
881
    return 0;
882
}
883
884
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
885
{
886
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
887 302c389e Michael Niedermayer
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
888 5ca1d879 Zdenek Kabelac
    int entries, frames_per_sample;
889
    uint32_t format;
890 53ffdd14 Roine Gustafsson
    uint8_t codec_name[32];
891 5ca1d879 Zdenek Kabelac
892 b595afaa Mike Melanson
    /* for palette traversal */
893
    int color_depth;
894
    int color_start;
895
    int color_count;
896
    int color_end;
897
    int color_index;
898
    int color_dec;
899
    int color_greyscale;
900
    unsigned char *color_table;
901
    int j;
902
    unsigned char r, g, b;
903
904 5ca1d879 Zdenek Kabelac
    print_atom("stsd", atom);
905 6cea494e Zdenek Kabelac
906
    get_byte(pb); /* version */
907
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
908
909
    entries = get_be32(pb);
910
911 891f64b3 joca@rixmail.se
    while(entries--) { //Parsing Sample description table
912 b6a17df4 Zdenek Kabelac
        enum CodecID id;
913 bb270c08 Diego Biurrun
        int size = get_be32(pb); /* size */
914 6cea494e Zdenek Kabelac
        format = get_le32(pb); /* data format */
915 5cd62665 Zdenek Kabelac
916 6cea494e Zdenek Kabelac
        get_be32(pb); /* reserved */
917
        get_be16(pb); /* reserved */
918
        get_be16(pb); /* index */
919 0e7eed09 Fabrice Bellard
920
        /* for MPEG4: set codec type by looking for it */
921
        id = codec_get_id(mov_video_tags, format);
922
        if (id >= 0) {
923
            AVCodec *codec;
924 bb270c08 Diego Biurrun
            codec = avcodec_find_decoder(id);
925 0e7eed09 Fabrice Bellard
            if (codec)
926 bb270c08 Diego Biurrun
                st->codec->codec_type = codec->type;
927 0e7eed09 Fabrice Bellard
        }
928
#ifdef DEBUG
929 baf25c9d Gael Chardon
        av_log(NULL, AV_LOG_DEBUG, "size=%d 4CC= %c%c%c%c codec_type=%d\n",
930 5cd62665 Zdenek Kabelac
               size,
931 0e7eed09 Fabrice Bellard
               (format >> 0) & 0xff,
932
               (format >> 8) & 0xff,
933
               (format >> 16) & 0xff,
934
               (format >> 24) & 0xff,
935 01f4895c Michael Niedermayer
               st->codec->codec_type);
936 0e7eed09 Fabrice Bellard
#endif
937 bb270c08 Diego Biurrun
        st->codec->codec_tag = format;
938
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
939
            MOV_atom_t a = { 0, 0, 0 };
940 01f4895c Michael Niedermayer
            st->codec->codec_id = id;
941 6cea494e Zdenek Kabelac
            get_be16(pb); /* version */
942
            get_be16(pb); /* revision level */
943
            get_be32(pb); /* vendor */
944
            get_be32(pb); /* temporal quality */
945
            get_be32(pb); /* spacial quality */
946 01f4895c Michael Niedermayer
            if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
947 d57b7316 Michael Niedermayer
                get_be16(pb);
948
                get_be16(pb);
949
            }else{
950 01f4895c Michael Niedermayer
                st->codec->width = get_be16(pb); /* width */
951
                st->codec->height = get_be16(pb); /* height */
952 0e7eed09 Fabrice Bellard
            }
953 6cea494e Zdenek Kabelac
            get_be32(pb); /* horiz resolution */
954
            get_be32(pb); /* vert resolution */
955
            get_be32(pb); /* data size, always 0 */
956 5cd62665 Zdenek Kabelac
            frames_per_sample = get_be16(pb); /* frames per samples */
957 6cea494e Zdenek Kabelac
#ifdef DEBUG
958 bb270c08 Diego Biurrun
            av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
959 6cea494e Zdenek Kabelac
#endif
960 53ffdd14 Roine Gustafsson
        get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
961
        if (codec_name[0] <= 31) {
962 01f4895c Michael Niedermayer
            memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
963
            st->codec->codec_name[codec_name[0]] = 0;
964 53ffdd14 Roine Gustafsson
        }
965 5cd62665 Zdenek Kabelac
966 bb270c08 Diego Biurrun
            st->codec->bits_per_sample = get_be16(pb); /* depth */
967 01f4895c Michael Niedermayer
            st->codec->color_table_id = get_be16(pb); /* colortable id */
968 6cea494e Zdenek Kabelac
969 14342fd5 Johannes Carlsson
/*          These are set in mov_read_stts and might already be set!
970 01f4895c Michael Niedermayer
            st->codec->time_base.den      = 25;
971
            st->codec->time_base.num = 1;
972 14342fd5 Johannes Carlsson
*/
973 bb270c08 Diego Biurrun
            size -= (16+8*4+2+32+2*2);
974 5cd62665 Zdenek Kabelac
#if 0
975 bb270c08 Diego Biurrun
            while (size >= 8) {
976
                MOV_atom_t a;
977 0c1a9eda Zdenek Kabelac
                int64_t start_pos;
978 5cd62665 Zdenek Kabelac

979 bb270c08 Diego Biurrun
                a.size = get_be32(pb);
980
                a.type = get_le32(pb);
981
                size -= 8;
982 0e7eed09 Fabrice Bellard
#ifdef DEBUG
983 baf25c9d Gael Chardon
                av_log(NULL, AV_LOG_DEBUG, "VIDEO: atom_type=%c%c%c%c atom.size=%Ld size_left=%d\n",
984 5ca1d879 Zdenek Kabelac
                       (a.type >> 0) & 0xff,
985
                       (a.type >> 8) & 0xff,
986
                       (a.type >> 16) & 0xff,
987
                       (a.type >> 24) & 0xff,
988 bb270c08 Diego Biurrun
                       a.size, size);
989 0e7eed09 Fabrice Bellard
#endif
990
                start_pos = url_ftell(pb);
991
992 bb270c08 Diego Biurrun
                switch(a.type) {
993 0e7eed09 Fabrice Bellard
                case MKTAG('e', 's', 'd', 's'):
994
                    {
995
                        int tag, len;
996
                        /* Well, broken but suffisant for some MP4 streams */
997
                        get_be32(pb); /* version + flags */
998 bb270c08 Diego Biurrun
                        len = mov_mp4_read_descr(pb, &tag);
999 0e7eed09 Fabrice Bellard
                        if (tag == 0x03) {
1000
                            /* MP4ESDescrTag */
1001
                            get_be16(pb); /* ID */
1002
                            get_byte(pb); /* priority */
1003 bb270c08 Diego Biurrun
                            len = mov_mp4_read_descr(pb, &tag);
1004 0e7eed09 Fabrice Bellard
                            if (tag != 0x04)
1005
                                goto fail;
1006
                            /* MP4DecConfigDescrTag */
1007
                            get_byte(pb); /* objectTypeId */
1008
                            get_be32(pb); /* streamType + buffer size */
1009 bb270c08 Diego Biurrun
                            get_be32(pb); /* max bit rate */
1010 0e7eed09 Fabrice Bellard
                            get_be32(pb); /* avg bit rate */
1011 891f64b3 joca@rixmail.se
                            len = mov_mp4_read_descr(pb, &tag);
1012 0e7eed09 Fabrice Bellard
                            if (tag != 0x05)
1013
                                goto fail;
1014
                            /* MP4DecSpecificDescrTag */
1015
#ifdef DEBUG
1016 baf25c9d Gael Chardon
                            av_log(NULL, AV_LOG_DEBUG, "Specific MPEG4 header len=%d\n", len);
1017 0e7eed09 Fabrice Bellard
#endif
1018
                            sc->header_data = av_mallocz(len);
1019
                            if (sc->header_data) {
1020
                                get_buffer(pb, sc->header_data, len);
1021 bb270c08 Diego Biurrun
                                sc->header_len = len;
1022 0e7eed09 Fabrice Bellard
                            }
1023
                        }
1024
                        /* in any case, skip garbage */
1025
                    }
1026
                    break;
1027
                default:
1028
                    break;
1029
                }
1030 bb270c08 Diego Biurrun
            fail:
1031
                av_log(NULL, AV_LOG_DEBUG, "ATOMENEWSIZE %Ld   %d\n", atom.size, url_ftell(pb) - start_pos);
1032
                if (atom.size > 8) {
1033
                    url_fskip(pb, (atom.size - 8) -
1034
                              ((url_ftell(pb) - start_pos)));
1035
                    size -= atom.size - 8;
1036
                }
1037
            }
1038 0e7eed09 Fabrice Bellard
            if (size > 0) {
1039
                /* unknown extension */
1040
                url_fskip(pb, size);
1041
            }
1042 5cd62665 Zdenek Kabelac
#else
1043 b595afaa Mike Melanson
1044
            /* figure out the palette situation */
1045 01f4895c Michael Niedermayer
            color_depth = st->codec->bits_per_sample & 0x1F;
1046
            color_greyscale = st->codec->bits_per_sample & 0x20;
1047 b595afaa Mike Melanson
1048
            /* if the depth is 2, 4, or 8 bpp, file is palettized */
1049 115329f1 Diego Biurrun
            if ((color_depth == 2) || (color_depth == 4) ||
1050 b595afaa Mike Melanson
                (color_depth == 8)) {
1051
1052
                if (color_greyscale) {
1053
1054
                    /* compute the greyscale palette */
1055
                    color_count = 1 << color_depth;
1056
                    color_index = 255;
1057
                    color_dec = 256 / (color_count - 1);
1058
                    for (j = 0; j < color_count; j++) {
1059
                        r = g = b = color_index;
1060
                        c->palette_control.palette[j] =
1061
                            (r << 16) | (g << 8) | (b);
1062
                        color_index -= color_dec;
1063
                        if (color_index < 0)
1064
                            color_index = 0;
1065
                    }
1066
1067 01f4895c Michael Niedermayer
                } else if (st->codec->color_table_id & 0x08) {
1068 b595afaa Mike Melanson
1069
                    /* if flag bit 3 is set, use the default palette */
1070
                    color_count = 1 << color_depth;
1071
                    if (color_depth == 2)
1072 a90466f7 Michael Niedermayer
                        color_table = ff_qt_default_palette_4;
1073 b595afaa Mike Melanson
                    else if (color_depth == 4)
1074 a90466f7 Michael Niedermayer
                        color_table = ff_qt_default_palette_16;
1075 b595afaa Mike Melanson
                    else
1076 a90466f7 Michael Niedermayer
                        color_table = ff_qt_default_palette_256;
1077 b595afaa Mike Melanson
1078
                    for (j = 0; j < color_count; j++) {
1079
                        r = color_table[j * 4 + 0];
1080
                        g = color_table[j * 4 + 1];
1081
                        b = color_table[j * 4 + 2];
1082
                        c->palette_control.palette[j] =
1083
                            (r << 16) | (g << 8) | (b);
1084
                    }
1085
1086
                } else {
1087
1088
                    /* load the palette from the file */
1089
                    color_start = get_be32(pb);
1090
                    color_count = get_be16(pb);
1091
                    color_end = get_be16(pb);
1092
                    for (j = color_start; j <= color_end; j++) {
1093
                        /* each R, G, or B component is 16 bits;
1094
                         * only use the top 8 bits; skip alpha bytes
1095
                         * up front */
1096
                        get_byte(pb);
1097
                        get_byte(pb);
1098
                        r = get_byte(pb);
1099
                        get_byte(pb);
1100
                        g = get_byte(pb);
1101
                        get_byte(pb);
1102
                        b = get_byte(pb);
1103
                        get_byte(pb);
1104
                        c->palette_control.palette[j] =
1105
                            (r << 16) | (g << 8) | (b);
1106
                    }
1107
                }
1108
1109 01f4895c Michael Niedermayer
                st->codec->palctrl = &c->palette_control;
1110
                st->codec->palctrl->palette_changed = 1;
1111 b595afaa Mike Melanson
            } else
1112 01f4895c Michael Niedermayer
                st->codec->palctrl = NULL;
1113 b595afaa Mike Melanson
1114 5ca1d879 Zdenek Kabelac
            a.size = size;
1115 bb270c08 Diego Biurrun
            mov_read_default(c, pb, a);
1116 5cd62665 Zdenek Kabelac
#endif
1117 bb270c08 Diego Biurrun
        } else {
1118 01f4895c Michael Niedermayer
            st->codec->codec_id = codec_get_id(mov_audio_tags, format);
1119 bb270c08 Diego Biurrun
            if(st->codec->codec_id==CODEC_ID_AMR_NB || st->codec->codec_id==CODEC_ID_AMR_WB) //from TS26.244
1120
            {
1121 891f64b3 joca@rixmail.se
#ifdef DEBUG
1122 baf25c9d Gael Chardon
               av_log(NULL, AV_LOG_DEBUG, "AMR-NB or AMR-WB audio identified!!\n");
1123 891f64b3 joca@rixmail.se
#endif
1124
               get_be32(pb);get_be32(pb); //Reserved_8
1125
               get_be16(pb);//Reserved_2
1126
               get_be16(pb);//Reserved_2
1127
               get_be32(pb);//Reserved_4
1128
               get_be16(pb);//TimeScale
1129
               get_be16(pb);//Reserved_2
1130
1131
                //AMRSpecificBox.(10 bytes)
1132 115329f1 Diego Biurrun
1133 891f64b3 joca@rixmail.se
               get_be32(pb); //size
1134
               get_be32(pb); //type=='damr'
1135
               get_be32(pb); //vendor
1136
               get_byte(pb); //decoder version
1137
               get_be16(pb); //mode_set
1138
               get_byte(pb); //mode_change_period
1139
               get_byte(pb); //frames_per_sample
1140 6cea494e Zdenek Kabelac
1141 25c4950e Fabrice Bellard
               st->duration = AV_NOPTS_VALUE;//Not possible to get from this info, must count number of AMR frames
1142 01f4895c Michael Niedermayer
               if(st->codec->codec_id==CODEC_ID_AMR_NB)
1143 d663a1fd Michael Niedermayer
               {
1144 01f4895c Michael Niedermayer
                   st->codec->sample_rate=8000;
1145
                   st->codec->channels=1;
1146 d663a1fd Michael Niedermayer
               }
1147
               else //AMR-WB
1148
               {
1149 01f4895c Michael Niedermayer
                   st->codec->sample_rate=16000;
1150
                   st->codec->channels=1;
1151 d663a1fd Michael Niedermayer
               }
1152 01f4895c Michael Niedermayer
               st->codec->bits_per_sample=16;
1153 115329f1 Diego Biurrun
               st->codec->bit_rate=0; /*It is not possible to tell this before we have
1154 891f64b3 joca@rixmail.se
                                       an audio frame and even then every frame can be different*/
1155 bb270c08 Diego Biurrun
            }
1156 01f4895c Michael Niedermayer
            else if( st->codec->codec_tag == MKTAG( 'm', 'p', '4', 's' ))
1157 14342fd5 Johannes Carlsson
            {
1158
                //This is some stuff for the hint track, lets ignore it!
1159
                //Do some mp4 auto detect.
1160
                c->mp4=1;
1161
                size-=(16);
1162
                url_fskip(pb, size); /* The mp4s atom also contians a esds atom that we can skip*/
1163
            }
1164 01f4895c Michael Niedermayer
            else if( st->codec->codec_tag == MKTAG( 'm', 'p', '4', 'a' ))
1165 2768b0d9 Thomas Raivio
            {
1166 2f1e1ed3 Michael Niedermayer
                MOV_atom_t a;
1167
                int mp4_version;
1168
1169 2768b0d9 Thomas Raivio
                /* Handle mp4 audio tag */
1170 2f1e1ed3 Michael Niedermayer
                mp4_version=get_be16(pb);/*version*/
1171
                get_be16(pb); /*revesion*/
1172 2768b0d9 Thomas Raivio
                get_be32(pb);
1173 01f4895c Michael Niedermayer
                st->codec->channels = get_be16(pb); /* channels */
1174
                st->codec->bits_per_sample = get_be16(pb); /* bits per sample */
1175 2768b0d9 Thomas Raivio
                get_be32(pb);
1176 01f4895c Michael Niedermayer
                st->codec->sample_rate = get_be16(pb); /* sample rate, not always correct */
1177 302c389e Michael Niedermayer
                if(st->codec->sample_rate == 1) //nonsese rate? -> ignore
1178
                    st->codec->sample_rate= 0;
1179
1180 2768b0d9 Thomas Raivio
                get_be16(pb);
1181
                c->mp4=1;
1182 115329f1 Diego Biurrun
1183 2f1e1ed3 Michael Niedermayer
                if(mp4_version==1)
1184
                {
1185
                    url_fskip(pb,16);
1186
                    a.size=size-(16+20+16);
1187
                }
1188
                else
1189
                    a.size=size-(16+20);
1190
1191
                a.offset=url_ftell(pb);
1192 115329f1 Diego Biurrun
1193 2768b0d9 Thomas Raivio
                mov_read_default(c, pb, a);
1194 2f1e1ed3 Michael Niedermayer
1195 2768b0d9 Thomas Raivio
                /* Get correct sample rate from extradata */
1196 01f4895c Michael Niedermayer
                if(st->codec->extradata_size) {
1197 2768b0d9 Thomas Raivio
                   const int samplerate_table[] = {
1198 115329f1 Diego Biurrun
                     96000, 88200, 64000, 48000, 44100, 32000,
1199 2768b0d9 Thomas Raivio
                     24000, 22050, 16000, 12000, 11025, 8000,
1200
                     7350, 0, 0, 0
1201
                   };
1202 01f4895c Michael Niedermayer
                   unsigned char *px = st->codec->extradata;
1203 2768b0d9 Thomas Raivio
                   // 5 bits objectTypeIndex, 4 bits sampleRateIndex, 4 bits channels
1204
                   int samplerate_index = ((px[0] & 7) << 1) + ((px[1] >> 7) & 1);
1205 01f4895c Michael Niedermayer
                   st->codec->sample_rate = samplerate_table[samplerate_index];
1206
                   st->codec->channels = (px[1] >> 3) & 15;
1207 2768b0d9 Thomas Raivio
                }
1208
            }
1209 01f4895c Michael Niedermayer
            else if( st->codec->codec_tag == MKTAG( 'a', 'l', 'a', 'c' ))
1210 6d6d7970 Mike Melanson
            {
1211
                /* Handle alac audio tag + special extradata */
1212
                get_be32(pb); /* version */
1213
                get_be32(pb);
1214 01f4895c Michael Niedermayer
                st->codec->channels = get_be16(pb); /* channels */
1215
                st->codec->bits_per_sample = get_be16(pb); /* bits per sample */
1216 6d6d7970 Mike Melanson
                get_be32(pb);
1217 01f4895c Michael Niedermayer
                st->codec->sample_rate = get_be16(pb);
1218 6d6d7970 Mike Melanson
                get_be16(pb);
1219
1220
                /* fetch the 36-byte extradata needed for alac decoding */
1221 01f4895c Michael Niedermayer
                st->codec->extradata_size = 36;
1222 115329f1 Diego Biurrun
                st->codec->extradata = (uint8_t*)
1223 01f4895c Michael Niedermayer
                    av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
1224
                get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
1225 6d6d7970 Mike Melanson
            }
1226 bb270c08 Diego Biurrun
            else if(size>=(16+20))
1227
            {//16 bytes read, reading atleast 20 more
1228 c3ea71a0 François Revol
                uint16_t version;
1229 14342fd5 Johannes Carlsson
#ifdef DEBUG
1230 baf25c9d Gael Chardon
                av_log(NULL, AV_LOG_DEBUG, "audio size=0x%X\n",size);
1231 14342fd5 Johannes Carlsson
#endif
1232 c3ea71a0 François Revol
                version = get_be16(pb); /* version */
1233 891f64b3 joca@rixmail.se
                get_be16(pb); /* revision level */
1234
                get_be32(pb); /* vendor */
1235
1236 bb270c08 Diego Biurrun
                st->codec->channels = get_be16(pb);             /* channel count */
1237
                st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1238 891f64b3 joca@rixmail.se
1239
                /* handle specific s8 codec */
1240
                get_be16(pb); /* compression id = 0*/
1241
                get_be16(pb); /* packet size = 0 */
1242
1243 01f4895c Michael Niedermayer
                st->codec->sample_rate = ((get_be32(pb) >> 16));
1244 bb270c08 Diego Biurrun
                //av_log(NULL, AV_LOG_DEBUG, "CODECID %d  %d  %.4s\n", st->codec->codec_id, CODEC_ID_PCM_S16BE, (char*)&format);
1245 891f64b3 joca@rixmail.se
1246 bb270c08 Diego Biurrun
                switch (st->codec->codec_id) {
1247
                case CODEC_ID_PCM_S16BE:
1248
                    if (st->codec->bits_per_sample == 8)
1249
                        st->codec->codec_id = CODEC_ID_PCM_S8;
1250 891f64b3 joca@rixmail.se
                    /* fall */
1251 bb270c08 Diego Biurrun
                case CODEC_ID_PCM_U8:
1252
                    st->codec->bit_rate = st->codec->sample_rate * 8;
1253
                    break;
1254
                default:
1255 891f64b3 joca@rixmail.se
                    ;
1256 bb270c08 Diego Biurrun
                }
1257 14342fd5 Johannes Carlsson
1258
                //Read QT version 1 fields. In version 0 theese dont exist
1259
#ifdef DEBUG
1260 baf25c9d Gael Chardon
                av_log(NULL, AV_LOG_DEBUG, "version =%d mp4=%d\n",version,c->mp4);
1261
                av_log(NULL, AV_LOG_DEBUG, "size-(16+20+16)=%d\n",size-(16+20+16));
1262 14342fd5 Johannes Carlsson
#endif
1263
                if((version==1) && size>=(16+20+16))
1264
                {
1265
                    get_be32(pb); /* samples per packet */
1266
                    get_be32(pb); /* bytes per packet */
1267
                    get_be32(pb); /* bytes per frame */
1268
                    get_be32(pb); /* bytes per sample */
1269
                    if(size>(16+20+16))
1270
                    {
1271
                        //Optional, additional atom-based fields
1272 c3ea71a0 François Revol
                        MOV_atom_t a = { format, url_ftell(pb), size - (16 + 20 + 16 + 8) };
1273 14342fd5 Johannes Carlsson
#ifdef DEBUG
1274 baf25c9d Gael Chardon
                        av_log(NULL, AV_LOG_DEBUG, "offest=0x%X, sizeleft=%d=0x%x,format=%c%c%c%c\n",(int)url_ftell(pb),size - (16 + 20 + 16 ),size - (16 + 20 + 16 ),
1275 14342fd5 Johannes Carlsson
                            (format >> 0) & 0xff,
1276
                            (format >> 8) & 0xff,
1277
                            (format >> 16) & 0xff,
1278
                            (format >> 24) & 0xff);
1279
#endif
1280
                        mov_read_default(c, pb, a);
1281
                    }
1282
                }
1283
                else
1284
                {
1285
                    //We should be down to 0 bytes here, but lets make sure.
1286
                    size-=(16+20);
1287
#ifdef DEBUG
1288
                    if(size>0)
1289 baf25c9d Gael Chardon
                        av_log(NULL, AV_LOG_DEBUG, "skipping 0x%X bytes\n",size-(16+20));
1290 14342fd5 Johannes Carlsson
#endif
1291
                    url_fskip(pb, size);
1292
                }
1293
            }
1294
            else
1295
            {
1296
                size-=16;
1297
                //Unknown size, but lets do our best and skip the rest.
1298
#ifdef DEBUG
1299 baf25c9d Gael Chardon
                av_log(NULL, AV_LOG_DEBUG, "Strange size, skipping 0x%X bytes\n",size);
1300 14342fd5 Johannes Carlsson
#endif
1301
                url_fskip(pb, size);
1302 891f64b3 joca@rixmail.se
            }
1303 6cea494e Zdenek Kabelac
        }
1304
    }
1305 115329f1 Diego Biurrun
1306 302c389e Michael Niedermayer
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1307
        st->codec->sample_rate= sc->time_scale;
1308
    }
1309 5cd62665 Zdenek Kabelac
1310 6cea494e Zdenek Kabelac
    return 0;
1311
}
1312
1313 5ca1d879 Zdenek Kabelac
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1314 6cea494e Zdenek Kabelac
{
1315 5ca1d879 Zdenek Kabelac
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1316
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1317 568e18b1 Michael Niedermayer
    unsigned int i, entries;
1318 b6a17df4 Zdenek Kabelac
1319 5ca1d879 Zdenek Kabelac
    print_atom("stsc", atom);
1320 5cd62665 Zdenek Kabelac
1321 6cea494e Zdenek Kabelac
    get_byte(pb); /* version */
1322
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1323
1324
    entries = get_be32(pb);
1325 115329f1 Diego Biurrun
1326 568e18b1 Michael Niedermayer
    if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1327
        return -1;
1328 115329f1 Diego Biurrun
1329 3ffe3793 François Revol
#ifdef DEBUG
1330 baf25c9d Gael Chardon
av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1331 3ffe3793 François Revol
#endif
1332 6cea494e Zdenek Kabelac
    sc->sample_to_chunk_sz = entries;
1333 b6a17df4 Zdenek Kabelac
    sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1334
    if (!sc->sample_to_chunk)
1335
        return -1;
1336 6cea494e Zdenek Kabelac
    for(i=0; i<entries; i++) {
1337
        sc->sample_to_chunk[i].first = get_be32(pb);
1338
        sc->sample_to_chunk[i].count = get_be32(pb);
1339
        sc->sample_to_chunk[i].id = get_be32(pb);
1340
#ifdef DEBUG
1341 baf25c9d Gael Chardon
/*        av_log(NULL, AV_LOG_DEBUG, "sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id); */
1342 6cea494e Zdenek Kabelac
#endif
1343
    }
1344
    return 0;
1345
}
1346
1347 247d56f5 Brian Becker
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1348
{
1349
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1350
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1351 568e18b1 Michael Niedermayer
    unsigned int i, entries;
1352 247d56f5 Brian Becker
1353
    print_atom("stss", atom);
1354
1355
    get_byte(pb); /* version */
1356
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1357
1358
    entries = get_be32(pb);
1359 115329f1 Diego Biurrun
1360 568e18b1 Michael Niedermayer
    if(entries >= UINT_MAX / sizeof(long))
1361
        return -1;
1362 115329f1 Diego Biurrun
1363 247d56f5 Brian Becker
    sc->keyframe_count = entries;
1364
#ifdef DEBUG
1365
    av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1366
#endif
1367
    sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1368
    if (!sc->keyframes)
1369
        return -1;
1370
    for(i=0; i<entries; i++) {
1371
        sc->keyframes[i] = get_be32(pb);
1372
#ifdef DEBUG
1373
/*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1374
#endif
1375
    }
1376
    return 0;
1377
}
1378
1379 5ca1d879 Zdenek Kabelac
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1380 6cea494e Zdenek Kabelac
{
1381 5ca1d879 Zdenek Kabelac
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1382
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1383 568e18b1 Michael Niedermayer
    unsigned int i, entries;
1384 b6a17df4 Zdenek Kabelac
1385 5ca1d879 Zdenek Kabelac
    print_atom("stsz", atom);
1386 5cd62665 Zdenek Kabelac
1387 6cea494e Zdenek Kabelac
    get_byte(pb); /* version */
1388
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1389 5cd62665 Zdenek Kabelac
1390 6cea494e Zdenek Kabelac
    sc->sample_size = get_be32(pb);
1391
    entries = get_be32(pb);
1392 568e18b1 Michael Niedermayer
    if(entries >= UINT_MAX / sizeof(long))
1393
        return -1;
1394
1395 6cea494e Zdenek Kabelac
    sc->sample_count = entries;
1396 0147f198 François Revol
#ifdef DEBUG
1397 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1398 0147f198 François Revol
#endif
1399 6cea494e Zdenek Kabelac
    if(sc->sample_size)
1400
        return 0; /* there isn't any table following */
1401 b6a17df4 Zdenek Kabelac
    sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1402
    if (!sc->sample_sizes)
1403
        return -1;
1404 6cea494e Zdenek Kabelac
    for(i=0; i<entries; i++) {
1405
        sc->sample_sizes[i] = get_be32(pb);
1406
#ifdef DEBUG
1407 7dbab4a9 François Revol
        av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1408 6cea494e Zdenek Kabelac
#endif
1409
    }
1410
    return 0;
1411
}
1412
1413 5ca1d879 Zdenek Kabelac
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1414 0147f198 François Revol
{
1415 5ca1d879 Zdenek Kabelac
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1416 fd6e513e Zdenek Kabelac
    //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1417 568e18b1 Michael Niedermayer
    unsigned int i, entries;
1418 d957696f Michael Niedermayer
    int64_t duration=0;
1419
    int64_t total_sample_count=0;
1420 b6a17df4 Zdenek Kabelac
1421 5ca1d879 Zdenek Kabelac
    print_atom("stts", atom);
1422 0147f198 François Revol
1423
    get_byte(pb); /* version */
1424
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1425
    entries = get_be32(pb);
1426 cd461d48 Michael Niedermayer
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1427 568e18b1 Michael Niedermayer
        return -1;
1428 891f64b3 joca@rixmail.se
1429 baf25c9d Gael Chardon
    c->streams[c->fc->nb_streams-1]->stts_count = entries;
1430 cd461d48 Michael Niedermayer
    c->streams[c->fc->nb_streams-1]->stts_data = av_malloc(entries * sizeof(Time2Sample));
1431 891f64b3 joca@rixmail.se
1432 3ffe3793 François Revol
#ifdef DEBUG
1433 baf25c9d Gael Chardon
av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1434 3ffe3793 François Revol
#endif
1435 0147f198 François Revol
    for(i=0; i<entries; i++) {
1436 cd461d48 Michael Niedermayer
        int sample_duration;
1437
        int sample_count;
1438 0147f198 François Revol
1439 891f64b3 joca@rixmail.se
        sample_count=get_be32(pb);
1440 0147f198 François Revol
        sample_duration = get_be32(pb);
1441 cd461d48 Michael Niedermayer
        c->streams[c->fc->nb_streams - 1]->stts_data[i].count= sample_count;
1442
        c->streams[c->fc->nb_streams - 1]->stts_data[i].duration= sample_duration;
1443 961e0ccd Michael Niedermayer
1444 891f64b3 joca@rixmail.se
#ifdef DEBUG
1445 baf25c9d Gael Chardon
        av_log(NULL, AV_LOG_DEBUG, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1446 891f64b3 joca@rixmail.se
#endif
1447
        duration+=sample_duration*sample_count;
1448
        total_sample_count+=sample_count;
1449
    }
1450
1451 961e0ccd Michael Niedermayer
    st->nb_frames= total_sample_count;
1452
    if(duration)
1453
        st->duration= duration;
1454 0147f198 François Revol
    return 0;
1455
}
1456
1457 c4ac052b Michael Niedermayer
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1458
{
1459
//    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1460
    //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1461
    unsigned int i, entries;
1462
1463
    print_atom("ctts", atom);
1464
1465
    get_byte(pb); /* version */
1466
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1467
    entries = get_be32(pb);
1468
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1469
        return -1;
1470
1471
    c->streams[c->fc->nb_streams-1]->ctts_count = entries;
1472
    c->streams[c->fc->nb_streams-1]->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1473
1474
// #ifdef DEBUG
1475
av_log(NULL, AV_LOG_DEBUG, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
1476
// #endif
1477
    for(i=0; i<entries; i++) {
1478
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].count= get_be32(pb);
1479
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].duration= get_be32(pb);
1480
    }
1481
    return 0;
1482
}
1483
1484 5ca1d879 Zdenek Kabelac
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1485
{
1486
    AVStream *st;
1487
    MOVStreamContext *sc;
1488
1489
    print_atom("trak", atom);
1490
1491
    st = av_new_stream(c->fc, c->fc->nb_streams);
1492
    if (!st) return -2;
1493
    sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1494
    if (!sc) {
1495 bb270c08 Diego Biurrun
        av_free(st);
1496 5ca1d879 Zdenek Kabelac
        return -1;
1497
    }
1498
1499
    sc->sample_to_chunk_index = -1;
1500
    st->priv_data = sc;
1501 01f4895c Michael Niedermayer
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1502 25c4950e Fabrice Bellard
    st->start_time = 0; /* XXX: check */
1503 5ca1d879 Zdenek Kabelac
    c->streams[c->fc->nb_streams-1] = sc;
1504
1505
    return mov_read_default(c, pb, atom);
1506
}
1507
1508
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1509
{
1510
    AVStream *st;
1511
1512
    print_atom("tkhd", atom);
1513
1514
    st = c->fc->streams[c->fc->nb_streams-1];
1515
1516
    get_byte(pb); /* version */
1517
1518
    get_byte(pb); get_byte(pb);
1519
    get_byte(pb); /* flags */
1520
    /*
1521
    MOV_TRACK_ENABLED 0x0001
1522
    MOV_TRACK_IN_MOVIE 0x0002
1523
    MOV_TRACK_IN_PREVIEW 0x0004
1524
    MOV_TRACK_IN_POSTER 0x0008
1525
    */
1526
1527
    get_be32(pb); /* creation time */
1528
    get_be32(pb); /* modification time */
1529
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1530
    get_be32(pb); /* reserved */
1531 25c4950e Fabrice Bellard
    st->start_time = 0; /* check */
1532 961e0ccd Michael Niedermayer
    get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1533 5ca1d879 Zdenek Kabelac
    get_be32(pb); /* reserved */
1534
    get_be32(pb); /* reserved */
1535
1536
    get_be16(pb); /* layer */
1537
    get_be16(pb); /* alternate group */
1538
    get_be16(pb); /* volume */
1539
    get_be16(pb); /* reserved */
1540
1541
    url_fskip(pb, 36); /* display matrix */
1542
1543
    /* those are fixed-point */
1544 01f4895c Michael Niedermayer
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1545
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1546 5ca1d879 Zdenek Kabelac
1547
    return 0;
1548
}
1549
1550
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1551
/* like the files created with Adobe Premiere 5.0, for samples see */
1552
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1553
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1554
{
1555
    int err;
1556
1557
#ifdef DEBUG
1558
    print_atom("wide", atom);
1559
    debug_indent++;
1560
#endif
1561
    if (atom.size < 8)
1562
        return 0; /* continue */
1563
    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1564
        url_fskip(pb, atom.size - 4);
1565
        return 0;
1566
    }
1567
    atom.type = get_le32(pb);
1568
    atom.offset += 8;
1569
    atom.size -= 8;
1570 fd6e513e Zdenek Kabelac
    if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1571 5ca1d879 Zdenek Kabelac
        url_fskip(pb, atom.size);
1572
        return 0;
1573
    }
1574
    err = mov_read_mdat(c, pb, atom);
1575
#ifdef DEBUG
1576
    debug_indent--;
1577
#endif
1578
    return err;
1579
}
1580
1581
1582 0147f198 François Revol
#ifdef CONFIG_ZLIB
1583 0c1a9eda Zdenek Kabelac
static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1584 0147f198 François Revol
{
1585
    return -1;
1586
}
1587
1588 5ca1d879 Zdenek Kabelac
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1589 0147f198 François Revol
{
1590
    ByteIOContext ctx;
1591 b6a17df4 Zdenek Kabelac
    uint8_t *cmov_data;
1592
    uint8_t *moov_data; /* uncompressed data */
1593 0147f198 François Revol
    long cmov_len, moov_len;
1594
    int ret;
1595 b6a17df4 Zdenek Kabelac
1596 5ca1d879 Zdenek Kabelac
    print_atom("cmov", atom);
1597 0147f198 François Revol
1598
    get_be32(pb); /* dcom atom */
1599
    if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1600
        return -1;
1601
    if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1602 baf25c9d Gael Chardon
        av_log(NULL, AV_LOG_DEBUG, "unknown compression for cmov atom !");
1603 0147f198 François Revol
        return -1;
1604
    }
1605
    get_be32(pb); /* cmvd atom */
1606
    if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1607
        return -1;
1608
    moov_len = get_be32(pb); /* uncompressed size */
1609 5ca1d879 Zdenek Kabelac
    cmov_len = atom.size - 6 * 4;
1610 5cd62665 Zdenek Kabelac
1611 b6a17df4 Zdenek Kabelac
    cmov_data = (uint8_t *) av_malloc(cmov_len);
1612 0147f198 François Revol
    if (!cmov_data)
1613
        return -1;
1614 b6a17df4 Zdenek Kabelac
    moov_data = (uint8_t *) av_malloc(moov_len);
1615 0147f198 François Revol
    if (!moov_data) {
1616
        av_free(cmov_data);
1617
        return -1;
1618
    }
1619
    get_buffer(pb, cmov_data, cmov_len);
1620 b6a17df4 Zdenek Kabelac
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1621 0147f198 François Revol
        return -1;
1622
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1623
        return -1;
1624
    ctx.buf_end = ctx.buffer + moov_len;
1625 5ca1d879 Zdenek Kabelac
    atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1626
    atom.offset = 0;
1627
    atom.size = moov_len;
1628 9ed83b0a Zdenek Kabelac
#ifdef DEBUG
1629
    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1630
#endif
1631 5ca1d879 Zdenek Kabelac
    ret = mov_read_default(c, &ctx, atom);
1632 0147f198 François Revol
    av_free(moov_data);
1633
    av_free(cmov_data);
1634 9ed83b0a Zdenek Kabelac
1635 0147f198 François Revol
    return ret;
1636
}
1637
#endif
1638
1639 baf25c9d Gael Chardon
/* edit list atom */
1640
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1641
{
1642 58e555d4 Michael Niedermayer
  int i, edit_count;
1643 baf25c9d Gael Chardon
  print_atom("elst", atom);
1644
1645
  get_byte(pb); /* version */
1646
  get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1647 58e555d4 Michael Niedermayer
  edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1648 115329f1 Diego Biurrun
1649 58e555d4 Michael Niedermayer
  for(i=0; i<edit_count; i++){
1650
    get_be32(pb); /* Track duration */
1651
    get_be32(pb); /* Media time */
1652
    get_be32(pb); /* Media rate */
1653
  }
1654 baf25c9d Gael Chardon
#ifdef DEBUG
1655
  av_log(NULL, AV_LOG_DEBUG, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1656
#endif
1657
  return 0;
1658
}
1659
1660 6cea494e Zdenek Kabelac
static const MOVParseTableEntry mov_default_parse_table[] = {
1661
/* mp4 atoms */
1662 5ca1d879 Zdenek Kabelac
{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1663
{ MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1664
{ MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1665 c4ac052b Michael Niedermayer
{ MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1666 5ca1d879 Zdenek Kabelac
{ MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1667
{ MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1668
{ MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1669
{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1670 58e555d4 Michael Niedermayer
{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1671 5ca1d879 Zdenek Kabelac
{ MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1672
{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1673
{ MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1674
{ MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1675
{ MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
1676
{ MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1677
{ MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1678
{ MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1679
{ MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1680
{ MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
1681
{ MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },
1682
{ MKTAG( 'm', 'p', '4', 's' ), mov_read_default },
1683
{ MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },
1684
{ MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },
1685
{ MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
1686
{ MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },
1687
{ MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },
1688
{ MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },
1689 3c13647a Cedric Vincent
{ MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },
1690 5ca1d879 Zdenek Kabelac
{ MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */
1691 169eb021 Mike Melanson
{ MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
1692 115329f1 Diego Biurrun
{ MKTAG( 'a', 'v', 'c', 'C' ), mov_read_avcC },
1693 5ca1d879 Zdenek Kabelac
{ MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1694
{ MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1695
{ MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1696
{ MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1697
{ MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1698
{ MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1699 247d56f5 Brian Becker
{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1700 5ca1d879 Zdenek Kabelac
{ MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1701
{ MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1702
{ MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1703
{ MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1704
{ MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1705
{ MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1706
{ MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1707
{ MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1708 a0f1f165 Måns Rullgård
{ MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1709 5ca1d879 Zdenek Kabelac
{ MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1710 d9b1c197 Roberto Togni
{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1711 6cea494e Zdenek Kabelac
/* extra mp4 */
1712 5ca1d879 Zdenek Kabelac
{ MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1713 6cea494e Zdenek Kabelac
/* QT atoms */
1714 5ca1d879 Zdenek Kabelac
{ MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1715
{ MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1716
{ MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1717
{ MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1718
{ MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1719
{ MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1720
{ MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1721
{ MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1722
{ MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1723
{ MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1724
{ MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1725
{ MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1726
{ MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1727
{ MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1728
{ MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1729
{ MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1730
//{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1731 0147f198 François Revol
#ifdef CONFIG_ZLIB
1732 5ca1d879 Zdenek Kabelac
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1733 0147f198 François Revol
#else
1734 5ca1d879 Zdenek Kabelac
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1735 0147f198 François Revol
#endif
1736 5ca1d879 Zdenek Kabelac
{ 0L, mov_read_leaf }
1737 6cea494e Zdenek Kabelac
};
1738
1739
static void mov_free_stream_context(MOVStreamContext *sc)
1740
{
1741
    if(sc) {
1742 c4ac052b Michael Niedermayer
        av_freep(&sc->chunk_offsets);
1743
        av_freep(&sc->sample_to_chunk);
1744
        av_freep(&sc->sample_sizes);
1745
        av_freep(&sc->keyframes);
1746 115329f1 Diego Biurrun
        av_freep(&sc->stts_data);
1747
        av_freep(&sc->ctts_data);
1748 c4ac052b Michael Niedermayer
        av_freep(&sc);
1749 6cea494e Zdenek Kabelac
    }
1750
}
1751
1752 5ca1d879 Zdenek Kabelac
static inline uint32_t mov_to_tag(uint8_t *buf)
1753 0e7eed09 Fabrice Bellard
{
1754 5ca1d879 Zdenek Kabelac
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1755 0e7eed09 Fabrice Bellard
}
1756
1757 5cd62665 Zdenek Kabelac
static inline uint32_t to_be32(uint8_t *buf)
1758 0e7eed09 Fabrice Bellard
{
1759
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1760
}
1761
1762 b6a17df4 Zdenek Kabelac
/* XXX: is it sufficient ? */
1763 c9a65ca8 Fabrice Bellard
static int mov_probe(AVProbeData *p)
1764
{
1765 0e7eed09 Fabrice Bellard
    unsigned int offset;
1766
    uint32_t tag;
1767 2497479f François Revol
    int score = 0;
1768 3ffe3793 François Revol
1769 c9a65ca8 Fabrice Bellard
    /* check file header */
1770
    if (p->buf_size <= 12)
1771
        return 0;
1772 0e7eed09 Fabrice Bellard
    offset = 0;
1773
    for(;;) {
1774
        /* ignore invalid offset */
1775
        if ((offset + 8) > (unsigned int)p->buf_size)
1776 2497479f François Revol
            return score;
1777 5ca1d879 Zdenek Kabelac
        tag = mov_to_tag(p->buf + offset + 4);
1778 0e7eed09 Fabrice Bellard
        switch(tag) {
1779 2497479f François Revol
        /* check for obvious tags */
1780 0e7eed09 Fabrice Bellard
        case MKTAG( 'm', 'o', 'o', 'v' ):
1781 8b879f18 François Revol
        case MKTAG( 'm', 'd', 'a', 't' ):
1782
        case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1783 bc634f6f Zdenek Kabelac
        case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1784 3ffe3793 François Revol
            return AVPROBE_SCORE_MAX;
1785 2497479f François Revol
        /* those are more common words, so rate then a bit less */
1786
        case MKTAG( 'w', 'i', 'd', 'e' ):
1787
        case MKTAG( 'f', 'r', 'e', 'e' ):
1788
        case MKTAG( 'j', 'u', 'n', 'k' ):
1789
        case MKTAG( 'p', 'i', 'c', 't' ):
1790
            return AVPROBE_SCORE_MAX - 5;
1791 0e7eed09 Fabrice Bellard
        case MKTAG( 'f', 't', 'y', 'p' ):
1792 5ca1d879 Zdenek Kabelac
        case MKTAG( 's', 'k', 'i', 'p' ):
1793 0d23cb84 François Revol
        case MKTAG( 'u', 'u', 'i', 'd' ):
1794 14342fd5 Johannes Carlsson
            offset = to_be32(p->buf+offset) + offset;
1795 2497479f François Revol
            /* if we only find those cause probedata is too small at least rate them */
1796
            score = AVPROBE_SCORE_MAX - 50;
1797 0e7eed09 Fabrice Bellard
            break;
1798
        default:
1799
            /* unrecognized tag */
1800 2497479f François Revol
            return score;
1801 0e7eed09 Fabrice Bellard
        }
1802 3ffe3793 François Revol
    }
1803 2497479f François Revol
    return score;
1804 c9a65ca8 Fabrice Bellard
}
1805
1806 a266644f Zdenek Kabelac
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1807 6cea494e Zdenek Kabelac
{
1808 b6a17df4 Zdenek Kabelac
    MOVContext *mov = (MOVContext *) s->priv_data;
1809 6cea494e Zdenek Kabelac
    ByteIOContext *pb = &s->pb;
1810 684f44d9 Zdenek Kabelac
    int i, j, nb, err;
1811 5ca1d879 Zdenek Kabelac
    MOV_atom_t atom = { 0, 0, 0 };
1812 6cea494e Zdenek Kabelac
1813
    mov->fc = s;
1814 b6a17df4 Zdenek Kabelac
    mov->parse_table = mov_default_parse_table;
1815 c9a65ca8 Fabrice Bellard
#if 0
1816
    /* XXX: I think we should auto detect */
1817
    if(s->iformat->name[1] == 'p')
1818 6cea494e Zdenek Kabelac
        mov->mp4 = 1;
1819 c9a65ca8 Fabrice Bellard
#endif
1820 6cea494e Zdenek Kabelac
    if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1821 bb270c08 Diego Biurrun
        atom.size = url_fsize(pb);
1822 6cea494e Zdenek Kabelac
    else
1823 bb270c08 Diego Biurrun
        atom.size = 0x7FFFFFFFFFFFFFFFLL;
1824 6cea494e Zdenek Kabelac
1825
#ifdef DEBUG
1826 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "filesz=%Ld\n", atom.size);
1827 6cea494e Zdenek Kabelac
#endif
1828
1829
    /* check MOV header */
1830 5ca1d879 Zdenek Kabelac
    err = mov_read_default(mov, pb, atom);
1831 25fa62e1 Zdenek Kabelac
    if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1832 bb270c08 Diego Biurrun
        av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1833
                err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1834
        return -1;
1835 6cea494e Zdenek Kabelac
    }
1836
#ifdef DEBUG
1837 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1838 6cea494e Zdenek Kabelac
#endif
1839
    /* some cleanup : make sure we are on the mdat atom */
1840
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1841
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1842
1843
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1844
1845
#ifdef DEBUG
1846 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "mdat_reset_offset=%d\n", (int) url_ftell(pb));
1847 6cea494e Zdenek Kabelac
#endif
1848
1849
#ifdef DEBUG
1850 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "streams= %d\n", s->nb_streams);
1851 6cea494e Zdenek Kabelac
#endif
1852
    mov->total_streams = nb = s->nb_streams;
1853 5ca1d879 Zdenek Kabelac
1854 6cea494e Zdenek Kabelac
#if 1
1855
    for(i=0; i<s->nb_streams;) {
1856 01f4895c Michael Niedermayer
        if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1857 1ea4f593 Fabrice Bellard
            av_free(s->streams[i]);
1858 6cea494e Zdenek Kabelac
            for(j=i+1; j<s->nb_streams; j++)
1859
                s->streams[j-1] = s->streams[j];
1860
            s->nb_streams--;
1861
        } else
1862
            i++;
1863
    }
1864
    for(i=0; i<s->nb_streams;i++) {
1865
        MOVStreamContext *sc;
1866
        sc = (MOVStreamContext *)s->streams[i]->priv_data;
1867
        sc->ffindex = i;
1868
        sc->is_ff_stream = 1;
1869
    }
1870
#endif
1871
#ifdef DEBUG
1872 baf25c9d Gael Chardon
    av_log(NULL, AV_LOG_DEBUG, "real streams= %d\n", s->nb_streams);
1873 6cea494e Zdenek Kabelac
#endif
1874
    return 0;
1875
}
1876
1877
/* Yes, this is ugly... I didn't write the specs of QT :p */
1878
/* XXX:remove useless commented code sometime */
1879 a266644f Zdenek Kabelac
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1880 6cea494e Zdenek Kabelac
{
1881 b6a17df4 Zdenek Kabelac
    MOVContext *mov = (MOVContext *) s->priv_data;
1882 0e7eed09 Fabrice Bellard
    MOVStreamContext *sc;
1883 86d8602f Michael Niedermayer
    int64_t offset = INT64_MAX;
1884
    int64_t best_dts = INT64_MAX;
1885 247d56f5 Brian Becker
    int i, a, b, m;
1886 5cd62665 Zdenek Kabelac
    int size;
1887 7619ed2b Roine Gustafsson
    int idx;
1888 6cea494e Zdenek Kabelac
    size = 0x0FFFFFFF;
1889 5cd62665 Zdenek Kabelac
1890 3ffe3793 François Revol
#ifdef MOV_SPLIT_CHUNKS
1891
    if (mov->partial) {
1892 bb270c08 Diego Biurrun
        sc = mov->partial;
1893
        idx = sc->sample_to_chunk_index;
1894 5cd62665 Zdenek Kabelac
1895 3ffe3793 François Revol
        if (idx < 0) return 0;
1896 7dbab4a9 François Revol
#ifdef DEBUG
1897
        fprintf(stderr, "sc[ffid %d]->sample_size = %d\n", sc->ffindex, sc->sample_size);
1898
#endif
1899 de39cdf5 Michael Niedermayer
        //size = sc->sample_sizes[sc->current_sample];
1900
        // that ain't working...
1901
        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1902
        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1903
1904 5cd62665 Zdenek Kabelac
        sc->current_sample++;
1905
        sc->left_in_chunk--;
1906 3ffe3793 François Revol
1907 5cd62665 Zdenek Kabelac
        if (sc->left_in_chunk <= 0)
1908 3ffe3793 François Revol
            mov->partial = 0;
1909
        offset = mov->next_chunk_offset;
1910
        /* extract the sample */
1911
1912
        goto readchunk;
1913
    }
1914
#endif
1915
1916 6cea494e Zdenek Kabelac
again:
1917 5cd62665 Zdenek Kabelac
    sc = 0;
1918 86d8602f Michael Niedermayer
    if(offset == INT64_MAX)
1919
        best_dts= INT64_MAX;
1920 6cea494e Zdenek Kabelac
    for(i=0; i<mov->total_streams; i++) {
1921 bb270c08 Diego Biurrun
        MOVStreamContext *msc = mov->streams[i];
1922 86d8602f Michael Niedermayer
1923
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1924
            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1925
                int64_t dts;
1926
                int index= msc->sample_to_time_index;
1927
                int sample= msc->sample_to_time_sample;
1928
                int time= msc->sample_to_time_time;
1929
                int duration = msc->stts_data[index].duration;
1930
                int count = msc->stts_data[index].count;
1931
                if (sample + count < msc->current_sample) {
1932
                    sample += count;
1933
                    time   += count*duration;
1934
                    index ++;
1935
                    duration = msc->stts_data[index].duration;
1936
                }
1937
                dts = time + (msc->current_sample-1 - sample) * (int64_t)duration;
1938
                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1939
//                av_log(NULL, AV_LOG_DEBUG, "%d %Ld %Ld %Ld \n", i, dts, best_dts, offset);
1940
                if(dts < best_dts){
1941
                    best_dts= dts;
1942
                    sc = msc;
1943
                    offset = msc->chunk_offsets[msc->next_chunk];
1944
                }
1945
            }else{
1946
            //av_log(NULL, AV_LOG_DEBUG, "MOCHUNK %ld  %d   %p  pos:%Ld\n", mov->streams[i]->next_chunk, mov->total_streams, mov->streams[i], url_ftell(&s->pb));
1947
                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1948
                    sc = msc;
1949
                    offset = msc->chunk_offsets[msc->next_chunk];
1950
                    //av_log(NULL, AV_LOG_DEBUG, "SELETED  %Ld  i:%d\n", offset, i);
1951
                }
1952
            }
1953 6cea494e Zdenek Kabelac
        }
1954
    }
1955 86d8602f Michael Niedermayer
    if (!sc || offset==INT64_MAX)
1956 bb270c08 Diego Biurrun
        return -1;
1957 5cd62665 Zdenek Kabelac
1958
    sc->next_chunk++;
1959
1960 3ffe3793 François Revol
    if(mov->next_chunk_offset < offset) { /* some meta data */
1961 6cea494e Zdenek Kabelac
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1962 3ffe3793 François Revol
        mov->next_chunk_offset = offset;
1963
    }
1964
1965 baf25c9d Gael Chardon
//av_log(NULL, AV_LOG_DEBUG, "chunk: [%i] %lli -> %lli\n", st_id, mov->next_chunk_offset, offset);
1966 f3356e9c Michael Niedermayer
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1967 6cea494e Zdenek Kabelac
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1968 3ffe3793 François Revol
        mov->next_chunk_offset = offset;
1969 bb270c08 Diego Biurrun
        offset = INT64_MAX;
1970 6cea494e Zdenek Kabelac
        goto again;
1971
    }
1972
1973
    /* now get the chunk size... */
1974
1975
    for(i=0; i<mov->total_streams; i++) {
1976 bb270c08 Diego Biurrun
        MOVStreamContext *msc = mov->streams[i];
1977
        if ((msc->next_chunk < msc->chunk_count)
1978 86d8602f Michael Niedermayer
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1979
            && msc->chunk_offsets[msc->next_chunk] > offset)
1980 bb270c08 Diego Biurrun
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1981 6cea494e Zdenek Kabelac
    }
1982 bc634f6f Zdenek Kabelac
1983
#ifdef MOV_MINOLTA_FIX
1984 115329f1 Diego Biurrun
    //Make sure that size is according to sample_size (Needed by .mov files
1985 bc634f6f Zdenek Kabelac
    //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1986
    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1987
    //but I have no such movies
1988 115329f1 Diego Biurrun
    if (sc->sample_size > 0) {
1989 bc634f6f Zdenek Kabelac
        int foundsize=0;
1990
        for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1991 92e51b66 Roine Gustafsson
            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1992 bc634f6f Zdenek Kabelac
            {
1993 bb270c08 Diego Biurrun
                // I can't figure out why for PCM audio sample_size is always 1
1994
                // (it should actually be channels*bits_per_second/8) but it is.
1995
                AVCodecContext* cod = s->streams[sc->ffindex]->codec;
1996 cac0a56c Roman Shaposhnik
                if (sc->sample_size == 1 && (cod->codec_id == CODEC_ID_PCM_S16BE || cod->codec_id == CODEC_ID_PCM_S16LE))
1997 bb270c08 Diego Biurrun
                    foundsize=(sc->sample_to_chunk[i].count*cod->channels*cod->bits_per_sample)/8;
1998
                else
1999
                    foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
2000 bc634f6f Zdenek Kabelac
            }
2001
#ifdef DEBUG
2002 c3ea71a0 François Revol
            av_log(NULL, AV_LOG_DEBUG, "sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id);
2003 bc634f6f Zdenek Kabelac
#endif
2004
        }
2005
        if( (foundsize>0) && (foundsize<size) )
2006
        {
2007
#ifdef DEBUG
2008 baf25c9d Gael Chardon
            /*av_log(NULL, AV_LOG_DEBUG, "this size should actually be %d\n",foundsize);*/
2009 bc634f6f Zdenek Kabelac
#endif
2010
            size=foundsize;
2011
        }
2012
    }
2013
#endif //MOV_MINOLTA_FIX
2014
2015 e2b9cf4e Michael Niedermayer
    idx = sc->sample_to_chunk_index;
2016
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
2017
        idx++;
2018
    sc->sample_to_chunk_index = idx;
2019 3ffe3793 François Revol
#ifdef MOV_SPLIT_CHUNKS
2020
    /* split chunks into samples */
2021 e2b9cf4e Michael Niedermayer
    if (sc->sample_size == 0 || sc->sample_size > 100) {
2022 7dbab4a9 François Revol
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
2023 bb270c08 Diego Biurrun
            mov->partial = sc;
2024 7dbab4a9 François Revol
            /* we'll have to get those samples before next chunk */
2025
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
2026 de39cdf5 Michael Niedermayer
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
2027 7dbab4a9 François Revol
        }
2028 7619ed2b Roine Gustafsson
2029 7dbab4a9 François Revol
        sc->current_sample++;
2030 e2b9cf4e Michael Niedermayer
    }else if(idx + 1 < sc->sample_to_chunk_sz){
2031
        sc->current_sample += sc->sample_size * sc->sample_to_chunk[idx].count;
2032 7dbab4a9 François Revol
    }
2033 3ffe3793 François Revol
#endif
2034
2035
readchunk:
2036 c3ea71a0 François Revol
#ifdef DEBUG
2037
    av_log(NULL, AV_LOG_DEBUG, "chunk: %lli -> %lli (%i)\n", offset, offset + size, size);
2038
#endif
2039 6cea494e Zdenek Kabelac
    if(size == 0x0FFFFFFF)
2040
        size = mov->mdat_size + mov->mdat_offset - offset;
2041
    if(size < 0)
2042
        return -1;
2043
    if(size == 0)
2044
        return -1;
2045 0e7eed09 Fabrice Bellard
    url_fseek(&s->pb, offset, SEEK_SET);
2046 5cd62665 Zdenek Kabelac
2047 2692067a Michael Niedermayer
    av_get_packet(&s->pb, pkt, size);
2048 0e7eed09 Fabrice Bellard
    pkt->stream_index = sc->ffindex;
2049 115329f1 Diego Biurrun
2050 247d56f5 Brian Becker
    // If the keyframes table exists, mark any samples that are in the table as key frames.
2051
    // If no table exists, treat very sample as a key frame.
2052 115329f1 Diego Biurrun
    if (sc->keyframes) {
2053 247d56f5 Brian Becker
        a = 0;
2054
        b = sc->keyframe_count - 1;
2055 115329f1 Diego Biurrun
2056 247d56f5 Brian Becker
        while (a < b) {
2057
            m = (a + b + 1) >> 1;
2058
            if (sc->keyframes[m] > sc->current_sample) {
2059
                b = m - 1;
2060
            } else {
2061
                a = m;
2062 115329f1 Diego Biurrun
            }
2063 247d56f5 Brian Becker
        }
2064 115329f1 Diego Biurrun
2065 247d56f5 Brian Becker
        if (sc->keyframes[a] == sc->current_sample)
2066
            pkt->flags |= PKT_FLAG_KEY;
2067
    }
2068
    else
2069
        pkt->flags |= PKT_FLAG_KEY;
2070 6cea494e Zdenek Kabelac
2071
#ifdef DEBUG
2072 7dbab4a9 François Revol
/*
2073 c3ea71a0 François Revol
    av_log(NULL, AV_LOG_DEBUG, "Packet (%d, %ld) ", pkt->stream_index, pkt->size);
2074 6cea494e Zdenek Kabelac
    for(i=0; i<8; i++)
2075 baf25c9d Gael Chardon
        av_log(NULL, AV_LOG_DEBUG, "%02x ", pkt->data[i]);
2076 6cea494e Zdenek Kabelac
    for(i=0; i<8; i++)
2077 baf25c9d Gael Chardon
        av_log(NULL, AV_LOG_DEBUG, "%c ", (pkt->data[i]) & 0x7F);
2078 c3ea71a0 François Revol
    av_log(NULL, AV_LOG_DEBUG, "\n");
2079 7dbab4a9 François Revol
*/
2080 6cea494e Zdenek Kabelac
#endif
2081
2082
    mov->next_chunk_offset = offset + size;
2083 115329f1 Diego Biurrun
2084
    /* find the corresponding dts */
2085
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
2086 cd461d48 Michael Niedermayer
      unsigned int count;
2087 c4ac052b Michael Niedermayer
      uint64_t dts, pts;
2088 cd461d48 Michael Niedermayer
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
2089
      count = sc->stts_data[sc->sample_to_time_index].count;
2090 115329f1 Diego Biurrun
      if ((sc->sample_to_time_sample + count) < sc->current_sample) {
2091
        sc->sample_to_time_sample += count;
2092
        sc->sample_to_time_time   += count*duration;
2093
        sc->sample_to_time_index ++;
2094 cd461d48 Michael Niedermayer
        duration = sc->stts_data[sc->sample_to_time_index].duration;
2095 115329f1 Diego Biurrun
      }
2096 cd461d48 Michael Niedermayer
      dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * (int64_t)duration;
2097 c4ac052b Michael Niedermayer
        /* find the corresponding pts */
2098
        if (sc->sample_to_ctime_index < sc->ctts_count) {
2099
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
2100
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
2101
2102
            if ((sc->sample_to_ctime_sample + count) < sc->current_sample) {
2103
                sc->sample_to_ctime_sample += count;
2104
                sc->sample_to_ctime_index ++;
2105
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
2106
            }
2107
            pts = dts + duration;
2108
        }else
2109
            pts = dts;
2110 961e0ccd Michael Niedermayer
        pkt->pts = pts;
2111
        pkt->dts = dts;
2112 c4ac052b Michael Niedermayer
#ifdef DEBUG
2113
    av_log(NULL, AV_LOG_DEBUG, "stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n"
2114
      , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
2115
      , sc->sample_to_time_sample
2116
      , sc->sample_to_time_time
2117
      , sc->sample_to_time_index
2118
      , sc->stts_count
2119
      , count
2120
      , duration);
2121
#endif
2122
    }
2123 6cea494e Zdenek Kabelac
2124
    return 0;
2125
}
2126
2127 baf25c9d Gael Chardon
#if defined(MOV_SPLIT_CHUNKS) && defined(MOV_SEEK)
2128
/**
2129
 * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
2130
 */
2131 961e0ccd Michael Niedermayer
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
2132 baf25c9d Gael Chardon
{
2133
    MOVContext* mov = (MOVContext *) s->priv_data;
2134
    MOVStreamContext* sc;
2135
    int32_t i, a, b, m;
2136
    int64_t start_time;
2137
    int32_t seek_sample, sample;
2138
    int32_t duration;
2139
    int32_t count;
2140
    int32_t chunk;
2141
    int32_t left_in_chunk;
2142
    int64_t chunk_file_offset;
2143
    int64_t sample_file_offset;
2144
    int32_t first_chunk_sample;
2145
    int32_t sample_to_chunk_idx;
2146 115329f1 Diego Biurrun
    int sample_to_time_index;
2147
    long sample_to_time_sample = 0;
2148
    uint64_t sample_to_time_time = 0;
2149 baf25c9d Gael Chardon
    int mov_idx;
2150
2151
    // Find the corresponding mov stream
2152
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
2153
        if (mov->streams[mov_idx]->ffindex == stream_index)
2154
            break;
2155
    if (mov_idx == mov->total_streams) {
2156
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
2157
        return -1;
2158
    }
2159
    sc = mov->streams[mov_idx];
2160
2161
    // Step 1. Find the edit that contains the requested time (elst)
2162
    if (sc->edit_count) {
2163
        // FIXME should handle edit list
2164
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
2165
        return -1;
2166
    }
2167
2168
    // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */
2169
#ifdef DEBUG
2170
  av_log(s, AV_LOG_DEBUG, "Searching for time %li in stream #%i (time_scale=%i)\n", (long)timestamp, mov_idx, sc->time_scale);
2171
#endif
2172
    start_time = 0; // FIXME use elst atom
2173
    sample = 1; // sample are 0 based in table
2174
#ifdef DEBUG
2175
    av_log(s, AV_LOG_DEBUG, "Searching for sample_time %li \n", (long)sample_time);
2176
#endif
2177
    for (i = 0; i < sc->stts_count; i++) {
2178 cd461d48 Michael Niedermayer
        count = sc->stts_data[i].count;
2179
        duration = sc->stts_data[i].duration;
2180 115329f1 Diego Biurrun
//av_log(s, AV_LOG_DEBUG, "> sample_time %lli \n", (long)sample_time);
2181
//av_log(s, AV_LOG_DEBUG, "> count=%i duration=%i\n", count, duration);
2182 baf25c9d Gael Chardon
        if ((start_time + count*duration) > sample_time) {
2183 115329f1 Diego Biurrun
            sample_to_time_time = start_time;
2184
            sample_to_time_index = i;
2185
            sample_to_time_sample = sample;
2186 baf25c9d Gael Chardon
            sample += (sample_time - start_time) / duration;
2187
            break;
2188
        }
2189
        sample += count;
2190
        start_time += count * duration;
2191 115329f1 Diego Biurrun
    }
2192
    sample_to_time_time = start_time;
2193
    sample_to_time_index = i;
2194 baf25c9d Gael Chardon
    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
2195
       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
2196
2197
#ifdef DEBUG
2198
    av_log(s, AV_LOG_DEBUG, "Found time %li at sample #%u\n", (long)sample_time, sample);
2199
#endif
2200
    if (sample > sc->sample_count) {
2201
        av_log(s, AV_LOG_ERROR, "mov: sample pos is too high, unable to seek (req. sample=%i, sample count=%ld)\n", sample, sc->sample_count);
2202
        return -1;
2203
    }
2204
2205
    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
2206
    if (sc->keyframes) {
2207
        a = 0;
2208
        b = sc->keyframe_count - 1;
2209
        while (a < b) {
2210
            m = (a + b + 1) >> 1;
2211
            if (sc->keyframes[m] > sample) {
2212
                b = m - 1;
2213
            } else {
2214
                a = m;
2215
            }
2216
#ifdef DEBUG
2217
         // av_log(s, AV_LOG_DEBUG, "a=%i (%i) b=%i (%i) m=%i (%i) stream #%i\n", a, sc->keyframes[a], b, sc->keyframes[b], m, sc->keyframes[m], mov_idx);
2218
#endif
2219
        }
2220 7fe5a3c0 Gael Chardon
        // for low latency prob: always use the previous keyframe, just uncomment the next line
2221
        // if (a) a--;
2222 baf25c9d Gael Chardon
        seek_sample = sc->keyframes[a];
2223
    }
2224
    else
2225
        seek_sample = sample; // else all samples are key frames
2226
#ifdef DEBUG
2227
    av_log(s, AV_LOG_DEBUG, "Found nearest keyframe at sample #%i \n", seek_sample);
2228
#endif
2229
2230
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2231
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2232
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2233
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2234
            break;
2235
        first_chunk_sample += b;
2236
    }
2237
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2238
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2239
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2240
    sample_to_chunk_idx = i;
2241
#ifdef DEBUG
2242
    av_log(s, AV_LOG_DEBUG, "Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2243
#endif
2244
2245
    // Step 5. Find the offset of the chunk using the chunk offset atom
2246
    if (!sc->chunk_offsets) {
2247
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2248
        return -1;
2249
    }
2250
    if (chunk > sc->chunk_count) {
2251
        av_log(s, AV_LOG_ERROR, "mov: chunk offset atom too short, unable to seek (req. chunk=%i, chunk count=%li)\n", chunk, sc->chunk_count);
2252
        return -1;
2253
    }
2254
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
2255
#ifdef DEBUG
2256
    av_log(s, AV_LOG_DEBUG, "Chunk file offset is #%llu \n", chunk_file_offset);
2257
#endif
2258
2259
    // Step 6. Find the byte offset within the chunk using the sample size atom
2260
    sample_file_offset = chunk_file_offset;
2261
    if (sc->sample_size)
2262
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2263
    else {
2264
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2265
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2266
        }
2267
    }
2268
#ifdef DEBUG
2269
    av_log(s, AV_LOG_DEBUG, "Sample file offset is #%llu \n", sample_file_offset);
2270
#endif
2271
2272
    // Step 6. Update the parser
2273
    mov->partial = sc;
2274
    mov->next_chunk_offset = sample_file_offset;
2275
    // Update current stream state
2276
    sc->current_sample = seek_sample - 1;  // zero based
2277
    sc->left_in_chunk = left_in_chunk;
2278
    sc->next_chunk = chunk; // +1 -1 (zero based)
2279
    sc->sample_to_chunk_index = sample_to_chunk_idx;
2280
2281 115329f1 Diego Biurrun
    // Update other streams
2282 baf25c9d Gael Chardon
    for (i = 0; i<mov->total_streams; i++) {
2283 5c030d3e Michel Bardiaux
        MOVStreamContext *msc;
2284 baf25c9d Gael Chardon
        if (i == mov_idx) continue;
2285
        // Find the nearest 'next' chunk
2286 5c030d3e Michel Bardiaux
        msc = mov->streams[i];
2287 baf25c9d Gael Chardon
        a = 0;
2288
        b = msc->chunk_count - 1;
2289
        while (a < b) {
2290
            m = (a + b + 1) >> 1;
2291
            if (msc->chunk_offsets[m] > chunk_file_offset) {
2292
                b = m - 1;
2293
            } else {
2294
                a = m;
2295
            }
2296 115329f1 Diego Biurrun
#ifdef DEBUG
2297 baf25c9d Gael Chardon
/*            av_log(s, AV_LOG_DEBUG, "a=%i (%li) b=%i (%li) m=%i (%li) stream #%i\n"
2298
            , a, (long)msc->chunk_offsets[a], b, (long)msc->chunk_offsets[b], m, (long)msc->chunk_offsets[m],  i); */
2299 115329f1 Diego Biurrun
#endif
2300 baf25c9d Gael Chardon
        }
2301
        msc->next_chunk = a;
2302
        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2303
            msc->next_chunk ++;
2304 115329f1 Diego Biurrun
#ifdef DEBUG
2305 baf25c9d Gael Chardon
        av_log(s, AV_LOG_DEBUG, "Nearest next chunk for stream #%i is #%i @%lli\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2306 115329f1 Diego Biurrun
#endif
2307 baf25c9d Gael Chardon
        // Compute sample count and index in the sample_to_chunk table (what a pity)
2308
        msc->sample_to_chunk_index = 0;
2309
        msc->current_sample = 0;
2310
        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2311
            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2312
            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2313
            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2314
        }
2315
        msc->current_sample += (msc->next_chunk - (msc->sample_to_chunk[msc->sample_to_chunk_index].first - 1)) * sc->sample_to_chunk[msc->sample_to_chunk_index].count;
2316
        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2317 115329f1 Diego Biurrun
        // Find corresponding position in stts (used later to compute dts)
2318
        sample = 0;
2319
        start_time = 0;
2320
        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2321 cd461d48 Michael Niedermayer
            count = msc->stts_data[msc->sample_to_time_index].count;
2322
            duration = msc->stts_data[msc->sample_to_time_index].duration;
2323 115329f1 Diego Biurrun
            if ((sample + count - 1) > msc->current_sample) {
2324
                msc->sample_to_time_time = start_time;
2325
                msc->sample_to_time_sample = sample;
2326
                break;
2327
            }
2328
            sample += count;
2329
            start_time += count * duration;
2330 c4ac052b Michael Niedermayer
        }
2331
        sample = 0;
2332
        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2333
            count = msc->ctts_data[msc->sample_to_ctime_index].count;
2334
            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2335
            if ((sample + count - 1) > msc->current_sample) {
2336
                msc->sample_to_ctime_sample = sample;
2337
                break;
2338
            }
2339
            sample += count;
2340 115329f1 Diego Biurrun
        }
2341
#ifdef DEBUG
2342 baf25c9d Gael Chardon
        av_log(s, AV_LOG_DEBUG, "Next Sample for stream #%i is #%i @%i\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2343 115329f1 Diego Biurrun
#endif
2344
    }
2345 baf25c9d Gael Chardon
    return 0;
2346
}
2347
#endif
2348
2349 a266644f Zdenek Kabelac
static int mov_read_close(AVFormatContext *s)
2350 6cea494e Zdenek Kabelac
{
2351
    int i;
2352 b6a17df4 Zdenek Kabelac
    MOVContext *mov = (MOVContext *) s->priv_data;
2353 6cea494e Zdenek Kabelac
    for(i=0; i<mov->total_streams; i++)
2354
        mov_free_stream_context(mov->streams[i]);
2355 5ca1d879 Zdenek Kabelac
    /* free color tabs */
2356
    for(i=0; i<mov->ctab_size; i++)
2357 bb270c08 Diego Biurrun
        av_freep(&mov->ctab[i]);
2358 5ca1d879 Zdenek Kabelac
    av_freep(&mov->ctab);
2359 6cea494e Zdenek Kabelac
    return 0;
2360
}
2361
2362 c9a65ca8 Fabrice Bellard
static AVInputFormat mov_iformat = {
2363 8536ab89 tjraivio@cc.hut.fi
    "mov,mp4,m4a,3gp,3g2",
2364 c9a65ca8 Fabrice Bellard
    "QuickTime/MPEG4 format",
2365
    sizeof(MOVContext),
2366
    mov_probe,
2367 6cea494e Zdenek Kabelac
    mov_read_header,
2368
    mov_read_packet,
2369
    mov_read_close,
2370 baf25c9d Gael Chardon
#if defined(MOV_SPLIT_CHUNKS) && defined(MOV_SEEK)
2371
    mov_read_seek,
2372 115329f1 Diego Biurrun
#endif
2373 6cea494e Zdenek Kabelac
};
2374
2375 c9a65ca8 Fabrice Bellard
int mov_init(void)
2376
{
2377
    av_register_input_format(&mov_iformat);
2378
    return 0;
2379
}