Statistics
| Branch: | Revision:

ffmpeg / libavformat / mov.c @ 6a045bf3

History | View | Annotate | Download (73.5 KB)

1
/*
2
 * MOV decoder.
3
 * Copyright (c) 2001 Fabrice Bellard.
4
 *
5
 * This library is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU Lesser General Public
7
 * License as published by the Free Software Foundation; either
8
 * version 2 of the License, or (at your option) any later version.
9
 *
10
 * This library is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
 * Lesser General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU Lesser General Public
16
 * License along with this library; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
 */
19

    
20
#include <limits.h>
21

    
22
//#define DEBUG
23

    
24
#include "avformat.h"
25
#include "avi.h"
26
#include "mov.h"
27

    
28
#ifdef CONFIG_ZLIB
29
#include <zlib.h>
30
#endif
31

    
32
/*
33
 * First version by Francois Revol revol@free.fr
34
 * Seek function by Gael Chardon gael.dev@4now.net
35
 *
36
 * Features and limitations:
37
 * - reads most of the QT files I have (at least the structure),
38
 *   the exceptions are .mov with zlib compressed headers ('cmov' section). It shouldn't be hard to implement.
39
 *   FIXED, Francois Revol, 07/17/2002
40
 * - ffmpeg has nearly none of the usual QuickTime codecs,
41
 *   although I succesfully dumped raw and mp3 audio tracks off .mov files.
42
 *   Sample QuickTime files with mp3 audio can be found at: http://www.3ivx.com/showcase.html
43
 * - .mp4 parsing is still hazardous, although the format really is QuickTime with some minor changes
44
 *   (to make .mov parser crash maybe ?), despite what they say in the MPEG FAQ at
45
 *   http://mpeg.telecomitalialab.com/faq.htm
46
 * - the code is quite ugly... maybe I won't do it recursive next time :-)
47
 * - seek is not supported with files that contain edit list
48
 *
49
 * Funny I didn't know about http://sourceforge.net/projects/qt-ffmpeg/
50
 * when coding this :) (it's a writer anyway)
51
 *
52
 * Reference documents:
53
 * http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
54
 * Apple:
55
 *  http://developer.apple.com/documentation/QuickTime/QTFF/
56
 *  http://developer.apple.com/documentation/QuickTime/QTFF/qtff.pdf
57
 * QuickTime is a trademark of Apple (AFAIK :))
58
 */
59

    
60
#include "qtpalette.h"
61

    
62

    
63
#undef NDEBUG
64
#include <assert.h>
65

    
66
/* Allows seeking */
67
#define MOV_SEEK
68

    
69
/* Special handling for movies created with Minolta Dimaxe Xi*/
70
/* this fix should not interfere with other .mov files, but just in case*/
71
#define MOV_MINOLTA_FIX
72

    
73
/* some streams in QT (and in MP4 mostly) aren't either video nor audio */
74
/* so we first list them as this, then clean up the list of streams we give back, */
75
/* getting rid of these */
76
#define CODEC_TYPE_MOV_OTHER    (enum CodecType) 2
77

    
78
/* http://gpac.sourceforge.net/tutorial/mediatypes.htm */
79
const CodecTag ff_mov_obj_type[] = {
80
    { CODEC_ID_MPEG4     ,  32 },
81
    { CODEC_ID_H264      ,  33 },
82
    { CODEC_ID_AAC       ,  64 },
83
    { CODEC_ID_MPEG2VIDEO,  96 }, /* MPEG2 Simple */
84
    { CODEC_ID_MPEG2VIDEO,  97 }, /* MPEG2 Main */
85
    { CODEC_ID_MPEG2VIDEO,  98 }, /* MPEG2 SNR */
86
    { CODEC_ID_MPEG2VIDEO,  99 }, /* MPEG2 Spatial */
87
    { CODEC_ID_MPEG2VIDEO, 100 }, /* MPEG2 High */
88
    { CODEC_ID_MPEG2VIDEO, 101 }, /* MPEG2 422 */
89
    { CODEC_ID_AAC       , 102 }, /* MPEG2 AAC Main */
90
    { CODEC_ID_AAC       , 103 }, /* MPEG2 AAC Low */
91
    { CODEC_ID_AAC       , 104 }, /* MPEG2 AAC SSR */
92
    { CODEC_ID_MP3       , 105 },
93
    { CODEC_ID_MPEG1VIDEO, 106 },
94
    { CODEC_ID_MP2       , 107 },
95
    { CODEC_ID_MJPEG     , 108 },
96
    { CODEC_ID_PCM_S16LE , 224 },
97
    { CODEC_ID_VORBIS    , 225 },
98
    { CODEC_ID_AC3       , 226 },
99
    { CODEC_ID_PCM_ALAW  , 227 },
100
    { CODEC_ID_PCM_MULAW , 228 },
101
    { CODEC_ID_PCM_S16BE , 230 },
102
    { CODEC_ID_H263      , 242 },
103
    { CODEC_ID_H261      , 243 },
104
    { 0, 0 },
105
};
106

    
107
static const CodecTag mov_video_tags[] = {
108
/*  { CODEC_ID_, MKTAG('c', 'v', 'i', 'd') }, *//* Cinepak */
109
/*  { CODEC_ID_H263, MKTAG('r', 'a', 'w', ' ') }, *//* Uncompressed RGB */
110
/*  { CODEC_ID_H263, MKTAG('Y', 'u', 'v', '2') }, *//* Uncompressed YUV422 */
111
/*    { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'U', 'I') }, *//* YUV with alpha-channel (AVID Uncompressed) */
112
/* Graphics */
113
/* Animation */
114
/* Apple video */
115
/* Kodak Photo CD */
116
    { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */
117
    { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
118
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */
119
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */
120
    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */
121
/*    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */
122
/*    { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, *//* embedded gif files as frames (usually one "click to play movie" frame) */
123
/* Sorenson video */
124
    { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */
125
    { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */
126
    { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/
127
    { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */
128
    { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
129
    { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
130
    { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
131
    { CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, /* experimental: 3IVX files before ivx D4 4.5.1 */
132
/*    { CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */
133
    { CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H263 */
134
    { CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H263 ?? works */
135
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */
136
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */
137
/*    { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, *//* AVID dv */
138
    { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */
139
    { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */
140
    { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */
141
    { CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */
142
    { CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */
143
    { CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */
144
    { CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */
145
    { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */
146
    { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 produced by Sony HD camera */
147
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX 635/50 50mb/s produced by FCP */
148
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG2 IMX 635/50 30mb/s produced by FCP */
149
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') }, /* DVCPRO PAL produced by FCP */
150
    //{ CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') }, /* DVCPRO HD produced by FCP */
151
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 produced by FCP */
152
    { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* HDV produced by FCP */
153
    //{ CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */
154
    { CODEC_ID_NONE, 0 },
155
};
156

    
157
static const CodecTag mov_audio_tags[] = {
158
    { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') },
159
    { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
160
/*    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */
161
    { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
162
    /* { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') },*/ /* 8 bits */
163
    { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
164
    { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /*  */
165
    { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /*  */
166
    { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /*  */
167
    { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */
168
    { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */
169
    { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */
170

    
171
    { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */
172
    { CODEC_ID_MP2, 0x6D730055 }, /* MPEG layer 3 */
173
    { CODEC_ID_MP2, 0x5500736D }, /* MPEG layer 3 *//* XXX: check endianness */
174
/*    { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
175
/* MP4 tags */
176
    { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, /* MPEG-4 AAC */
177
    /* The standard for mpeg4 audio is still not normalised AFAIK anyway */
178
    { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */
179
    { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */
180
    { CODEC_ID_AC3, MKTAG('m', 's', 0x20, 0x00) }, /* Dolby AC-3 */
181
    { CODEC_ID_ALAC,MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */
182
    { CODEC_ID_QDM2,MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */
183
    { CODEC_ID_NONE, 0 },
184
};
185

    
186
/* map numeric codes from mdhd atom to ISO 639 */
187
/* cf. QTFileFormat.pdf p253, qtff.pdf p205 */
188
/* http://developer.apple.com/documentation/mac/Text/Text-368.html */
189
/* deprecated by putting the code as 3*5bit ascii */
190
static const char *mov_mdhd_language_map[] = {
191
/* 0-9 */
192
"eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
193
"heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/,
194
"urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav",  NULL,
195
"fo ",  NULL, "rus", "chi",  NULL, "iri", "alb", "ron", "ces", "slk",
196
"slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
197
/*?*/
198
"aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon",  NULL, "pus",
199
"kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
200
"pa ", "ori", "mal", "kan", "tam", "tel",  NULL, "bur", "khm", "lao",
201
/*                   roman? arabic? */
202
"vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
203
/*==rundi?*/
204
 NULL, "run",  NULL, "mlg", "epo",  NULL,  NULL,  NULL,  NULL,  NULL,
205
/* 100 */
206
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
207
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
208
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, "wel", "baq",
209
"cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
210
};
211

    
212
/* the QuickTime file format is quite convoluted...
213
 * it has lots of index tables, each indexing something in another one...
214
 * Here we just use what is needed to read the chunks
215
 */
216

    
217
typedef struct MOV_sample_to_chunk_tbl {
218
    long first;
219
    long count;
220
    long id;
221
} MOV_sample_to_chunk_tbl;
222

    
223
typedef struct {
224
    uint32_t type;
225
    int64_t offset;
226
    int64_t size; /* total size (excluding the size and type fields) */
227
} MOV_atom_t;
228

    
229
typedef struct {
230
    int seed;
231
    int flags;
232
    int size;
233
    void* clrs;
234
} MOV_ctab_t;
235

    
236
typedef struct {
237
    uint8_t  version;
238
    uint32_t flags; // 24bit
239

    
240
    /* 0x03 ESDescrTag */
241
    uint16_t es_id;
242
#define MP4ODescrTag                    0x01
243
#define MP4IODescrTag                   0x02
244
#define MP4ESDescrTag                   0x03
245
#define MP4DecConfigDescrTag            0x04
246
#define MP4DecSpecificDescrTag          0x05
247
#define MP4SLConfigDescrTag             0x06
248
#define MP4ContentIdDescrTag            0x07
249
#define MP4SupplContentIdDescrTag       0x08
250
#define MP4IPIPtrDescrTag               0x09
251
#define MP4IPMPPtrDescrTag              0x0A
252
#define MP4IPMPDescrTag                 0x0B
253
#define MP4RegistrationDescrTag         0x0D
254
#define MP4ESIDIncDescrTag              0x0E
255
#define MP4ESIDRefDescrTag              0x0F
256
#define MP4FileIODescrTag               0x10
257
#define MP4FileODescrTag                0x11
258
#define MP4ExtProfileLevelDescrTag      0x13
259
#define MP4ExtDescrTagsStart            0x80
260
#define MP4ExtDescrTagsEnd              0xFE
261
    uint8_t  stream_priority;
262

    
263
    /* 0x04 DecConfigDescrTag */
264
    uint8_t  object_type_id;
265
    uint8_t  stream_type;
266
    /* XXX: really streamType is
267
     * only 6bit, followed by:
268
     * 1bit  upStream
269
     * 1bit  reserved
270
     */
271
    uint32_t buffer_size_db; // 24
272
    uint32_t max_bitrate;
273
    uint32_t avg_bitrate;
274

    
275
    /* 0x05 DecSpecificDescrTag */
276
    uint8_t  decoder_cfg_len;
277
    uint8_t *decoder_cfg;
278

    
279
    /* 0x06 SLConfigDescrTag */
280
    uint8_t  sl_config_len;
281
    uint8_t *sl_config;
282
} MOV_esds_t;
283

    
284
struct MOVParseTableEntry;
285

    
286
typedef struct MOVStreamContext {
287
    int ffindex; /* the ffmpeg stream id */
288
    int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */
289
    long next_chunk;
290
    long chunk_count;
291
    int64_t *chunk_offsets;
292
    int stts_count;
293
    Time2Sample *stts_data;
294
    int ctts_count;
295
    Time2Sample *ctts_data;
296
    int edit_count;             /* number of 'edit' (elst atom) */
297
    long sample_to_chunk_sz;
298
    MOV_sample_to_chunk_tbl *sample_to_chunk;
299
    long sample_to_chunk_index;
300
    int sample_to_time_index;
301
    long sample_to_time_sample;
302
    uint64_t sample_to_time_time;
303
    int sample_to_ctime_index;
304
    int sample_to_ctime_sample;
305
    long sample_size;
306
    long sample_count;
307
    long *sample_sizes;
308
    long keyframe_count;
309
    long *keyframes;
310
    int time_scale;
311
    int time_rate;
312
    long current_sample;
313
    long left_in_chunk; /* how many samples before next chunk */
314
    MOV_esds_t esds;
315
} MOVStreamContext;
316

    
317
typedef struct MOVContext {
318
    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) */
319
    AVFormatContext *fc;
320
    int time_scale;
321
    int duration; /* duration of the longest track */
322
    int found_moov; /* when both 'moov' and 'mdat' sections has been found */
323
    int found_mdat; /* we suppose we have enough data to read the file */
324
    int64_t mdat_size;
325
    int64_t mdat_offset;
326
    int ni;                                         ///< non interleaved mode
327
    int total_streams;
328
    /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio
329
     * but we need the info to be able to skip data from those streams in the 'mdat' section
330
     */
331
    MOVStreamContext *streams[MAX_STREAMS];
332

    
333
    int64_t next_chunk_offset;
334
    MOVStreamContext *partial; /* != 0 : there is still to read in the current chunk */
335
    int ctab_size;
336
    MOV_ctab_t **ctab;           /* color tables */
337
    const struct MOVParseTableEntry *parse_table; /* could be eventually used to change the table */
338
    /* NOTE: for recursion save to/ restore from local variable! */
339

    
340
    AVPaletteControl palette_control;
341
} MOVContext;
342

    
343

    
344
/* XXX: it's the first time I make a recursive parser I think... sorry if it's ugly :P */
345

    
346
/* those functions parse an atom */
347
/* return code:
348
 1: found what I wanted, exit
349
 0: continue to parse next atom
350
 -1: error occured, exit
351
 */
352
typedef int (*mov_parse_function)(MOVContext *ctx, ByteIOContext *pb, MOV_atom_t atom);
353

    
354
/* links atom IDs to parse functions */
355
typedef struct MOVParseTableEntry {
356
    uint32_t type;
357
    mov_parse_function func;
358
} MOVParseTableEntry;
359

    
360
static int ff_mov_lang_to_iso639(int code, char *to)
361
{
362
    int i;
363
    /* is it the mangled iso code? */
364
    /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */
365
    if (code > 138) {
366
        for (i = 2; i >= 0; i--) {
367
            to[i] = 0x60 + (code & 0x1f);
368
            code >>= 5;
369
        }
370
        return 1;
371
    }
372
    /* old fashion apple lang code */
373
    if (code >= (sizeof(mov_mdhd_language_map)/sizeof(char *)))
374
        return 0;
375
    if (!mov_mdhd_language_map[code])
376
        return 0;
377
    strncpy(to, mov_mdhd_language_map[code], 4);
378
    return 1;
379
}
380

    
381
extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */
382
int ff_mov_iso639_to_lang(const char *lang, int mp4)
383
{
384
    int i, code = 0;
385

    
386
    /* old way, only for QT? */
387
    for (i = 0; !mp4 && (i < (sizeof(mov_mdhd_language_map)/sizeof(char *))); i++) {
388
        if (mov_mdhd_language_map[i] && !strcmp(lang, mov_mdhd_language_map[i]))
389
            return i;
390
    }
391
    /* XXX:can we do that in mov too? */
392
    if (!mp4)
393
        return 0;
394
    /* handle undefined as such */
395
    if (lang[0] == '\0')
396
        lang = "und";
397
    /* 5bit ascii */
398
    for (i = 0; i < 3; i++) {
399
        unsigned char c = (unsigned char)lang[i];
400
        if (c < 0x60)
401
            return 0;
402
        if (c > 0x60 + 0x1f)
403
            return 0;
404
        code <<= 5;
405
        code |= (c - 0x60);
406
    }
407
    return code;
408
}
409

    
410
static int mov_read_leaf(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
411
{
412
    if (atom.size>1)
413
        url_fskip(pb, atom.size);
414
/*        url_seek(pb, atom_offset+atom.size, SEEK_SET); */
415
    return 0;
416
}
417

    
418
static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
419
{
420
    int64_t total_size = 0;
421
    MOV_atom_t a;
422
    int i;
423
    int err = 0;
424

    
425
    a.offset = atom.offset;
426

    
427
    if (atom.size < 0)
428
        atom.size = 0x7fffffffffffffffLL;
429
    while(((total_size + 8) < atom.size) && !url_feof(pb) && !err) {
430
        a.size = atom.size;
431
        a.type=0L;
432
        if(atom.size >= 8) {
433
            a.size = get_be32(pb);
434
            a.type = get_le32(pb);
435
        }
436
        total_size += 8;
437
        a.offset += 8;
438
        dprintf("type: %08x  %.4s  sz: %Lx  %Lx   %Lx\n", a.type, (char*)&a.type, a.size, atom.size, total_size);
439
        if (a.size == 1) { /* 64 bit extended size */
440
            a.size = get_be64(pb) - 8;
441
            a.offset += 8;
442
            total_size += 8;
443
        }
444
        if (a.size == 0) {
445
            a.size = atom.size - total_size;
446
            if (a.size <= 8)
447
                break;
448
        }
449
        for (i = 0; c->parse_table[i].type != 0L
450
             && c->parse_table[i].type != a.type; i++)
451
            /* empty */;
452

    
453
        a.size -= 8;
454

    
455
        if(a.size < 0)
456
            break;
457

    
458
        if (c->parse_table[i].type == 0) { /* skip leaf atoms data */
459
            url_fskip(pb, a.size);
460
        } else {
461
            err = (c->parse_table[i].func)(c, pb, a);
462
        }
463

    
464
        a.offset += a.size;
465
        total_size += a.size;
466
    }
467

    
468
    if (!err && total_size < atom.size && atom.size < 0x7ffff) {
469
        url_fskip(pb, atom.size - total_size);
470
    }
471

    
472
    return err;
473
}
474

    
475
static int mov_read_ctab(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
476
{
477
#if 1
478
    url_fskip(pb, atom.size); // for now
479
#else
480
    VERY VERY BROKEN, NEVER execute this, needs rewrite
481
    unsigned int len;
482
    MOV_ctab_t *t;
483
    c->ctab = av_realloc(c->ctab, ++c->ctab_size);
484
    t = c->ctab[c->ctab_size];
485
    t->seed = get_be32(pb);
486
    t->flags = get_be16(pb);
487
    t->size = get_be16(pb) + 1;
488
    len = 2 * t->size * 4;
489
    if (len > 0) {
490
        t->clrs = av_malloc(len); // 16bit A R G B
491
        if (t->clrs)
492
            get_buffer(pb, t->clrs, len);
493
    }
494
#endif
495

    
496
    return 0;
497
}
498

    
499
static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
500
{
501
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
502
    int len = 0;
503
    uint32_t type;
504
    uint32_t ctype;
505

    
506
    get_byte(pb); /* version */
507
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
508

    
509
    /* component type */
510
    ctype = get_le32(pb);
511
    type = get_le32(pb); /* component subtype */
512

    
513
    dprintf("ctype= %c%c%c%c (0x%08lx)\n", *((char *)&ctype), ((char *)&ctype)[1], ((char *)&ctype)[2], ((char *)&ctype)[3], (long) ctype);
514
    dprintf("stype= %c%c%c%c\n", *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]);
515
    if(ctype == MKTAG('m', 'h', 'l', 'r')) /* MOV */
516
        c->mp4 = 0;
517
    else if(ctype == 0)
518
        c->mp4 = 1;
519
    if(type == MKTAG('v', 'i', 'd', 'e'))
520
        st->codec->codec_type = CODEC_TYPE_VIDEO;
521
    else if(type == MKTAG('s', 'o', 'u', 'n'))
522
        st->codec->codec_type = CODEC_TYPE_AUDIO;
523
    get_be32(pb); /* component  manufacture */
524
    get_be32(pb); /* component flags */
525
    get_be32(pb); /* component flags mask */
526

    
527
    if(atom.size <= 24)
528
        return 0; /* nothing left to read */
529
    /* XXX: MP4 uses a C string, not a pascal one */
530
    /* component name */
531

    
532
    if(c->mp4) {
533
        /* .mp4: C string */
534
        while(get_byte(pb) && (++len < (atom.size - 24)));
535
    } else {
536
        /* .mov: PASCAL string */
537
        len = get_byte(pb);
538
        url_fskip(pb, len);
539
    }
540

    
541
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
542
    return 0;
543
}
544

    
545
static int mov_mp4_read_descr_len(ByteIOContext *pb)
546
{
547
    int len = 0;
548
    int count = 4;
549
    while (count--) {
550
        int c = get_byte(pb);
551
        len = (len << 7) | (c & 0x7f);
552
        if (!(c & 0x80))
553
            break;
554
    }
555
    return len;
556
}
557

    
558
static int mov_mp4_read_descr(ByteIOContext *pb, int *tag)
559
{
560
    int len;
561
    *tag = get_byte(pb);
562
    len = mov_mp4_read_descr_len(pb);
563
    dprintf("MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
564
    return len;
565
}
566

    
567
static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
568
{
569
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
570
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
571
    int64_t start_pos = url_ftell(pb);
572
    int tag, len;
573

    
574
    /* Well, broken but suffisant for some MP4 streams */
575
    get_be32(pb); /* version + flags */
576
    len = mov_mp4_read_descr(pb, &tag);
577
    if (tag == MP4ESDescrTag) {
578
        get_be16(pb); /* ID */
579
        get_byte(pb); /* priority */
580
    } else
581
        get_be16(pb); /* ID */
582

    
583
    len = mov_mp4_read_descr(pb, &tag);
584
    if (tag == MP4DecConfigDescrTag) {
585
        sc->esds.object_type_id = get_byte(pb);
586
        sc->esds.stream_type = get_byte(pb);
587
        sc->esds.buffer_size_db = get_be24(pb);
588
        sc->esds.max_bitrate = get_be32(pb);
589
        sc->esds.avg_bitrate = get_be32(pb);
590

    
591
        st->codec->codec_id= codec_get_id(ff_mov_obj_type, sc->esds.object_type_id);
592
        len = mov_mp4_read_descr(pb, &tag);
593
        if (tag == MP4DecSpecificDescrTag) {
594
            dprintf("Specific MPEG4 header len=%d\n", len);
595
            st->codec->extradata = (uint8_t*) av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
596
            if (st->codec->extradata) {
597
                get_buffer(pb, st->codec->extradata, len);
598
                st->codec->extradata_size = len;
599
            }
600
        }
601
    }
602
    /* in any case, skip garbage */
603
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
604
    return 0;
605
}
606

    
607
/* this atom contains actual media data */
608
static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
609
{
610
    if(atom.size == 0) /* wrong one (MP4) */
611
        return 0;
612
    c->found_mdat=1;
613
    c->mdat_offset = atom.offset;
614
    c->mdat_size = atom.size;
615
    if(c->found_moov)
616
        return 1; /* found both, just go */
617
    url_fskip(pb, atom.size);
618
    return 0; /* now go for moov */
619
}
620

    
621
static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
622
{
623
    uint32_t type = get_le32(pb);
624

    
625
    /* from mplayer */
626
    switch (type) {
627
    case MKTAG('i', 's', 'o', 'm'):
628
    case MKTAG('m', 'p', '4', '1'):
629
    case MKTAG('m', 'p', '4', '2'):
630
    case MKTAG('3', 'g', 'p', '1'):
631
    case MKTAG('3', 'g', 'p', '2'):
632
    case MKTAG('3', 'g', '2', 'a'):
633
    case MKTAG('3', 'g', 'p', '3'):
634
    case MKTAG('3', 'g', 'p', '4'):
635
    case MKTAG('3', 'g', 'p', '5'):
636
    case MKTAG('m', 'm', 'p', '4'): /* Mobile MP4 */
637
    case MKTAG('M', '4', 'A', ' '): /* Apple iTunes AAC-LC Audio */
638
    case MKTAG('M', '4', 'P', ' '): /* Apple iTunes AAC-LC Protected Audio */
639
        c->mp4 = 1;
640
    case MKTAG('q', 't', ' ', ' '):
641
        av_log(c->fc, AV_LOG_DEBUG, "ISO: File Type Major Brand: %.4s\n",(char *)&type);
642
    }
643
    get_be32(pb); /* minor version */
644
    url_fskip(pb, atom.size - 8);
645
    return 0;
646
}
647

    
648
/* this atom should contain all header atoms */
649
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
650
{
651
    int err;
652

    
653
    err = mov_read_default(c, pb, atom);
654
    /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
655
    /* so we don't parse the whole file if over a network */
656
    c->found_moov=1;
657
    if(c->found_mdat)
658
        return 1; /* found both, just go */
659
    return 0; /* now go for mdat */
660
}
661

    
662

    
663
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
664
{
665
    int version;
666
    int lang;
667

    
668
    version = get_byte(pb); /* version */
669
    if (version > 1)
670
        return 1; /* unsupported */
671

    
672
    get_byte(pb); get_byte(pb);
673
    get_byte(pb); /* flags */
674

    
675
    (version==1)?get_be64(pb):get_be32(pb); /* creation time */
676
    (version==1)?get_be64(pb):get_be32(pb); /* modification time */
677

    
678
    c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb);
679
    c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
680

    
681
    lang = get_be16(pb); /* language */
682
    ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
683
    get_be16(pb); /* quality */
684

    
685
    return 0;
686
}
687

    
688
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
689
{
690
    get_byte(pb); /* version */
691
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
692

    
693
    get_be32(pb); /* creation time */
694
    get_be32(pb); /* modification time */
695
    c->time_scale = get_be32(pb); /* time scale */
696
#ifdef DEBUG
697
    av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);
698
#endif
699
    c->duration = get_be32(pb); /* duration */
700
    get_be32(pb); /* preferred scale */
701

    
702
    get_be16(pb); /* preferred volume */
703

    
704
    url_fskip(pb, 10); /* reserved */
705

    
706
    url_fskip(pb, 36); /* display matrix */
707

    
708
    get_be32(pb); /* preview time */
709
    get_be32(pb); /* preview duration */
710
    get_be32(pb); /* poster time */
711
    get_be32(pb); /* selection time */
712
    get_be32(pb); /* selection duration */
713
    get_be32(pb); /* current time */
714
    get_be32(pb); /* next track ID */
715

    
716
    return 0;
717
}
718

    
719
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
720
{
721
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
722

    
723
    if((uint64_t)atom.size > (1<<30))
724
        return -1;
725

    
726
    // currently SVQ3 decoder expect full STSD header - so let's fake it
727
    // this should be fixed and just SMI header should be passed
728
    av_free(st->codec->extradata);
729
    st->codec->extradata_size = 0x5a + atom.size;
730
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
731

    
732
    if (st->codec->extradata) {
733
        strcpy(st->codec->extradata, "SVQ3"); // fake
734
        get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
735
        dprintf("Reading SMI %Ld  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
736
    } else
737
        url_fskip(pb, atom.size);
738

    
739
    return 0;
740
}
741

    
742
static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
743
{
744
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
745
    int little_endian = get_be16(pb);
746

    
747
    if (little_endian) {
748
        switch (st->codec->codec_id) {
749
        case CODEC_ID_PCM_S24BE:
750
            st->codec->codec_id = CODEC_ID_PCM_S24LE;
751
            break;
752
        case CODEC_ID_PCM_S32BE:
753
            st->codec->codec_id = CODEC_ID_PCM_S32LE;
754
            break;
755
        default:
756
            break;
757
        }
758
    }
759
    return 0;
760
}
761

    
762
static int mov_read_alac(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
763
{
764
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
765

    
766
    // currently ALAC decoder expect full atom header - so let's fake it
767
    // this should be fixed and just ALAC header should be passed
768

    
769
    av_free(st->codec->extradata);
770
    st->codec->extradata_size = 36;
771
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
772

    
773
    if (st->codec->extradata) {
774
        strcpy(st->codec->extradata + 4, "alac"); // fake
775
        get_buffer(pb, st->codec->extradata + 8, 36 - 8);
776
        dprintf("Reading alac %Ld  %s\n", st->codec->extradata_size, (char*)st->codec->extradata);
777
    } else
778
        url_fskip(pb, atom.size);
779
    return 0;
780
}
781

    
782
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
783
{
784
    offset_t start_pos = url_ftell(pb);
785
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
786

    
787
    if((uint64_t)atom.size > (1<<30))
788
        return -1;
789

    
790
    if (st->codec->codec_id == CODEC_ID_QDM2) {
791
        // pass all frma atom to codec, needed at least for QDM2
792
        av_free(st->codec->extradata);
793
        st->codec->extradata_size = atom.size;
794
        st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
795

    
796
        if (st->codec->extradata) {
797
            get_buffer(pb, st->codec->extradata, atom.size);
798
        } else
799
            url_fskip(pb, atom.size);
800
    } else if (atom.size > 8) { /* to read frma, esds atoms */
801
        mov_read_default(c, pb, atom);
802
    } else if (atom.size > 0)
803
        url_fskip(pb, atom.size);
804
    /* in any case, skip garbage */
805
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
806
    return 0;
807
}
808

    
809
static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
810
{
811
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
812

    
813
    if((uint64_t)atom.size > (1<<30))
814
        return -1;
815

    
816
    av_free(st->codec->extradata);
817

    
818
    st->codec->extradata_size = atom.size;
819
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
820

    
821
    if (st->codec->extradata) {
822
        get_buffer(pb, st->codec->extradata, atom.size);
823
    } else
824
        url_fskip(pb, atom.size);
825

    
826
    return 0;
827
}
828

    
829
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
830
{
831
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
832
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
833
    unsigned int i, entries;
834

    
835
    get_byte(pb); /* version */
836
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
837

    
838
    entries = get_be32(pb);
839

    
840
    if(entries >= UINT_MAX/sizeof(int64_t))
841
        return -1;
842

    
843
    sc->chunk_count = entries;
844
    sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t));
845
    if (!sc->chunk_offsets)
846
        return -1;
847
    if (atom.type == MKTAG('s', 't', 'c', 'o')) {
848
        for(i=0; i<entries; i++) {
849
            sc->chunk_offsets[i] = get_be32(pb);
850
        }
851
    } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
852
        for(i=0; i<entries; i++) {
853
            sc->chunk_offsets[i] = get_be64(pb);
854
        }
855
    } else
856
        return -1;
857

    
858
    for(i=0; i<c->fc->nb_streams; i++){
859
        MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
860
        if(sc2 && sc2->chunk_offsets){
861
            int64_t first= sc2->chunk_offsets[0];
862
            int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
863
            if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
864
                c->ni=1;
865
        }
866
    }
867
    return 0;
868
}
869

    
870
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
871
{
872
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
873
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
874
    int entries, frames_per_sample;
875
    uint32_t format;
876
    uint8_t codec_name[32];
877

    
878
    /* for palette traversal */
879
    int color_depth;
880
    int color_start;
881
    int color_count;
882
    int color_end;
883
    int color_index;
884
    int color_dec;
885
    int color_greyscale;
886
    unsigned char *color_table;
887
    int j;
888
    unsigned char r, g, b;
889

    
890
    get_byte(pb); /* version */
891
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
892

    
893
    entries = get_be32(pb);
894

    
895
    while(entries--) { //Parsing Sample description table
896
        enum CodecID id;
897
        MOV_atom_t a = { 0, 0, 0 };
898
        offset_t start_pos = url_ftell(pb);
899
        int size = get_be32(pb); /* size */
900
        format = get_le32(pb); /* data format */
901

    
902
        get_be32(pb); /* reserved */
903
        get_be16(pb); /* reserved */
904
        get_be16(pb); /* index */
905

    
906
        dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
907
                size,
908
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
909
                st->codec->codec_type);
910
        st->codec->codec_tag = format;
911
        /* codec_type is set earlier by read_hdlr */
912
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
913
            /* for MPEG4: set codec type by looking for it */
914
            id = codec_get_id(mov_video_tags, format);
915
            if(id <= 0)
916
                id = codec_get_id(codec_bmp_tags, format);
917
            st->codec->codec_id = id;
918
            get_be16(pb); /* version */
919
            get_be16(pb); /* revision level */
920
            get_be32(pb); /* vendor */
921
            get_be32(pb); /* temporal quality */
922
            get_be32(pb); /* spacial quality */
923
            if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
924
                get_be16(pb);
925
                get_be16(pb);
926
            }else{
927
                st->codec->width = get_be16(pb); /* width */
928
                st->codec->height = get_be16(pb); /* height */
929
            }
930
            get_be32(pb); /* horiz resolution */
931
            get_be32(pb); /* vert resolution */
932
            get_be32(pb); /* data size, always 0 */
933
            frames_per_sample = get_be16(pb); /* frames per samples */
934
#ifdef DEBUG
935
            av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
936
#endif
937
        get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
938
        if (codec_name[0] <= 31) {
939
            memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
940
            st->codec->codec_name[codec_name[0]] = 0;
941
        }
942

    
943
            st->codec->bits_per_sample = get_be16(pb); /* depth */
944
            st->codec->color_table_id = get_be16(pb); /* colortable id */
945

    
946
/*          These are set in mov_read_stts and might already be set!
947
            st->codec->time_base.den      = 25;
948
            st->codec->time_base.num = 1;
949
*/
950

    
951
            /* figure out the palette situation */
952
            color_depth = st->codec->bits_per_sample & 0x1F;
953
            color_greyscale = st->codec->bits_per_sample & 0x20;
954

    
955
            /* if the depth is 2, 4, or 8 bpp, file is palettized */
956
            if ((color_depth == 2) || (color_depth == 4) ||
957
                (color_depth == 8)) {
958

    
959
                if (color_greyscale) {
960

    
961
                    /* compute the greyscale palette */
962
                    color_count = 1 << color_depth;
963
                    color_index = 255;
964
                    color_dec = 256 / (color_count - 1);
965
                    for (j = 0; j < color_count; j++) {
966
                        r = g = b = color_index;
967
                        c->palette_control.palette[j] =
968
                            (r << 16) | (g << 8) | (b);
969
                        color_index -= color_dec;
970
                        if (color_index < 0)
971
                            color_index = 0;
972
                    }
973

    
974
                } else if (st->codec->color_table_id & 0x08) {
975

    
976
                    /* if flag bit 3 is set, use the default palette */
977
                    color_count = 1 << color_depth;
978
                    if (color_depth == 2)
979
                        color_table = ff_qt_default_palette_4;
980
                    else if (color_depth == 4)
981
                        color_table = ff_qt_default_palette_16;
982
                    else
983
                        color_table = ff_qt_default_palette_256;
984

    
985
                    for (j = 0; j < color_count; j++) {
986
                        r = color_table[j * 4 + 0];
987
                        g = color_table[j * 4 + 1];
988
                        b = color_table[j * 4 + 2];
989
                        c->palette_control.palette[j] =
990
                            (r << 16) | (g << 8) | (b);
991
                    }
992

    
993
                } else {
994

    
995
                    /* load the palette from the file */
996
                    color_start = get_be32(pb);
997
                    color_count = get_be16(pb);
998
                    color_end = get_be16(pb);
999
                    for (j = color_start; j <= color_end; j++) {
1000
                        /* each R, G, or B component is 16 bits;
1001
                         * only use the top 8 bits; skip alpha bytes
1002
                         * up front */
1003
                        get_byte(pb);
1004
                        get_byte(pb);
1005
                        r = get_byte(pb);
1006
                        get_byte(pb);
1007
                        g = get_byte(pb);
1008
                        get_byte(pb);
1009
                        b = get_byte(pb);
1010
                        get_byte(pb);
1011
                        c->palette_control.palette[j] =
1012
                            (r << 16) | (g << 8) | (b);
1013
                    }
1014
                }
1015

    
1016
                st->codec->palctrl = &c->palette_control;
1017
                st->codec->palctrl->palette_changed = 1;
1018
            } else
1019
                st->codec->palctrl = NULL;
1020
        } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
1021
            uint16_t version = get_be16(pb);
1022

    
1023
            st->codec->codec_id = codec_get_id(mov_audio_tags, format);
1024
            get_be16(pb); /* revision level */
1025
            get_be32(pb); /* vendor */
1026

    
1027
            st->codec->channels = get_be16(pb);             /* channel count */
1028
            st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1029
            /* do we need to force to 16 for AMR ? */
1030

    
1031
            /* handle specific s8 codec */
1032
            get_be16(pb); /* compression id = 0*/
1033
            get_be16(pb); /* packet size = 0 */
1034

    
1035
            st->codec->sample_rate = ((get_be32(pb) >> 16));
1036

    
1037
            switch (st->codec->codec_id) {
1038
            case CODEC_ID_PCM_S16BE:
1039
                if (st->codec->bits_per_sample == 8)
1040
                    st->codec->codec_id = CODEC_ID_PCM_S8;
1041
                /* fall */
1042
            case CODEC_ID_PCM_U8:
1043
                if (st->codec->bits_per_sample == 16)
1044
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
1045
                st->codec->bit_rate = st->codec->sample_rate * 8;
1046
                break;
1047
            case CODEC_ID_AMR_WB:
1048
                st->codec->sample_rate = 16000; /* should really we ? */
1049
                st->codec->channels=1; /* really needed */
1050
                break;
1051
            case CODEC_ID_AMR_NB:
1052
                st->codec->sample_rate = 8000; /* should really we ? */
1053
                st->codec->channels=1; /* really needed */
1054
                break;
1055
            default:
1056
                break;
1057
            }
1058

    
1059
            //Read QT version 1 fields. In version 0 theese dont exist
1060
            dprintf("version =%d mp4=%d\n",version,c->mp4);
1061
            if(version==1) {
1062
                get_be32(pb); /* samples per packet */
1063
                get_be32(pb); /* bytes per packet */
1064
                get_be32(pb); /* bytes per frame */
1065
                get_be32(pb); /* bytes per sample */
1066
            } else if(version==2) {
1067
                get_be32(pb); /* sizeof struct only */
1068
                st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */
1069
                st->codec->channels = get_be32(pb);
1070
                get_be32(pb); /* always 0x7F000000 */
1071
                get_be32(pb); /* bits per channel if sound is uncompressed */
1072
                get_be32(pb); /* lcpm format specific flag */
1073
                get_be32(pb); /* bytes per audio packet if constant */
1074
                get_be32(pb); /* lpcm frames per audio packet if constant */
1075
            }
1076
        } else {
1077
            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
1078
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
1079
        }
1080
        /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
1081
        a.size = size - (url_ftell(pb) - start_pos);
1082
        if (a.size > 8)
1083
            mov_read_default(c, pb, a);
1084
        else if (a.size > 0)
1085
            url_fskip(pb, a.size);
1086
    }
1087

    
1088
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1089
        st->codec->sample_rate= sc->time_scale;
1090
    }
1091

    
1092
    return 0;
1093
}
1094

    
1095
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1096
{
1097
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1098
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1099
    unsigned int i, entries;
1100

    
1101
    get_byte(pb); /* version */
1102
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1103

    
1104
    entries = get_be32(pb);
1105

    
1106
    if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1107
        return -1;
1108

    
1109
#ifdef DEBUG
1110
av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1111
#endif
1112
    sc->sample_to_chunk_sz = entries;
1113
    sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1114
    if (!sc->sample_to_chunk)
1115
        return -1;
1116
    for(i=0; i<entries; i++) {
1117
        sc->sample_to_chunk[i].first = get_be32(pb);
1118
        sc->sample_to_chunk[i].count = get_be32(pb);
1119
        sc->sample_to_chunk[i].id = get_be32(pb);
1120
    }
1121
    return 0;
1122
}
1123

    
1124
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1125
{
1126
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1127
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1128
    unsigned int i, entries;
1129

    
1130
    get_byte(pb); /* version */
1131
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1132

    
1133
    entries = get_be32(pb);
1134

    
1135
    if(entries >= UINT_MAX / sizeof(long))
1136
        return -1;
1137

    
1138
    sc->keyframe_count = entries;
1139
#ifdef DEBUG
1140
    av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1141
#endif
1142
    sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1143
    if (!sc->keyframes)
1144
        return -1;
1145
    for(i=0; i<entries; i++) {
1146
        sc->keyframes[i] = get_be32(pb);
1147
#ifdef DEBUG
1148
/*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1149
#endif
1150
    }
1151
    return 0;
1152
}
1153

    
1154
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1155
{
1156
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1157
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1158
    unsigned int i, entries;
1159

    
1160
    get_byte(pb); /* version */
1161
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1162

    
1163
    sc->sample_size = get_be32(pb);
1164
    entries = get_be32(pb);
1165
    if(entries >= UINT_MAX / sizeof(long))
1166
        return -1;
1167

    
1168
    sc->sample_count = entries;
1169
#ifdef DEBUG
1170
    av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1171
#endif
1172
    if(sc->sample_size)
1173
        return 0; /* there isn't any table following */
1174
    sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1175
    if (!sc->sample_sizes)
1176
        return -1;
1177
    for(i=0; i<entries; i++) {
1178
        sc->sample_sizes[i] = get_be32(pb);
1179
#ifdef DEBUG
1180
        av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1181
#endif
1182
    }
1183
    return 0;
1184
}
1185

    
1186
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1187
{
1188
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1189
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1190
    unsigned int i, entries;
1191
    int64_t duration=0;
1192
    int64_t total_sample_count=0;
1193

    
1194
    get_byte(pb); /* version */
1195
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1196
    entries = get_be32(pb);
1197
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1198
        return -1;
1199

    
1200
    sc->stts_count = entries;
1201
    sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1202

    
1203
#ifdef DEBUG
1204
av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1205
#endif
1206

    
1207
    sc->time_rate=0;
1208

    
1209
    for(i=0; i<entries; i++) {
1210
        int sample_duration;
1211
        int sample_count;
1212

    
1213
        sample_count=get_be32(pb);
1214
        sample_duration = get_be32(pb);
1215
        sc->stts_data[i].count= sample_count;
1216
        sc->stts_data[i].duration= sample_duration;
1217

    
1218
        sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1219

    
1220
        dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1221

    
1222
        duration+=sample_duration*sample_count;
1223
        total_sample_count+=sample_count;
1224
    }
1225

    
1226
    st->nb_frames= total_sample_count;
1227
    if(duration)
1228
        st->duration= duration;
1229
    return 0;
1230
}
1231

    
1232
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1233
{
1234
    unsigned int i, entries;
1235

    
1236
    get_byte(pb); /* version */
1237
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1238
    entries = get_be32(pb);
1239
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1240
        return -1;
1241

    
1242
    c->streams[c->fc->nb_streams-1]->ctts_count = entries;
1243
    c->streams[c->fc->nb_streams-1]->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1244

    
1245
    dprintf("track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
1246

    
1247
    for(i=0; i<entries; i++) {
1248
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].count= get_be32(pb);
1249
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].duration= get_be32(pb);
1250
    }
1251
    return 0;
1252
}
1253

    
1254
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1255
{
1256
    AVStream *st;
1257
    MOVStreamContext *sc;
1258

    
1259
    st = av_new_stream(c->fc, c->fc->nb_streams);
1260
    if (!st) return -2;
1261
    sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1262
    if (!sc) {
1263
        av_free(st);
1264
        return -1;
1265
    }
1266

    
1267
    sc->sample_to_chunk_index = -1;
1268
    st->priv_data = sc;
1269
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1270
    st->start_time = 0; /* XXX: check */
1271
    c->streams[c->fc->nb_streams-1] = sc;
1272

    
1273
    return mov_read_default(c, pb, atom);
1274
}
1275

    
1276
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1277
{
1278
    AVStream *st;
1279

    
1280
    st = c->fc->streams[c->fc->nb_streams-1];
1281

    
1282
    get_byte(pb); /* version */
1283

    
1284
    get_byte(pb); get_byte(pb);
1285
    get_byte(pb); /* flags */
1286
    /*
1287
    MOV_TRACK_ENABLED 0x0001
1288
    MOV_TRACK_IN_MOVIE 0x0002
1289
    MOV_TRACK_IN_PREVIEW 0x0004
1290
    MOV_TRACK_IN_POSTER 0x0008
1291
    */
1292

    
1293
    get_be32(pb); /* creation time */
1294
    get_be32(pb); /* modification time */
1295
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1296
    get_be32(pb); /* reserved */
1297
    st->start_time = 0; /* check */
1298
    get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1299
    get_be32(pb); /* reserved */
1300
    get_be32(pb); /* reserved */
1301

    
1302
    get_be16(pb); /* layer */
1303
    get_be16(pb); /* alternate group */
1304
    get_be16(pb); /* volume */
1305
    get_be16(pb); /* reserved */
1306

    
1307
    url_fskip(pb, 36); /* display matrix */
1308

    
1309
    /* those are fixed-point */
1310
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1311
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1312

    
1313
    return 0;
1314
}
1315

    
1316
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1317
/* like the files created with Adobe Premiere 5.0, for samples see */
1318
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1319
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1320
{
1321
    int err;
1322

    
1323
    if (atom.size < 8)
1324
        return 0; /* continue */
1325
    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1326
        url_fskip(pb, atom.size - 4);
1327
        return 0;
1328
    }
1329
    atom.type = get_le32(pb);
1330
    atom.offset += 8;
1331
    atom.size -= 8;
1332
    if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1333
        url_fskip(pb, atom.size);
1334
        return 0;
1335
    }
1336
    err = mov_read_mdat(c, pb, atom);
1337
    return err;
1338
}
1339

    
1340

    
1341
#ifdef CONFIG_ZLIB
1342
static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1343
{
1344
    return -1;
1345
}
1346

    
1347
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1348
{
1349
    ByteIOContext ctx;
1350
    uint8_t *cmov_data;
1351
    uint8_t *moov_data; /* uncompressed data */
1352
    long cmov_len, moov_len;
1353
    int ret;
1354

    
1355
    get_be32(pb); /* dcom atom */
1356
    if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1357
        return -1;
1358
    if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1359
        av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
1360
        return -1;
1361
    }
1362
    get_be32(pb); /* cmvd atom */
1363
    if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1364
        return -1;
1365
    moov_len = get_be32(pb); /* uncompressed size */
1366
    cmov_len = atom.size - 6 * 4;
1367

    
1368
    cmov_data = (uint8_t *) av_malloc(cmov_len);
1369
    if (!cmov_data)
1370
        return -1;
1371
    moov_data = (uint8_t *) av_malloc(moov_len);
1372
    if (!moov_data) {
1373
        av_free(cmov_data);
1374
        return -1;
1375
    }
1376
    get_buffer(pb, cmov_data, cmov_len);
1377
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1378
        return -1;
1379
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1380
        return -1;
1381
    ctx.buf_end = ctx.buffer + moov_len;
1382
    atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1383
    atom.offset = 0;
1384
    atom.size = moov_len;
1385
#ifdef DEBUG
1386
//    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1387
#endif
1388
    ret = mov_read_default(c, &ctx, atom);
1389
    av_free(moov_data);
1390
    av_free(cmov_data);
1391

    
1392
    return ret;
1393
}
1394
#endif
1395

    
1396
/* edit list atom */
1397
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1398
{
1399
  int i, edit_count;
1400

    
1401
  get_byte(pb); /* version */
1402
  get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1403
  edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1404

    
1405
  for(i=0; i<edit_count; i++){
1406
    get_be32(pb); /* Track duration */
1407
    get_be32(pb); /* Media time */
1408
    get_be32(pb); /* Media rate */
1409
  }
1410
  dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1411
  return 0;
1412
}
1413

    
1414
static const MOVParseTableEntry mov_default_parse_table[] = {
1415
/* mp4 atoms */
1416
{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1417
{ MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1418
{ MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1419
{ MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1420
{ MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1421
{ MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1422
{ MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1423
{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1424
{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1425
{ MKTAG( 'e', 'n', 'd', 'a' ), mov_read_enda },
1426
{ MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1427
{ MKTAG( 'f', 't', 'y', 'p' ), mov_read_ftyp },
1428
{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1429
{ MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1430
{ MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1431
{ MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
1432
{ MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1433
{ MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1434
{ MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1435
{ MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1436
{ MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
1437
{ MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },
1438
{ MKTAG( 'm', 'p', '4', 's' ), mov_read_default },
1439
{ MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },
1440
{ MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },
1441
{ MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
1442
{ MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },
1443
{ MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },
1444
{ MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },
1445
{ MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },
1446
{ MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */
1447
{ MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
1448
{ MKTAG( 'a', 'l', 'a', 'c' ), mov_read_alac }, /* alac specific atom */
1449
{ MKTAG( 'a', 'v', 'c', 'C' ), mov_read_avcC },
1450
{ MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1451
{ MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1452
{ MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1453
{ MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1454
{ MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1455
{ MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1456
{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1457
{ MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1458
{ MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1459
{ MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1460
{ MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1461
{ MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1462
{ MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1463
{ MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1464
{ MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1465
{ MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1466
{ MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1467
{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1468
/* extra mp4 */
1469
{ MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1470
/* QT atoms */
1471
{ MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1472
{ MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1473
{ MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1474
{ MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1475
{ MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1476
{ MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1477
{ MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1478
{ MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1479
{ MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1480
{ MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1481
{ MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1482
{ MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1483
{ MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1484
{ MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1485
{ MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1486
{ MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1487
//{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1488
#ifdef CONFIG_ZLIB
1489
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1490
#else
1491
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1492
#endif
1493
{ 0L, mov_read_leaf }
1494
};
1495

    
1496
static void mov_free_stream_context(MOVStreamContext *sc)
1497
{
1498
    if(sc) {
1499
        av_freep(&sc->chunk_offsets);
1500
        av_freep(&sc->sample_to_chunk);
1501
        av_freep(&sc->sample_sizes);
1502
        av_freep(&sc->keyframes);
1503
        av_freep(&sc->stts_data);
1504
        av_freep(&sc->ctts_data);
1505
        av_freep(&sc);
1506
    }
1507
}
1508

    
1509
static inline uint32_t mov_to_tag(uint8_t *buf)
1510
{
1511
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1512
}
1513

    
1514
static inline uint32_t to_be32(uint8_t *buf)
1515
{
1516
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1517
}
1518

    
1519
/* XXX: is it sufficient ? */
1520
static int mov_probe(AVProbeData *p)
1521
{
1522
    unsigned int offset;
1523
    uint32_t tag;
1524
    int score = 0;
1525

    
1526
    /* check file header */
1527
    if (p->buf_size <= 12)
1528
        return 0;
1529
    offset = 0;
1530
    for(;;) {
1531
        /* ignore invalid offset */
1532
        if ((offset + 8) > (unsigned int)p->buf_size)
1533
            return score;
1534
        tag = mov_to_tag(p->buf + offset + 4);
1535
        switch(tag) {
1536
        /* check for obvious tags */
1537
        case MKTAG( 'm', 'o', 'o', 'v' ):
1538
        case MKTAG( 'm', 'd', 'a', 't' ):
1539
        case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1540
        case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1541
            return AVPROBE_SCORE_MAX;
1542
        /* those are more common words, so rate then a bit less */
1543
        case MKTAG( 'w', 'i', 'd', 'e' ):
1544
        case MKTAG( 'f', 'r', 'e', 'e' ):
1545
        case MKTAG( 'j', 'u', 'n', 'k' ):
1546
        case MKTAG( 'p', 'i', 'c', 't' ):
1547
            return AVPROBE_SCORE_MAX - 5;
1548
        case MKTAG( 'f', 't', 'y', 'p' ):
1549
        case MKTAG( 's', 'k', 'i', 'p' ):
1550
        case MKTAG( 'u', 'u', 'i', 'd' ):
1551
            offset = to_be32(p->buf+offset) + offset;
1552
            /* if we only find those cause probedata is too small at least rate them */
1553
            score = AVPROBE_SCORE_MAX - 50;
1554
            break;
1555
        default:
1556
            /* unrecognized tag */
1557
            return score;
1558
        }
1559
    }
1560
    return score;
1561
}
1562

    
1563
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1564
{
1565
    MOVContext *mov = (MOVContext *) s->priv_data;
1566
    ByteIOContext *pb = &s->pb;
1567
    int i, j, nb, err;
1568
    MOV_atom_t atom = { 0, 0, 0 };
1569

    
1570
    mov->fc = s;
1571
    mov->parse_table = mov_default_parse_table;
1572

    
1573
    if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1574
        atom.size = url_fsize(pb);
1575
    else
1576
        atom.size = 0x7FFFFFFFFFFFFFFFLL;
1577

    
1578
    /* check MOV header */
1579
    err = mov_read_default(mov, pb, atom);
1580
    if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1581
        av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1582
                err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1583
        return -1;
1584
    }
1585
    dprintf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1586

    
1587
    /* some cleanup : make sure we are on the mdat atom */
1588
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1589
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1590

    
1591
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1592
    mov->total_streams = nb = s->nb_streams;
1593

    
1594
#if 1
1595
    for(i=0; i<s->nb_streams;) {
1596
        if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1597
            av_free(s->streams[i]);
1598
            for(j=i+1; j<s->nb_streams; j++)
1599
                s->streams[j-1] = s->streams[j];
1600
            s->nb_streams--;
1601
        } else
1602
            i++;
1603
    }
1604
    for(i=0; i<s->nb_streams;i++) {
1605
        MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
1606

    
1607
        if(!sc->time_rate)
1608
            sc->time_rate=1;
1609
        av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1610

    
1611
        if(s->streams[i]->duration != AV_NOPTS_VALUE){
1612
            assert(s->streams[i]->duration % sc->time_rate == 0);
1613
            s->streams[i]->duration /= sc->time_rate;
1614
        }
1615

    
1616
        sc->ffindex = i;
1617
        sc->is_ff_stream = 1;
1618
    }
1619
#endif
1620
    return 0;
1621
}
1622

    
1623
/* Yes, this is ugly... I didn't write the specs of QT :p */
1624
/* XXX:remove useless commented code sometime */
1625
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1626
{
1627
    MOVContext *mov = (MOVContext *) s->priv_data;
1628
    MOVStreamContext *sc;
1629
    AVStream *st;
1630
    int64_t offset = INT64_MAX;
1631
    int64_t best_dts = INT64_MAX;
1632
    int i, a, b, m;
1633
    int size;
1634
    int idx;
1635
    size = 0x0FFFFFFF;
1636

    
1637
    if (mov->partial) {
1638
        sc = mov->partial;
1639
        idx = sc->sample_to_chunk_index;
1640

    
1641
        if (idx < 0) return 0;
1642
        dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1643
        //size = sc->sample_sizes[sc->current_sample];
1644
        // that ain't working...
1645
        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1646
        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1647

    
1648
        sc->current_sample++;
1649
        sc->left_in_chunk--;
1650

    
1651
        if (sc->left_in_chunk <= 0)
1652
            mov->partial = 0;
1653
        offset = mov->next_chunk_offset;
1654
        /* extract the sample */
1655

    
1656
        goto readchunk;
1657
    }
1658

    
1659
again:
1660
    sc = 0;
1661
    if(offset == INT64_MAX)
1662
        best_dts= INT64_MAX;
1663
    for(i=0; i<mov->total_streams; i++) {
1664
        MOVStreamContext *msc = mov->streams[i];
1665

    
1666
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1667
            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1668
                int64_t dts;
1669
                int index= msc->sample_to_time_index;
1670
                int sample= msc->sample_to_time_sample;
1671
                int time= msc->sample_to_time_time;
1672
                int duration = msc->stts_data[index].duration;
1673
                int count = msc->stts_data[index].count;
1674
                if (sample + count < msc->current_sample) {
1675
                    sample += count;
1676
                    time   += count*duration;
1677
                    index ++;
1678
                    duration = msc->stts_data[index].duration;
1679
                }
1680
                dts = time + (msc->current_sample-1 - sample) * (int64_t)duration;
1681
                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1682
                dprintf("stream: %d dts: %Ld best_dts: %Ld offset: %Ld \n", i, dts, best_dts, offset);
1683
                if(dts < best_dts){
1684
                    best_dts= dts;
1685
                    sc = msc;
1686
                    offset = msc->chunk_offsets[msc->next_chunk];
1687
                }
1688
            }else{
1689
                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1690
                    sc = msc;
1691
                    offset = msc->chunk_offsets[msc->next_chunk];
1692
                }
1693
            }
1694
        }
1695
    }
1696
    if (!sc || offset==INT64_MAX)
1697
        return -1;
1698

    
1699
    sc->next_chunk++;
1700

    
1701
    if(mov->next_chunk_offset < offset) { /* some meta data */
1702
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1703
        mov->next_chunk_offset = offset;
1704
    }
1705

    
1706
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1707
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1708
        mov->next_chunk_offset = offset;
1709
        offset = INT64_MAX;
1710
        goto again;
1711
    }
1712

    
1713
    /* now get the chunk size... */
1714

    
1715
    for(i=0; i<mov->total_streams; i++) {
1716
        MOVStreamContext *msc = mov->streams[i];
1717
        if ((msc->next_chunk < msc->chunk_count)
1718
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1719
            && msc->chunk_offsets[msc->next_chunk] > offset)
1720
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1721
    }
1722

    
1723
#ifdef MOV_MINOLTA_FIX
1724
    //Make sure that size is according to sample_size (Needed by .mov files
1725
    //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1726
    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1727
    //but I have no such movies
1728
    if (sc->sample_size > 0) {
1729
        int foundsize=0;
1730
        for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1731
            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1732
            {
1733
                // I can't figure out why for PCM audio sample_size is always 1
1734
                // (it should actually be channels*bits_per_second/8) but it is.
1735
                AVCodecContext* cod = s->streams[sc->ffindex]->codec;
1736
                if (sc->sample_size == 1 && (cod->codec_id == CODEC_ID_PCM_S16BE || cod->codec_id == CODEC_ID_PCM_S16LE))
1737
                    foundsize=(sc->sample_to_chunk[i].count*cod->channels*cod->bits_per_sample)/8;
1738
                else
1739
                    foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
1740
            }
1741
            dprintf("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);
1742
        }
1743
        if( (foundsize>0) && (foundsize<size) )
1744
        {
1745
            size=foundsize;
1746
        }
1747
    }
1748
#endif //MOV_MINOLTA_FIX
1749

    
1750
    idx = sc->sample_to_chunk_index;
1751
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1752
        idx++;
1753
    sc->sample_to_chunk_index = idx;
1754
    /* split chunks into samples */
1755
    if (sc->sample_size == 0 || sc->sample_size > 100) {
1756
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1757
            mov->partial = sc;
1758
            /* we'll have to get those samples before next chunk */
1759
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1760
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1761
        }
1762

    
1763
        sc->current_sample++;
1764
    }else if(idx + 1 < sc->sample_to_chunk_sz){
1765
        sc->current_sample += sc->sample_to_chunk[idx].count;
1766
    }
1767

    
1768
readchunk:
1769
    dprintf("chunk: %lli -> %lli (%i)\n", offset, offset + size, size);
1770
    if(size == 0x0FFFFFFF)
1771
        size = mov->mdat_size + mov->mdat_offset - offset;
1772
    if(size < 0)
1773
        return -1;
1774
    if(size == 0)
1775
        return -1;
1776
    url_fseek(&s->pb, offset, SEEK_SET);
1777

    
1778
    av_get_packet(&s->pb, pkt, size);
1779
    pkt->stream_index = sc->ffindex;
1780

    
1781
    // If the keyframes table exists, mark any samples that are in the table as key frames.
1782
    // If no table exists, treat very sample as a key frame.
1783
    if (sc->keyframes) {
1784
        a = 0;
1785
        b = sc->keyframe_count - 1;
1786

    
1787
        while (a < b) {
1788
            m = (a + b + 1) >> 1;
1789
            if (sc->keyframes[m] > sc->current_sample) {
1790
                b = m - 1;
1791
            } else {
1792
                a = m;
1793
            }
1794
        }
1795

    
1796
        if (sc->keyframes[a] == sc->current_sample)
1797
            pkt->flags |= PKT_FLAG_KEY;
1798
    }
1799
    else
1800
        pkt->flags |= PKT_FLAG_KEY;
1801

    
1802
    mov->next_chunk_offset = offset + size;
1803

    
1804
    /* find the corresponding dts */
1805
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1806
      unsigned int count;
1807
      uint64_t dts, pts;
1808
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1809
      count = sc->stts_data[sc->sample_to_time_index].count;
1810
      if ((sc->sample_to_time_sample + count) < sc->current_sample) {
1811
        sc->sample_to_time_sample += count;
1812
        sc->sample_to_time_time   += count*duration;
1813
        sc->sample_to_time_index ++;
1814
        duration = sc->stts_data[sc->sample_to_time_index].duration;
1815
      }
1816
      dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * (int64_t)duration;
1817
        /* find the corresponding pts */
1818
        if (sc->sample_to_ctime_index < sc->ctts_count) {
1819
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1820
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1821

    
1822
            if ((sc->sample_to_ctime_sample + count) < sc->current_sample) {
1823
                sc->sample_to_ctime_sample += count;
1824
                sc->sample_to_ctime_index ++;
1825
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1826
            }
1827
            pts = dts + duration;
1828
        }else
1829
            pts = dts;
1830

    
1831
        st= s->streams[ sc->ffindex ];
1832
        assert(pts % st->time_base.num == 0);
1833
        assert(dts % st->time_base.num == 0);
1834

    
1835
        pkt->pts = pts / st->time_base.num;
1836
        pkt->dts = dts / st->time_base.num;
1837
        dprintf("stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n"
1838
                , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1839
                , sc->sample_to_time_sample
1840
                , sc->sample_to_time_time
1841
                , sc->sample_to_time_index
1842
                , sc->stts_count
1843
                , count
1844
                , duration);
1845
    }
1846

    
1847
    return 0;
1848
}
1849

    
1850
#if defined(MOV_SEEK)
1851
/**
1852
 * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1853
 */
1854
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1855
{
1856
    MOVContext* mov = (MOVContext *) s->priv_data;
1857
    MOVStreamContext* sc;
1858
    int32_t i, a, b, m;
1859
    int64_t start_time;
1860
    int32_t seek_sample, sample;
1861
    int32_t duration;
1862
    int32_t count;
1863
    int32_t chunk;
1864
    int32_t left_in_chunk;
1865
    int64_t chunk_file_offset;
1866
    int64_t sample_file_offset;
1867
    int32_t first_chunk_sample;
1868
    int32_t sample_to_chunk_idx;
1869
    int sample_to_time_index;
1870
    long sample_to_time_sample = 0;
1871
    uint64_t sample_to_time_time = 0;
1872
    int mov_idx;
1873

    
1874
    // Find the corresponding mov stream
1875
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1876
        if (mov->streams[mov_idx]->ffindex == stream_index)
1877
            break;
1878
    if (mov_idx == mov->total_streams) {
1879
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1880
        return -1;
1881
    }
1882
    sc = mov->streams[mov_idx];
1883

    
1884
    sample_time *= s->streams[stream_index]->time_base.num;
1885

    
1886
    // Step 1. Find the edit that contains the requested time (elst)
1887
    if (sc->edit_count && 0) {
1888
        // FIXME should handle edit list
1889
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
1890
        return -1;
1891
    }
1892

    
1893
    // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */
1894
    dprintf("Searching for time %li in stream #%i (time_scale=%i)\n", (long)sample_time, mov_idx, sc->time_scale);
1895
    start_time = 0; // FIXME use elst atom
1896
    sample = 1; // sample are 0 based in table
1897

    
1898
    for (i = 0; i < sc->stts_count; i++) {
1899
        count = sc->stts_data[i].count;
1900
        duration = sc->stts_data[i].duration;
1901
        if ((start_time + count*duration) > sample_time) {
1902
            sample_to_time_time = start_time;
1903
            sample_to_time_index = i;
1904
            sample_to_time_sample = sample;
1905
            sample += (sample_time - start_time) / duration;
1906
            break;
1907
        }
1908
        sample += count;
1909
        start_time += count * duration;
1910
    }
1911
    sample_to_time_time = start_time;
1912
    sample_to_time_index = i;
1913
    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
1914
       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
1915

    
1916
    dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
1917
    if (sample > sc->sample_count) {
1918
        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);
1919
        return -1;
1920
    }
1921

    
1922
    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
1923
    if (sc->keyframes) {
1924
        a = 0;
1925
        b = sc->keyframe_count - 1;
1926
        while (a < b) {
1927
            m = (a + b + 1) >> 1;
1928
            if (sc->keyframes[m] > sample) {
1929
                b = m - 1;
1930
            } else {
1931
                a = m;
1932
            }
1933
        }
1934
        // for low latency prob: always use the previous keyframe, just uncomment the next line
1935
        // if (a) a--;
1936
        seek_sample = sc->keyframes[a];
1937
    }
1938
    else
1939
        seek_sample = sample; // else all samples are key frames
1940
    dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
1941

    
1942
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
1943
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
1944
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
1945
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
1946
            break;
1947
        first_chunk_sample += b;
1948
    }
1949
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
1950
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
1951
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
1952
    sample_to_chunk_idx = i;
1953
    dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
1954

    
1955
    // Step 5. Find the offset of the chunk using the chunk offset atom
1956
    if (!sc->chunk_offsets) {
1957
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
1958
        return -1;
1959
    }
1960
    if (chunk > sc->chunk_count) {
1961
        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);
1962
        return -1;
1963
    }
1964
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
1965
    dprintf("Chunk file offset is #%llu \n", chunk_file_offset);
1966

    
1967
    // Step 6. Find the byte offset within the chunk using the sample size atom
1968
    sample_file_offset = chunk_file_offset;
1969
    if (sc->sample_size)
1970
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
1971
    else {
1972
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
1973
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
1974
        }
1975
    }
1976
    dprintf("Sample file offset is #%llu \n", sample_file_offset);
1977

    
1978
    // Step 6. Update the parser
1979
    mov->partial = sc;
1980
    mov->next_chunk_offset = sample_file_offset;
1981
    // Update current stream state
1982
    sc->current_sample = seek_sample - 1;  // zero based
1983
    sc->left_in_chunk = left_in_chunk;
1984
    sc->next_chunk = chunk; // +1 -1 (zero based)
1985
    sc->sample_to_chunk_index = sample_to_chunk_idx;
1986

    
1987
    // Update other streams
1988
    for (i = 0; i<mov->total_streams; i++) {
1989
        MOVStreamContext *msc;
1990
        if (i == mov_idx) continue;
1991
        // Find the nearest 'next' chunk
1992
        msc = mov->streams[i];
1993
        a = 0;
1994
        b = msc->chunk_count - 1;
1995
        while (a < b) {
1996
            m = (a + b + 1) >> 1;
1997
            if (msc->chunk_offsets[m] > chunk_file_offset) {
1998
                b = m - 1;
1999
            } else {
2000
                a = m;
2001
            }
2002
        }
2003
        msc->next_chunk = a;
2004
        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2005
            msc->next_chunk ++;
2006
        dprintf("Nearest next chunk for stream #%i is #%li @%lli\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2007

    
2008
        // Compute sample count and index in the sample_to_chunk table (what a pity)
2009
        msc->sample_to_chunk_index = 0;
2010
        msc->current_sample = 0;
2011
        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2012
            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2013
            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2014
            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2015
        }
2016
        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;
2017
        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2018
        // Find corresponding position in stts (used later to compute dts)
2019
        sample = 0;
2020
        start_time = 0;
2021
        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2022
            count = msc->stts_data[msc->sample_to_time_index].count;
2023
            duration = msc->stts_data[msc->sample_to_time_index].duration;
2024
            if ((sample + count - 1) > msc->current_sample) {
2025
                msc->sample_to_time_time = start_time;
2026
                msc->sample_to_time_sample = sample;
2027
                break;
2028
            }
2029
            sample += count;
2030
            start_time += count * duration;
2031
        }
2032
        sample = 0;
2033
        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2034
            count = msc->ctts_data[msc->sample_to_ctime_index].count;
2035
            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2036
            if ((sample + count - 1) > msc->current_sample) {
2037
                msc->sample_to_ctime_sample = sample;
2038
                break;
2039
            }
2040
            sample += count;
2041
        }
2042
        dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2043
    }
2044
    return 0;
2045
}
2046
#endif
2047

    
2048
static int mov_read_close(AVFormatContext *s)
2049
{
2050
    int i;
2051
    MOVContext *mov = (MOVContext *) s->priv_data;
2052
    for(i=0; i<mov->total_streams; i++)
2053
        mov_free_stream_context(mov->streams[i]);
2054
    /* free color tabs */
2055
    for(i=0; i<mov->ctab_size; i++)
2056
        av_freep(&mov->ctab[i]);
2057
    av_freep(&mov->ctab);
2058
    return 0;
2059
}
2060

    
2061
static AVInputFormat mov_iformat = {
2062
    "mov,mp4,m4a,3gp,3g2",
2063
    "QuickTime/MPEG4 format",
2064
    sizeof(MOVContext),
2065
    mov_probe,
2066
    mov_read_header,
2067
    mov_read_packet,
2068
    mov_read_close,
2069
#if defined(MOV_SEEK)
2070
    mov_read_seek,
2071
#endif
2072
};
2073

    
2074
int mov_init(void)
2075
{
2076
    av_register_input_format(&mov_iformat);
2077
    return 0;
2078
}