Statistics
| Branch: | Revision:

ffmpeg / libavformat / mov.c @ 576f1445

History | View | Annotate | Download (75 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('h', 'd', 'v', '3') }, /* HDV produced by FCP */
148
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG2 IMX NTSC 525/60 50mb/s produced by FCP */
149
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX PAL 625/50 50mb/s produced by FCP */
150
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'n') }, /* MPEG2 IMX NTSC 525/60 30mb/s produced by FCP */
151
    { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '3', 'p') }, /* MPEG2 IMX PAL 625/50 30mb/s produced by FCP */
152
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'p', 'p') }, /* DVCPRO PAL produced by FCP */
153
    //{ CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '5') }, /* DVCPRO HD 50i produced by FCP */
154
    //{ CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') }, /* DVCPRO HD 60i produced by FCP */
155
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 PAL produced by FCP */
156
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') }, /* DVCPRO50 NTSC produced by FCP */
157
    //{ CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */
158
    { CODEC_ID_NONE, 0 },
159
};
160

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

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

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

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

    
221
typedef struct MOV_sample_to_chunk_tbl {
222
    long first;
223
    long count;
224
    long id;
225
} MOV_sample_to_chunk_tbl;
226

    
227
typedef struct {
228
    uint32_t type;
229
    int64_t offset;
230
    int64_t size; /* total size (excluding the size and type fields) */
231
} MOV_atom_t;
232

    
233
typedef struct {
234
    int seed;
235
    int flags;
236
    int size;
237
    void* clrs;
238
} MOV_ctab_t;
239

    
240
typedef struct {
241
    uint8_t  version;
242
    uint32_t flags; // 24bit
243

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

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

    
279
    /* 0x05 DecSpecificDescrTag */
280
    uint8_t  decoder_cfg_len;
281
    uint8_t *decoder_cfg;
282

    
283
    /* 0x06 SLConfigDescrTag */
284
    uint8_t  sl_config_len;
285
    uint8_t *sl_config;
286
} MOV_esds_t;
287

    
288
struct MOVParseTableEntry;
289

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

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

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

    
344
    AVPaletteControl palette_control;
345
} MOVContext;
346

    
347

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

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

    
358
/* links atom IDs to parse functions */
359
typedef struct MOVParseTableEntry {
360
    uint32_t type;
361
    mov_parse_function func;
362
} MOVParseTableEntry;
363

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

    
385
extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */
386
int ff_mov_iso639_to_lang(const char *lang, int mp4)
387
{
388
    int i, code = 0;
389

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

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

    
422
static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
423
{
424
    int64_t total_size = 0;
425
    MOV_atom_t a;
426
    int i;
427
    int err = 0;
428

    
429
    a.offset = atom.offset;
430

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

    
457
        a.size -= 8;
458

    
459
        if(a.size < 0)
460
            break;
461

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

    
468
        a.offset += a.size;
469
        total_size += a.size;
470
    }
471

    
472
    if (!err && total_size < atom.size && atom.size < 0x7ffff) {
473
        url_fskip(pb, atom.size - total_size);
474
    }
475

    
476
    return err;
477
}
478

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

    
500
    return 0;
501
}
502

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

    
510
    get_byte(pb); /* version */
511
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
512

    
513
    /* component type */
514
    ctype = get_le32(pb);
515
    type = get_le32(pb); /* component subtype */
516

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

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

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

    
545
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
546
    return 0;
547
}
548

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

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

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

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

    
587
    len = mov_mp4_read_descr(pb, &tag);
588
    if (tag == MP4DecConfigDescrTag) {
589
        sc->esds.object_type_id = get_byte(pb);
590
        sc->esds.stream_type = get_byte(pb);
591
        sc->esds.buffer_size_db = get_be24(pb);
592
        sc->esds.max_bitrate = get_be32(pb);
593
        sc->esds.avg_bitrate = get_be32(pb);
594

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

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

    
625
static int mov_read_ftyp(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
626
{
627
    uint32_t type = get_le32(pb);
628

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

    
654
/* this atom should contain all header atoms */
655
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
656
{
657
    int err;
658

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

    
668

    
669
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
670
{
671
    int version;
672
    int lang;
673

    
674
    version = get_byte(pb); /* version */
675
    if (version > 1)
676
        return 1; /* unsupported */
677

    
678
    get_byte(pb); get_byte(pb);
679
    get_byte(pb); /* flags */
680

    
681
    (version==1)?get_be64(pb):get_be32(pb); /* creation time */
682
    (version==1)?get_be64(pb):get_be32(pb); /* modification time */
683

    
684
    c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb);
685
    c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
686

    
687
    lang = get_be16(pb); /* language */
688
    ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
689
    get_be16(pb); /* quality */
690

    
691
    return 0;
692
}
693

    
694
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
695
{
696
    get_byte(pb); /* version */
697
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
698

    
699
    get_be32(pb); /* creation time */
700
    get_be32(pb); /* modification time */
701
    c->time_scale = get_be32(pb); /* time scale */
702
#ifdef DEBUG
703
    av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);
704
#endif
705
    c->duration = get_be32(pb); /* duration */
706
    get_be32(pb); /* preferred scale */
707

    
708
    get_be16(pb); /* preferred volume */
709

    
710
    url_fskip(pb, 10); /* reserved */
711

    
712
    url_fskip(pb, 36); /* display matrix */
713

    
714
    get_be32(pb); /* preview time */
715
    get_be32(pb); /* preview duration */
716
    get_be32(pb); /* poster time */
717
    get_be32(pb); /* selection time */
718
    get_be32(pb); /* selection duration */
719
    get_be32(pb); /* current time */
720
    get_be32(pb); /* next track ID */
721

    
722
    return 0;
723
}
724

    
725
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
726
{
727
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
728

    
729
    if((uint64_t)atom.size > (1<<30))
730
        return -1;
731

    
732
    // currently SVQ3 decoder expect full STSD header - so let's fake it
733
    // this should be fixed and just SMI header should be passed
734
    av_free(st->codec->extradata);
735
    st->codec->extradata_size = 0x5a + atom.size;
736
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
737

    
738
    if (st->codec->extradata) {
739
        strcpy(st->codec->extradata, "SVQ3"); // fake
740
        get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
741
        dprintf("Reading SMI %"PRId64"  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
742
    } else
743
        url_fskip(pb, atom.size);
744

    
745
    return 0;
746
}
747

    
748
static int mov_read_enda(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
749
{
750
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
751
    int little_endian = get_be16(pb);
752

    
753
    if (little_endian) {
754
        switch (st->codec->codec_id) {
755
        case CODEC_ID_PCM_S24BE:
756
            st->codec->codec_id = CODEC_ID_PCM_S24LE;
757
            break;
758
        case CODEC_ID_PCM_S32BE:
759
            st->codec->codec_id = CODEC_ID_PCM_S32LE;
760
            break;
761
        default:
762
            break;
763
        }
764
    }
765
    return 0;
766
}
767

    
768
static int mov_read_alac(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
769
{
770
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
771

    
772
    // currently ALAC decoder expect full atom header - so let's fake it
773
    // this should be fixed and just ALAC header should be passed
774

    
775
    av_free(st->codec->extradata);
776
    st->codec->extradata_size = 36;
777
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
778

    
779
    if (st->codec->extradata) {
780
        strcpy(st->codec->extradata + 4, "alac"); // fake
781
        get_buffer(pb, st->codec->extradata + 8, 36 - 8);
782
        dprintf("Reading alac %d  %s\n", st->codec->extradata_size, (char*)st->codec->extradata);
783
    } else
784
        url_fskip(pb, atom.size);
785
    return 0;
786
}
787

    
788
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
789
{
790
    offset_t start_pos = url_ftell(pb);
791
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
792

    
793
    if((uint64_t)atom.size > (1<<30))
794
        return -1;
795

    
796
    if (st->codec->codec_id == CODEC_ID_QDM2) {
797
        // pass all frma atom to codec, needed at least for QDM2
798
        av_free(st->codec->extradata);
799
        st->codec->extradata_size = atom.size;
800
        st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
801

    
802
        if (st->codec->extradata) {
803
            get_buffer(pb, st->codec->extradata, atom.size);
804
        } else
805
            url_fskip(pb, atom.size);
806
    } else if (atom.size > 8) { /* to read frma, esds atoms */
807
        mov_read_default(c, pb, atom);
808
    } else if (atom.size > 0)
809
        url_fskip(pb, atom.size);
810
    /* in any case, skip garbage */
811
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
812
    return 0;
813
}
814

    
815
static int mov_read_jp2h(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
816
{
817
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
818

    
819
    if((uint64_t)atom.size > (1<<30))
820
        return -1;
821

    
822
    av_free(st->codec->extradata);
823

    
824
    st->codec->extradata_size = atom.size + 8;
825
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
826

    
827
    /* pass all jp2h atom to codec */
828
    if (st->codec->extradata) {
829
        strcpy(st->codec->extradata + 4, "jp2h");
830
        get_buffer(pb, st->codec->extradata + 8, atom.size);
831
    } else
832
        url_fskip(pb, atom.size);
833
    return 0;
834
}
835

    
836
static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
837
{
838
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
839

    
840
    if((uint64_t)atom.size > (1<<30))
841
        return -1;
842

    
843
    av_free(st->codec->extradata);
844

    
845
    st->codec->extradata_size = atom.size;
846
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
847

    
848
    if (st->codec->extradata) {
849
        get_buffer(pb, st->codec->extradata, atom.size);
850
    } else
851
        url_fskip(pb, atom.size);
852

    
853
    return 0;
854
}
855

    
856
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
857
{
858
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
859
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
860
    unsigned int i, entries;
861

    
862
    get_byte(pb); /* version */
863
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
864

    
865
    entries = get_be32(pb);
866

    
867
    if(entries >= UINT_MAX/sizeof(int64_t))
868
        return -1;
869

    
870
    sc->chunk_count = entries;
871
    sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t));
872
    if (!sc->chunk_offsets)
873
        return -1;
874
    if (atom.type == MKTAG('s', 't', 'c', 'o')) {
875
        for(i=0; i<entries; i++) {
876
            sc->chunk_offsets[i] = get_be32(pb);
877
        }
878
    } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
879
        for(i=0; i<entries; i++) {
880
            sc->chunk_offsets[i] = get_be64(pb);
881
        }
882
    } else
883
        return -1;
884

    
885
    for(i=0; i<c->fc->nb_streams; i++){
886
        MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
887
        if(sc2 && sc2->chunk_offsets){
888
            int64_t first= sc2->chunk_offsets[0];
889
            int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
890
            if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
891
                c->ni=1;
892
        }
893
    }
894
    return 0;
895
}
896

    
897
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
898
{
899
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
900
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
901
    int entries, frames_per_sample;
902
    uint32_t format;
903
    uint8_t codec_name[32];
904

    
905
    /* for palette traversal */
906
    int color_depth;
907
    int color_start;
908
    int color_count;
909
    int color_end;
910
    int color_index;
911
    int color_dec;
912
    int color_greyscale;
913
    unsigned char *color_table;
914
    int j;
915
    unsigned char r, g, b;
916

    
917
    get_byte(pb); /* version */
918
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
919

    
920
    entries = get_be32(pb);
921

    
922
    while(entries--) { //Parsing Sample description table
923
        enum CodecID id;
924
        MOV_atom_t a = { 0, 0, 0 };
925
        offset_t start_pos = url_ftell(pb);
926
        int size = get_be32(pb); /* size */
927
        format = get_le32(pb); /* data format */
928

    
929
        get_be32(pb); /* reserved */
930
        get_be16(pb); /* reserved */
931
        get_be16(pb); /* index */
932

    
933
        dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
934
                size,
935
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
936
                st->codec->codec_type);
937
        st->codec->codec_tag = format;
938
        /* codec_type is set earlier by read_hdlr */
939
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
940
            /* for MPEG4: set codec type by looking for it */
941
            id = codec_get_id(mov_video_tags, format);
942
            if(id <= 0)
943
                id = codec_get_id(codec_bmp_tags, format);
944
            st->codec->codec_id = id;
945
            get_be16(pb); /* version */
946
            get_be16(pb); /* revision level */
947
            get_be32(pb); /* vendor */
948
            get_be32(pb); /* temporal quality */
949
            get_be32(pb); /* spacial quality */
950
            if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
951
                get_be16(pb);
952
                get_be16(pb);
953
            }else{
954
                st->codec->width = get_be16(pb); /* width */
955
                st->codec->height = get_be16(pb); /* height */
956
            }
957
            get_be32(pb); /* horiz resolution */
958
            get_be32(pb); /* vert resolution */
959
            get_be32(pb); /* data size, always 0 */
960
            frames_per_sample = get_be16(pb); /* frames per samples */
961
#ifdef DEBUG
962
            av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
963
#endif
964
            get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
965
            if (codec_name[0] <= 31) {
966
                memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
967
                st->codec->codec_name[codec_name[0]] = 0;
968
            }
969

    
970
            st->codec->bits_per_sample = get_be16(pb); /* depth */
971
            st->codec->color_table_id = get_be16(pb); /* colortable id */
972

    
973
/*          These are set in mov_read_stts and might already be set!
974
            st->codec->time_base.den      = 25;
975
            st->codec->time_base.num = 1;
976
*/
977

    
978
            /* figure out the palette situation */
979
            color_depth = st->codec->bits_per_sample & 0x1F;
980
            color_greyscale = st->codec->bits_per_sample & 0x20;
981

    
982
            /* if the depth is 2, 4, or 8 bpp, file is palettized */
983
            if ((color_depth == 2) || (color_depth == 4) ||
984
                (color_depth == 8)) {
985

    
986
                if (color_greyscale) {
987

    
988
                    /* compute the greyscale palette */
989
                    color_count = 1 << color_depth;
990
                    color_index = 255;
991
                    color_dec = 256 / (color_count - 1);
992
                    for (j = 0; j < color_count; j++) {
993
                        r = g = b = color_index;
994
                        c->palette_control.palette[j] =
995
                            (r << 16) | (g << 8) | (b);
996
                        color_index -= color_dec;
997
                        if (color_index < 0)
998
                            color_index = 0;
999
                    }
1000

    
1001
                } else if (st->codec->color_table_id & 0x08) {
1002

    
1003
                    /* if flag bit 3 is set, use the default palette */
1004
                    color_count = 1 << color_depth;
1005
                    if (color_depth == 2)
1006
                        color_table = ff_qt_default_palette_4;
1007
                    else if (color_depth == 4)
1008
                        color_table = ff_qt_default_palette_16;
1009
                    else
1010
                        color_table = ff_qt_default_palette_256;
1011

    
1012
                    for (j = 0; j < color_count; j++) {
1013
                        r = color_table[j * 4 + 0];
1014
                        g = color_table[j * 4 + 1];
1015
                        b = color_table[j * 4 + 2];
1016
                        c->palette_control.palette[j] =
1017
                            (r << 16) | (g << 8) | (b);
1018
                    }
1019

    
1020
                } else {
1021

    
1022
                    /* load the palette from the file */
1023
                    color_start = get_be32(pb);
1024
                    color_count = get_be16(pb);
1025
                    color_end = get_be16(pb);
1026
                    for (j = color_start; j <= color_end; j++) {
1027
                        /* each R, G, or B component is 16 bits;
1028
                         * only use the top 8 bits; skip alpha bytes
1029
                         * up front */
1030
                        get_byte(pb);
1031
                        get_byte(pb);
1032
                        r = get_byte(pb);
1033
                        get_byte(pb);
1034
                        g = get_byte(pb);
1035
                        get_byte(pb);
1036
                        b = get_byte(pb);
1037
                        get_byte(pb);
1038
                        c->palette_control.palette[j] =
1039
                            (r << 16) | (g << 8) | (b);
1040
                    }
1041
                }
1042

    
1043
                st->codec->palctrl = &c->palette_control;
1044
                st->codec->palctrl->palette_changed = 1;
1045
            } else
1046
                st->codec->palctrl = NULL;
1047
        } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
1048
            uint16_t version = get_be16(pb);
1049

    
1050
            st->codec->codec_id = codec_get_id(mov_audio_tags, format);
1051
            get_be16(pb); /* revision level */
1052
            get_be32(pb); /* vendor */
1053

    
1054
            st->codec->channels = get_be16(pb);             /* channel count */
1055
            st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1056
            /* do we need to force to 16 for AMR ? */
1057

    
1058
            /* handle specific s8 codec */
1059
            get_be16(pb); /* compression id = 0*/
1060
            get_be16(pb); /* packet size = 0 */
1061

    
1062
            st->codec->sample_rate = ((get_be32(pb) >> 16));
1063

    
1064
            switch (st->codec->codec_id) {
1065
            case CODEC_ID_PCM_S16BE:
1066
                if (st->codec->bits_per_sample == 8)
1067
                    st->codec->codec_id = CODEC_ID_PCM_S8;
1068
                /* fall */
1069
            case CODEC_ID_PCM_U8:
1070
                if (st->codec->bits_per_sample == 16)
1071
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
1072
                st->codec->bit_rate = st->codec->sample_rate * 8;
1073
                break;
1074
            case CODEC_ID_AMR_WB:
1075
                st->codec->sample_rate = 16000; /* should really we ? */
1076
                st->codec->channels=1; /* really needed */
1077
                break;
1078
            case CODEC_ID_AMR_NB:
1079
                st->codec->sample_rate = 8000; /* should really we ? */
1080
                st->codec->channels=1; /* really needed */
1081
                break;
1082
            default:
1083
                break;
1084
            }
1085

    
1086
            //Read QT version 1 fields. In version 0 theese dont exist
1087
            dprintf("version =%d mp4=%d\n",version,c->mp4);
1088
            if(version==1) {
1089
                get_be32(pb); /* samples per packet */
1090
                get_be32(pb); /* bytes per packet */
1091
                get_be32(pb); /* bytes per frame */
1092
                get_be32(pb); /* bytes per sample */
1093
            } else if(version==2) {
1094
                get_be32(pb); /* sizeof struct only */
1095
                st->codec->sample_rate = av_int2dbl(get_be64(pb)); /* float 64 */
1096
                st->codec->channels = get_be32(pb);
1097
                get_be32(pb); /* always 0x7F000000 */
1098
                get_be32(pb); /* bits per channel if sound is uncompressed */
1099
                get_be32(pb); /* lcpm format specific flag */
1100
                get_be32(pb); /* bytes per audio packet if constant */
1101
                get_be32(pb); /* lpcm frames per audio packet if constant */
1102
            }
1103
        } else {
1104
            /* other codec type, just skip (rtp, mp4s, tmcd ...) */
1105
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
1106
        }
1107
        /* this will read extra atoms at the end (wave, alac, damr, avcC, SMI ...) */
1108
        a.size = size - (url_ftell(pb) - start_pos);
1109
        if (a.size > 8)
1110
            mov_read_default(c, pb, a);
1111
        else if (a.size > 0)
1112
            url_fskip(pb, a.size);
1113
    }
1114

    
1115
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1116
        st->codec->sample_rate= sc->time_scale;
1117
    }
1118

    
1119
    return 0;
1120
}
1121

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

    
1128
    get_byte(pb); /* version */
1129
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1130

    
1131
    entries = get_be32(pb);
1132

    
1133
    if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1134
        return -1;
1135

    
1136
#ifdef DEBUG
1137
av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1138
#endif
1139
    sc->sample_to_chunk_sz = entries;
1140
    sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1141
    if (!sc->sample_to_chunk)
1142
        return -1;
1143
    for(i=0; i<entries; i++) {
1144
        sc->sample_to_chunk[i].first = get_be32(pb);
1145
        sc->sample_to_chunk[i].count = get_be32(pb);
1146
        sc->sample_to_chunk[i].id = get_be32(pb);
1147
    }
1148
    return 0;
1149
}
1150

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

    
1157
    get_byte(pb); /* version */
1158
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1159

    
1160
    entries = get_be32(pb);
1161

    
1162
    if(entries >= UINT_MAX / sizeof(long))
1163
        return -1;
1164

    
1165
    sc->keyframe_count = entries;
1166
#ifdef DEBUG
1167
    av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1168
#endif
1169
    sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1170
    if (!sc->keyframes)
1171
        return -1;
1172
    for(i=0; i<entries; i++) {
1173
        sc->keyframes[i] = get_be32(pb);
1174
#ifdef DEBUG
1175
/*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1176
#endif
1177
    }
1178
    return 0;
1179
}
1180

    
1181
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1182
{
1183
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1184
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1185
    unsigned int i, entries;
1186

    
1187
    get_byte(pb); /* version */
1188
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1189

    
1190
    sc->sample_size = get_be32(pb);
1191
    entries = get_be32(pb);
1192
    if(entries >= UINT_MAX / sizeof(long))
1193
        return -1;
1194

    
1195
    sc->sample_count = entries;
1196
#ifdef DEBUG
1197
    av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1198
#endif
1199
    if(sc->sample_size)
1200
        return 0; /* there isn't any table following */
1201
    sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1202
    if (!sc->sample_sizes)
1203
        return -1;
1204
    for(i=0; i<entries; i++) {
1205
        sc->sample_sizes[i] = get_be32(pb);
1206
#ifdef DEBUG
1207
        av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1208
#endif
1209
    }
1210
    return 0;
1211
}
1212

    
1213
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1214
{
1215
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1216
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1217
    unsigned int i, entries;
1218
    int64_t duration=0;
1219
    int64_t total_sample_count=0;
1220

    
1221
    get_byte(pb); /* version */
1222
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1223
    entries = get_be32(pb);
1224
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1225
        return -1;
1226

    
1227
    sc->stts_count = entries;
1228
    sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1229

    
1230
#ifdef DEBUG
1231
av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1232
#endif
1233

    
1234
    sc->time_rate=0;
1235

    
1236
    for(i=0; i<entries; i++) {
1237
        int sample_duration;
1238
        int sample_count;
1239

    
1240
        sample_count=get_be32(pb);
1241
        sample_duration = get_be32(pb);
1242
        sc->stts_data[i].count= sample_count;
1243
        sc->stts_data[i].duration= sample_duration;
1244

    
1245
        sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1246

    
1247
        dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1248

    
1249
        duration+=sample_duration*sample_count;
1250
        total_sample_count+=sample_count;
1251
    }
1252

    
1253
    st->nb_frames= total_sample_count;
1254
    if(duration)
1255
        st->duration= duration;
1256
    return 0;
1257
}
1258

    
1259
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1260
{
1261
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1262
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1263
    unsigned int i, entries;
1264

    
1265
    get_byte(pb); /* version */
1266
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1267
    entries = get_be32(pb);
1268
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1269
        return -1;
1270

    
1271
    sc->ctts_count = entries;
1272
    sc->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1273

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

    
1276
    for(i=0; i<entries; i++) {
1277
        int count    =get_be32(pb);
1278
        int duration =get_be32(pb);
1279

    
1280
        sc->ctts_data[i].count   = count;
1281
        sc->ctts_data[i].duration= duration;
1282

    
1283
        sc->time_rate= ff_gcd(sc->time_rate, duration);
1284
    }
1285
    return 0;
1286
}
1287

    
1288
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1289
{
1290
    AVStream *st;
1291
    MOVStreamContext *sc;
1292

    
1293
    st = av_new_stream(c->fc, c->fc->nb_streams);
1294
    if (!st) return -2;
1295
    sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1296
    if (!sc) {
1297
        av_free(st);
1298
        return -1;
1299
    }
1300

    
1301
    sc->sample_to_chunk_index = -1;
1302
    st->priv_data = sc;
1303
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1304
    st->start_time = 0; /* XXX: check */
1305
    c->streams[c->fc->nb_streams-1] = sc;
1306

    
1307
    return mov_read_default(c, pb, atom);
1308
}
1309

    
1310
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1311
{
1312
    AVStream *st;
1313

    
1314
    st = c->fc->streams[c->fc->nb_streams-1];
1315

    
1316
    get_byte(pb); /* version */
1317

    
1318
    get_byte(pb); get_byte(pb);
1319
    get_byte(pb); /* flags */
1320
    /*
1321
    MOV_TRACK_ENABLED 0x0001
1322
    MOV_TRACK_IN_MOVIE 0x0002
1323
    MOV_TRACK_IN_PREVIEW 0x0004
1324
    MOV_TRACK_IN_POSTER 0x0008
1325
    */
1326

    
1327
    get_be32(pb); /* creation time */
1328
    get_be32(pb); /* modification time */
1329
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1330
    get_be32(pb); /* reserved */
1331
    st->start_time = 0; /* check */
1332
    get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1333
    get_be32(pb); /* reserved */
1334
    get_be32(pb); /* reserved */
1335

    
1336
    get_be16(pb); /* layer */
1337
    get_be16(pb); /* alternate group */
1338
    get_be16(pb); /* volume */
1339
    get_be16(pb); /* reserved */
1340

    
1341
    url_fskip(pb, 36); /* display matrix */
1342

    
1343
    /* those are fixed-point */
1344
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1345
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1346

    
1347
    return 0;
1348
}
1349

    
1350
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1351
/* like the files created with Adobe Premiere 5.0, for samples see */
1352
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1353
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1354
{
1355
    int err;
1356

    
1357
    if (atom.size < 8)
1358
        return 0; /* continue */
1359
    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1360
        url_fskip(pb, atom.size - 4);
1361
        return 0;
1362
    }
1363
    atom.type = get_le32(pb);
1364
    atom.offset += 8;
1365
    atom.size -= 8;
1366
    if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1367
        url_fskip(pb, atom.size);
1368
        return 0;
1369
    }
1370
    err = mov_read_mdat(c, pb, atom);
1371
    return err;
1372
}
1373

    
1374

    
1375
#ifdef CONFIG_ZLIB
1376
static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1377
{
1378
    return -1;
1379
}
1380

    
1381
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1382
{
1383
    ByteIOContext ctx;
1384
    uint8_t *cmov_data;
1385
    uint8_t *moov_data; /* uncompressed data */
1386
    long cmov_len, moov_len;
1387
    int ret;
1388

    
1389
    get_be32(pb); /* dcom atom */
1390
    if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1391
        return -1;
1392
    if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1393
        av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
1394
        return -1;
1395
    }
1396
    get_be32(pb); /* cmvd atom */
1397
    if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1398
        return -1;
1399
    moov_len = get_be32(pb); /* uncompressed size */
1400
    cmov_len = atom.size - 6 * 4;
1401

    
1402
    cmov_data = (uint8_t *) av_malloc(cmov_len);
1403
    if (!cmov_data)
1404
        return -1;
1405
    moov_data = (uint8_t *) av_malloc(moov_len);
1406
    if (!moov_data) {
1407
        av_free(cmov_data);
1408
        return -1;
1409
    }
1410
    get_buffer(pb, cmov_data, cmov_len);
1411
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1412
        return -1;
1413
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1414
        return -1;
1415
    ctx.buf_end = ctx.buffer + moov_len;
1416
    atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1417
    atom.offset = 0;
1418
    atom.size = moov_len;
1419
#ifdef DEBUG
1420
//    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1421
#endif
1422
    ret = mov_read_default(c, &ctx, atom);
1423
    av_free(moov_data);
1424
    av_free(cmov_data);
1425

    
1426
    return ret;
1427
}
1428
#endif
1429

    
1430
/* edit list atom */
1431
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1432
{
1433
  int i, edit_count;
1434

    
1435
  get_byte(pb); /* version */
1436
  get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1437
  edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1438

    
1439
  for(i=0; i<edit_count; i++){
1440
    get_be32(pb); /* Track duration */
1441
    get_be32(pb); /* Media time */
1442
    get_be32(pb); /* Media rate */
1443
  }
1444
  dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1445
  return 0;
1446
}
1447

    
1448
static const MOVParseTableEntry mov_default_parse_table[] = {
1449
/* mp4 atoms */
1450
{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1451
{ MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1452
{ MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1453
{ MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1454
{ MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1455
{ MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1456
{ MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1457
{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1458
{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1459
{ MKTAG( 'e', 'n', 'd', 'a' ), mov_read_enda },
1460
{ MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1461
{ MKTAG( 'f', 't', 'y', 'p' ), mov_read_ftyp },
1462
{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1463
{ MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1464
{ MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1465
{ MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
1466
{ MKTAG( 'j', 'p', '2', 'h' ), mov_read_jp2h },
1467
{ MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1468
{ MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1469
{ MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1470
{ MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1471
{ MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
1472
{ MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },
1473
{ MKTAG( 'm', 'p', '4', 's' ), mov_read_default },
1474
{ MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },
1475
{ MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },
1476
{ MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
1477
{ MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },
1478
{ MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },
1479
{ MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },
1480
{ MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },
1481
{ MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */
1482
{ MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
1483
{ MKTAG( 'a', 'l', 'a', 'c' ), mov_read_alac }, /* alac specific atom */
1484
{ MKTAG( 'a', 'v', 'c', 'C' ), mov_read_avcC },
1485
{ MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1486
{ MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1487
{ MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1488
{ MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1489
{ MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1490
{ MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1491
{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1492
{ MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1493
{ MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1494
{ MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1495
{ MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1496
{ MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1497
{ MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1498
{ MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1499
{ MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1500
{ MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1501
{ MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1502
{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1503
/* extra mp4 */
1504
{ MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1505
/* QT atoms */
1506
{ MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1507
{ MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1508
{ MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1509
{ MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1510
{ MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1511
{ MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1512
{ MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1513
{ MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1514
{ MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1515
{ MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1516
{ MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1517
{ MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1518
{ MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1519
{ MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1520
{ MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1521
{ MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1522
//{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1523
#ifdef CONFIG_ZLIB
1524
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1525
#else
1526
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1527
#endif
1528
{ 0L, mov_read_leaf }
1529
};
1530

    
1531
static void mov_free_stream_context(MOVStreamContext *sc)
1532
{
1533
    if(sc) {
1534
        av_freep(&sc->chunk_offsets);
1535
        av_freep(&sc->sample_to_chunk);
1536
        av_freep(&sc->sample_sizes);
1537
        av_freep(&sc->keyframes);
1538
        av_freep(&sc->stts_data);
1539
        av_freep(&sc->ctts_data);
1540
        av_freep(&sc);
1541
    }
1542
}
1543

    
1544
static inline uint32_t mov_to_tag(uint8_t *buf)
1545
{
1546
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1547
}
1548

    
1549
static inline uint32_t to_be32(uint8_t *buf)
1550
{
1551
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1552
}
1553

    
1554
/* XXX: is it sufficient ? */
1555
static int mov_probe(AVProbeData *p)
1556
{
1557
    unsigned int offset;
1558
    uint32_t tag;
1559
    int score = 0;
1560

    
1561
    /* check file header */
1562
    if (p->buf_size <= 12)
1563
        return 0;
1564
    offset = 0;
1565
    for(;;) {
1566
        /* ignore invalid offset */
1567
        if ((offset + 8) > (unsigned int)p->buf_size)
1568
            return score;
1569
        tag = mov_to_tag(p->buf + offset + 4);
1570
        switch(tag) {
1571
        /* check for obvious tags */
1572
        case MKTAG( 'j', 'P', ' ', ' ' ): /* jpeg 2000 signature */
1573
        case MKTAG( 'm', 'o', 'o', 'v' ):
1574
        case MKTAG( 'm', 'd', 'a', 't' ):
1575
        case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1576
        case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1577
            return AVPROBE_SCORE_MAX;
1578
        /* those are more common words, so rate then a bit less */
1579
        case MKTAG( 'w', 'i', 'd', 'e' ):
1580
        case MKTAG( 'f', 'r', 'e', 'e' ):
1581
        case MKTAG( 'j', 'u', 'n', 'k' ):
1582
        case MKTAG( 'p', 'i', 'c', 't' ):
1583
            return AVPROBE_SCORE_MAX - 5;
1584
        case MKTAG( 'f', 't', 'y', 'p' ):
1585
        case MKTAG( 's', 'k', 'i', 'p' ):
1586
        case MKTAG( 'u', 'u', 'i', 'd' ):
1587
            offset = to_be32(p->buf+offset) + offset;
1588
            /* if we only find those cause probedata is too small at least rate them */
1589
            score = AVPROBE_SCORE_MAX - 50;
1590
            break;
1591
        default:
1592
            /* unrecognized tag */
1593
            return score;
1594
        }
1595
    }
1596
    return score;
1597
}
1598

    
1599
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1600
{
1601
    MOVContext *mov = (MOVContext *) s->priv_data;
1602
    ByteIOContext *pb = &s->pb;
1603
    int i, j, nb, err;
1604
    MOV_atom_t atom = { 0, 0, 0 };
1605

    
1606
    mov->fc = s;
1607
    mov->parse_table = mov_default_parse_table;
1608

    
1609
    if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1610
        atom.size = url_fsize(pb);
1611
    else
1612
        atom.size = 0x7FFFFFFFFFFFFFFFLL;
1613

    
1614
    /* check MOV header */
1615
    err = mov_read_default(mov, pb, atom);
1616
    if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1617
        av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1618
                err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1619
        return -1;
1620
    }
1621
    dprintf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1622

    
1623
    /* some cleanup : make sure we are on the mdat atom */
1624
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1625
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1626

    
1627
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1628
    mov->total_streams = nb = s->nb_streams;
1629

    
1630
#if 1
1631
    for(i=0; i<s->nb_streams;) {
1632
        if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1633
            av_free(s->streams[i]);
1634
            for(j=i+1; j<s->nb_streams; j++)
1635
                s->streams[j-1] = s->streams[j];
1636
            s->nb_streams--;
1637
        } else
1638
            i++;
1639
    }
1640
    for(i=0; i<s->nb_streams;i++) {
1641
        MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
1642

    
1643
        if(!sc->time_rate)
1644
            sc->time_rate=1;
1645
        if(!sc->time_scale)
1646
            sc->time_scale= mov->time_scale;
1647
        av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1648

    
1649
        if(s->streams[i]->duration != AV_NOPTS_VALUE){
1650
            assert(s->streams[i]->duration % sc->time_rate == 0);
1651
            s->streams[i]->duration /= sc->time_rate;
1652
        }
1653

    
1654
        sc->ffindex = i;
1655
        sc->is_ff_stream = 1;
1656
    }
1657
#endif
1658
    return 0;
1659
}
1660

    
1661
/* Yes, this is ugly... I didn't write the specs of QT :p */
1662
/* XXX:remove useless commented code sometime */
1663
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1664
{
1665
    MOVContext *mov = (MOVContext *) s->priv_data;
1666
    MOVStreamContext *sc;
1667
    AVStream *st;
1668
    int64_t offset = INT64_MAX;
1669
    int64_t best_dts = INT64_MAX;
1670
    int i, a, b, m;
1671
    int size;
1672
    int idx;
1673
    size = 0x0FFFFFFF;
1674

    
1675
    if (mov->partial) {
1676
        sc = mov->partial;
1677
        idx = sc->sample_to_chunk_index;
1678

    
1679
        if (idx < 0) return 0;
1680
        dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1681
        //size = sc->sample_sizes[sc->current_sample];
1682
        // that ain't working...
1683
        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1684
        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1685

    
1686
        sc->current_sample++;
1687
        sc->left_in_chunk--;
1688

    
1689
        if (sc->left_in_chunk <= 0)
1690
            mov->partial = 0;
1691
        offset = mov->next_chunk_offset;
1692
        /* extract the sample */
1693

    
1694
        goto readchunk;
1695
    }
1696

    
1697
again:
1698
    sc = 0;
1699
    if(offset == INT64_MAX)
1700
        best_dts= INT64_MAX;
1701
    for(i=0; i<mov->total_streams; i++) {
1702
        MOVStreamContext *msc = mov->streams[i];
1703

    
1704
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1705
            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1706
                int64_t dts;
1707
                int index= msc->sample_to_time_index;
1708
                int sample= msc->sample_to_time_sample;
1709
                int time= msc->sample_to_time_time;
1710
                int duration = msc->stts_data[index].duration;
1711
                int count = msc->stts_data[index].count;
1712
                if (sample + count < msc->current_sample) {
1713
                    sample += count;
1714
                    time   += count*duration;
1715
                    index ++;
1716
                    duration = msc->stts_data[index].duration;
1717
                }
1718
                dts = time + (msc->current_sample-1 - sample) * (int64_t)duration;
1719
                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1720
                dprintf("stream: %d dts: %"PRId64" best_dts: %"PRId64" offset: %"PRId64"\n", i, dts, best_dts, offset);
1721
                if(dts < best_dts){
1722
                    best_dts= dts;
1723
                    sc = msc;
1724
                    offset = msc->chunk_offsets[msc->next_chunk];
1725
                }
1726
            }else{
1727
                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1728
                    sc = msc;
1729
                    offset = msc->chunk_offsets[msc->next_chunk];
1730
                }
1731
            }
1732
        }
1733
    }
1734
    if (!sc || offset==INT64_MAX)
1735
        return -1;
1736

    
1737
    sc->next_chunk++;
1738

    
1739
    if(mov->next_chunk_offset < offset) { /* some meta data */
1740
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1741
        mov->next_chunk_offset = offset;
1742
    }
1743

    
1744
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1745
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1746
        mov->next_chunk_offset = offset;
1747
        offset = INT64_MAX;
1748
        goto again;
1749
    }
1750

    
1751
    /* now get the chunk size... */
1752

    
1753
    for(i=0; i<mov->total_streams; i++) {
1754
        MOVStreamContext *msc = mov->streams[i];
1755
        if ((msc->next_chunk < msc->chunk_count)
1756
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1757
            && msc->chunk_offsets[msc->next_chunk] > offset)
1758
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1759
    }
1760

    
1761
#ifdef MOV_MINOLTA_FIX
1762
    //Make sure that size is according to sample_size (Needed by .mov files
1763
    //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1764
    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1765
    //but I have no such movies
1766
    if (sc->sample_size > 0) {
1767
        int foundsize=0;
1768
        for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1769
            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1770
            {
1771
                // I can't figure out why for PCM audio sample_size is always 1
1772
                // (it should actually be channels*bits_per_second/8) but it is.
1773
                AVCodecContext* cod = s->streams[sc->ffindex]->codec;
1774
                if (sc->sample_size == 1 && (cod->codec_id == CODEC_ID_PCM_S16BE || cod->codec_id == CODEC_ID_PCM_S16LE))
1775
                    foundsize=(sc->sample_to_chunk[i].count*cod->channels*cod->bits_per_sample)/8;
1776
                else
1777
                    foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
1778
            }
1779
            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);
1780
        }
1781
        if( (foundsize>0) && (foundsize<size) )
1782
        {
1783
            size=foundsize;
1784
        }
1785
    }
1786
#endif //MOV_MINOLTA_FIX
1787

    
1788
    idx = sc->sample_to_chunk_index;
1789
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1790
        idx++;
1791
    sc->sample_to_chunk_index = idx;
1792
    /* split chunks into samples */
1793
    if (sc->sample_size == 0 || sc->sample_size > 100) {
1794
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1795
            mov->partial = sc;
1796
            /* we'll have to get those samples before next chunk */
1797
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1798
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1799
        }
1800

    
1801
        sc->current_sample++;
1802
    }else if(idx + 1 < sc->sample_to_chunk_sz){
1803
        sc->current_sample += sc->sample_to_chunk[idx].count;
1804
    }
1805

    
1806
readchunk:
1807
    dprintf("chunk: %"PRId64" -> %"PRId64" (%i)\n", offset, offset + size, size);
1808
    if(size == 0x0FFFFFFF)
1809
        size = mov->mdat_size + mov->mdat_offset - offset;
1810
    if(size < 0)
1811
        return -1;
1812
    if(size == 0)
1813
        return -1;
1814
    url_fseek(&s->pb, offset, SEEK_SET);
1815

    
1816
    av_get_packet(&s->pb, pkt, size);
1817
    pkt->stream_index = sc->ffindex;
1818

    
1819
    // If the keyframes table exists, mark any samples that are in the table as key frames.
1820
    // If no table exists, treat very sample as a key frame.
1821
    if (sc->keyframes) {
1822
        a = 0;
1823
        b = sc->keyframe_count - 1;
1824

    
1825
        while (a < b) {
1826
            m = (a + b + 1) >> 1;
1827
            if (sc->keyframes[m] > sc->current_sample) {
1828
                b = m - 1;
1829
            } else {
1830
                a = m;
1831
            }
1832
        }
1833

    
1834
        if (sc->keyframes[a] == sc->current_sample)
1835
            pkt->flags |= PKT_FLAG_KEY;
1836
    }
1837
    else
1838
        pkt->flags |= PKT_FLAG_KEY;
1839

    
1840
    mov->next_chunk_offset = offset + size;
1841

    
1842
    /* find the corresponding dts */
1843
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1844
      unsigned int count;
1845
      uint64_t dts, pts;
1846
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1847
      count = sc->stts_data[sc->sample_to_time_index].count;
1848
      if ((sc->sample_to_time_sample + count) < sc->current_sample) {
1849
        sc->sample_to_time_sample += count;
1850
        sc->sample_to_time_time   += count*duration;
1851
        sc->sample_to_time_index ++;
1852
        duration = sc->stts_data[sc->sample_to_time_index].duration;
1853
      }
1854
      dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * (int64_t)duration;
1855
        /* find the corresponding pts */
1856
        if (sc->sample_to_ctime_index < sc->ctts_count) {
1857
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1858
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1859

    
1860
            if ((sc->sample_to_ctime_sample + count) < sc->current_sample) {
1861
                sc->sample_to_ctime_sample += count;
1862
                sc->sample_to_ctime_index ++;
1863
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1864
            }
1865
            pts = dts + duration;
1866
        }else
1867
            pts = dts;
1868

    
1869
        st= s->streams[ sc->ffindex ];
1870
        assert(pts % st->time_base.num == 0);
1871
        assert(dts % st->time_base.num == 0);
1872

    
1873
        pkt->pts = pts / st->time_base.num;
1874
        pkt->dts = dts / st->time_base.num;
1875
        dprintf("stream #%d smp #%ld dts = %"PRId64" pts = %"PRId64" (smp:%ld time:%"PRId64" idx:%d ent:%d count:%d dur:%d)\n"
1876
                , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1877
                , sc->sample_to_time_sample
1878
                , sc->sample_to_time_time
1879
                , sc->sample_to_time_index
1880
                , sc->stts_count
1881
                , count
1882
                , duration);
1883
    }
1884

    
1885
    return 0;
1886
}
1887

    
1888
#if defined(MOV_SEEK)
1889
/**
1890
 * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1891
 */
1892
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1893
{
1894
    MOVContext* mov = (MOVContext *) s->priv_data;
1895
    MOVStreamContext* sc;
1896
    int32_t i, a, b, m;
1897
    int64_t start_time;
1898
    int32_t seek_sample, sample;
1899
    int32_t duration;
1900
    int32_t count;
1901
    int32_t chunk;
1902
    int32_t left_in_chunk;
1903
    int64_t chunk_file_offset;
1904
    int64_t sample_file_offset;
1905
    int32_t first_chunk_sample;
1906
    int32_t sample_to_chunk_idx;
1907
    int sample_to_time_index;
1908
    long sample_to_time_sample = 0;
1909
    uint64_t sample_to_time_time = 0;
1910
    int mov_idx;
1911

    
1912
    // Find the corresponding mov stream
1913
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1914
        if (mov->streams[mov_idx]->ffindex == stream_index)
1915
            break;
1916
    if (mov_idx == mov->total_streams) {
1917
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1918
        return -1;
1919
    }
1920
    sc = mov->streams[mov_idx];
1921

    
1922
    sample_time *= s->streams[stream_index]->time_base.num;
1923

    
1924
    // Step 1. Find the edit that contains the requested time (elst)
1925
    if (sc->edit_count && 0) {
1926
        // FIXME should handle edit list
1927
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
1928
        return -1;
1929
    }
1930

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

    
1936
    for (i = 0; i < sc->stts_count; i++) {
1937
        count = sc->stts_data[i].count;
1938
        duration = sc->stts_data[i].duration;
1939
        if ((start_time + count*duration) > sample_time) {
1940
            sample_to_time_time = start_time;
1941
            sample_to_time_index = i;
1942
            sample_to_time_sample = sample;
1943
            sample += (sample_time - start_time) / duration;
1944
            break;
1945
        }
1946
        sample += count;
1947
        start_time += count * duration;
1948
    }
1949
    sample_to_time_time = start_time;
1950
    sample_to_time_index = i;
1951
    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
1952
       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
1953

    
1954
    dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
1955
    if (sample > sc->sample_count) {
1956
        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);
1957
        return -1;
1958
    }
1959

    
1960
    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
1961
    if (sc->keyframes) {
1962
        a = 0;
1963
        b = sc->keyframe_count - 1;
1964
        while (a < b) {
1965
            m = (a + b + 1) >> 1;
1966
            if (sc->keyframes[m] > sample) {
1967
                b = m - 1;
1968
            } else {
1969
                a = m;
1970
            }
1971
        }
1972
        // for low latency prob: always use the previous keyframe, just uncomment the next line
1973
        // if (a) a--;
1974
        seek_sample = sc->keyframes[a];
1975
    }
1976
    else
1977
        seek_sample = sample; // else all samples are key frames
1978
    dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
1979

    
1980
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
1981
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
1982
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
1983
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
1984
            break;
1985
        first_chunk_sample += b;
1986
    }
1987
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
1988
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
1989
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
1990
    sample_to_chunk_idx = i;
1991
    dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
1992

    
1993
    // Step 5. Find the offset of the chunk using the chunk offset atom
1994
    if (!sc->chunk_offsets) {
1995
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
1996
        return -1;
1997
    }
1998
    if (chunk > sc->chunk_count) {
1999
        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);
2000
        return -1;
2001
    }
2002
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
2003
    dprintf("Chunk file offset is #%"PRIu64"\n", chunk_file_offset);
2004

    
2005
    // Step 6. Find the byte offset within the chunk using the sample size atom
2006
    sample_file_offset = chunk_file_offset;
2007
    if (sc->sample_size)
2008
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2009
    else {
2010
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2011
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2012
        }
2013
    }
2014
    dprintf("Sample file offset is #%"PRIu64"\n", sample_file_offset);
2015

    
2016
    // Step 6. Update the parser
2017
    mov->partial = sc;
2018
    mov->next_chunk_offset = sample_file_offset;
2019
    // Update current stream state
2020
    sc->current_sample = seek_sample - 1;  // zero based
2021
    sc->left_in_chunk = left_in_chunk;
2022
    sc->next_chunk = chunk; // +1 -1 (zero based)
2023
    sc->sample_to_chunk_index = sample_to_chunk_idx;
2024

    
2025
    // Update other streams
2026
    for (i = 0; i<mov->total_streams; i++) {
2027
        MOVStreamContext *msc;
2028
        if (i == mov_idx) continue;
2029
        // Find the nearest 'next' chunk
2030
        msc = mov->streams[i];
2031
        a = 0;
2032
        b = msc->chunk_count - 1;
2033
        while (a < b) {
2034
            m = (a + b + 1) >> 1;
2035
            if (msc->chunk_offsets[m] > chunk_file_offset) {
2036
                b = m - 1;
2037
            } else {
2038
                a = m;
2039
            }
2040
        }
2041
        msc->next_chunk = a;
2042
        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2043
            msc->next_chunk ++;
2044
        dprintf("Nearest next chunk for stream #%i is #%li @%"PRId64"\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2045

    
2046
        // Compute sample count and index in the sample_to_chunk table (what a pity)
2047
        msc->sample_to_chunk_index = 0;
2048
        msc->current_sample = 0;
2049
        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2050
            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2051
            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2052
            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2053
        }
2054
        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;
2055
        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2056
        // Find corresponding position in stts (used later to compute dts)
2057
        sample = 0;
2058
        start_time = 0;
2059
        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2060
            count = msc->stts_data[msc->sample_to_time_index].count;
2061
            duration = msc->stts_data[msc->sample_to_time_index].duration;
2062
            if ((sample + count - 1) > msc->current_sample) {
2063
                msc->sample_to_time_time = start_time;
2064
                msc->sample_to_time_sample = sample;
2065
                break;
2066
            }
2067
            sample += count;
2068
            start_time += count * duration;
2069
        }
2070
        sample = 0;
2071
        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2072
            count = msc->ctts_data[msc->sample_to_ctime_index].count;
2073
            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2074
            if ((sample + count - 1) > msc->current_sample) {
2075
                msc->sample_to_ctime_sample = sample;
2076
                break;
2077
            }
2078
            sample += count;
2079
        }
2080
        dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2081
    }
2082
    return 0;
2083
}
2084
#endif
2085

    
2086
static int mov_read_close(AVFormatContext *s)
2087
{
2088
    int i;
2089
    MOVContext *mov = (MOVContext *) s->priv_data;
2090
    for(i=0; i<mov->total_streams; i++)
2091
        mov_free_stream_context(mov->streams[i]);
2092
    /* free color tabs */
2093
    for(i=0; i<mov->ctab_size; i++)
2094
        av_freep(&mov->ctab[i]);
2095
    av_freep(&mov->ctab);
2096
    return 0;
2097
}
2098

    
2099
static AVInputFormat mov_iformat = {
2100
    "mov,mp4,m4a,3gp,3g2,mj2",
2101
    "QuickTime/MPEG4/Motion JPEG 2000 format",
2102
    sizeof(MOVContext),
2103
    mov_probe,
2104
    mov_read_header,
2105
    mov_read_packet,
2106
    mov_read_close,
2107
#if defined(MOV_SEEK)
2108
    mov_read_seek,
2109
#endif
2110
};
2111

    
2112
int mov_init(void)
2113
{
2114
    av_register_input_format(&mov_iformat);
2115
    return 0;
2116
}