Statistics
| Branch: | Revision:

ffmpeg / libavformat / mov.c @ 232d8a1f

History | View | Annotate | Download (77.8 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_NONE, 0 },
148
};
149

    
150
static const CodecTag mov_audio_tags[] = {
151
/*    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */
152
    { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
153
    /* { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') },*/ /* 8 bits */
154
    { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
155
    { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /*  */
156
    { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /*  */
157
    { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /*  */
158
    { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */
159
    { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */
160
    { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */
161

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

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

    
203
/* the QuickTime file format is quite convoluted...
204
 * it has lots of index tables, each indexing something in another one...
205
 * Here we just use what is needed to read the chunks
206
 */
207

    
208
typedef struct MOV_sample_to_chunk_tbl {
209
    long first;
210
    long count;
211
    long id;
212
} MOV_sample_to_chunk_tbl;
213

    
214
typedef struct {
215
    uint32_t type;
216
    int64_t offset;
217
    int64_t size; /* total size (excluding the size and type fields) */
218
} MOV_atom_t;
219

    
220
typedef struct {
221
    int seed;
222
    int flags;
223
    int size;
224
    void* clrs;
225
} MOV_ctab_t;
226

    
227
typedef struct {
228
    uint8_t  version;
229
    uint32_t flags; // 24bit
230

    
231
    /* 0x03 ESDescrTag */
232
    uint16_t es_id;
233
#define MP4ODescrTag                    0x01
234
#define MP4IODescrTag                   0x02
235
#define MP4ESDescrTag                   0x03
236
#define MP4DecConfigDescrTag            0x04
237
#define MP4DecSpecificDescrTag          0x05
238
#define MP4SLConfigDescrTag             0x06
239
#define MP4ContentIdDescrTag            0x07
240
#define MP4SupplContentIdDescrTag       0x08
241
#define MP4IPIPtrDescrTag               0x09
242
#define MP4IPMPPtrDescrTag              0x0A
243
#define MP4IPMPDescrTag                 0x0B
244
#define MP4RegistrationDescrTag         0x0D
245
#define MP4ESIDIncDescrTag              0x0E
246
#define MP4ESIDRefDescrTag              0x0F
247
#define MP4FileIODescrTag               0x10
248
#define MP4FileODescrTag                0x11
249
#define MP4ExtProfileLevelDescrTag      0x13
250
#define MP4ExtDescrTagsStart            0x80
251
#define MP4ExtDescrTagsEnd              0xFE
252
    uint8_t  stream_priority;
253

    
254
    /* 0x04 DecConfigDescrTag */
255
    uint8_t  object_type_id;
256
    uint8_t  stream_type;
257
    /* XXX: really streamType is
258
     * only 6bit, followed by:
259
     * 1bit  upStream
260
     * 1bit  reserved
261
     */
262
    uint32_t buffer_size_db; // 24
263
    uint32_t max_bitrate;
264
    uint32_t avg_bitrate;
265

    
266
    /* 0x05 DecSpecificDescrTag */
267
    uint8_t  decoder_cfg_len;
268
    uint8_t *decoder_cfg;
269

    
270
    /* 0x06 SLConfigDescrTag */
271
    uint8_t  sl_config_len;
272
    uint8_t *sl_config;
273
} MOV_esds_t;
274

    
275
struct MOVParseTableEntry;
276

    
277
typedef struct Time2Sample{
278
    int count;
279
    int duration;
280
}Time2Sample;
281

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

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

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

    
336
    AVPaletteControl palette_control;
337
} MOVContext;
338

    
339

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

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

    
350
/* links atom IDs to parse functions */
351
typedef struct MOVParseTableEntry {
352
    uint32_t type;
353
    mov_parse_function func;
354
} MOVParseTableEntry;
355

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

    
377
extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */
378
int ff_mov_iso639_to_lang(const char *lang, int mp4)
379
{
380
    int i, code = 0;
381

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

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

    
414
static int mov_read_default(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
415
{
416
    int64_t total_size = 0;
417
    MOV_atom_t a;
418
    int i;
419
    int err = 0;
420

    
421
    a.offset = atom.offset;
422

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

    
449
        a.size -= 8;
450

    
451
        if(a.size < 0)
452
            break;
453

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

    
460
        a.offset += a.size;
461
        total_size += a.size;
462
    }
463

    
464
    if (!err && total_size < atom.size && atom.size < 0x7ffff) {
465
        url_fskip(pb, atom.size - total_size);
466
    }
467

    
468
    return err;
469
}
470

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

    
492
    return 0;
493
}
494

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

    
502
    get_byte(pb); /* version */
503
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
504

    
505
    /* component type */
506
    ctype = get_le32(pb);
507
    type = get_le32(pb); /* component subtype */
508

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

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

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

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

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

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

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

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

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

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

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

    
624
/* this atom should contain all header atoms */
625
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
626
{
627
    int err;
628

    
629
    err = mov_read_default(c, pb, atom);
630
    /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
631
    /* so we don't parse the whole file if over a network */
632
    c->found_moov=1;
633
    if(c->found_mdat)
634
        return 1; /* found both, just go */
635
    return 0; /* now go for mdat */
636
}
637

    
638

    
639
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
640
{
641
    int version;
642
    int lang;
643

    
644
    version = get_byte(pb); /* version */
645
    if (version > 1)
646
        return 1; /* unsupported */
647

    
648
    get_byte(pb); get_byte(pb);
649
    get_byte(pb); /* flags */
650

    
651
    (version==1)?get_be64(pb):get_be32(pb); /* creation time */
652
    (version==1)?get_be64(pb):get_be32(pb); /* modification time */
653

    
654
    c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb);
655
    c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
656

    
657
    lang = get_be16(pb); /* language */
658
    ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
659
    get_be16(pb); /* quality */
660

    
661
    return 0;
662
}
663

    
664
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
665
{
666
    get_byte(pb); /* version */
667
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
668

    
669
    get_be32(pb); /* creation time */
670
    get_be32(pb); /* modification time */
671
    c->time_scale = get_be32(pb); /* time scale */
672
#ifdef DEBUG
673
    av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);
674
#endif
675
    c->duration = get_be32(pb); /* duration */
676
    get_be32(pb); /* preferred scale */
677

    
678
    get_be16(pb); /* preferred volume */
679

    
680
    url_fskip(pb, 10); /* reserved */
681

    
682
    url_fskip(pb, 36); /* display matrix */
683

    
684
    get_be32(pb); /* preview time */
685
    get_be32(pb); /* preview duration */
686
    get_be32(pb); /* poster time */
687
    get_be32(pb); /* selection time */
688
    get_be32(pb); /* selection duration */
689
    get_be32(pb); /* current time */
690
    get_be32(pb); /* next track ID */
691

    
692
    return 0;
693
}
694

    
695
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
696
{
697
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
698

    
699
    if((uint64_t)atom.size > (1<<30))
700
        return -1;
701

    
702
    // currently SVQ3 decoder expect full STSD header - so let's fake it
703
    // this should be fixed and just SMI header should be passed
704
    av_free(st->codec->extradata);
705
    st->codec->extradata_size = 0x5a + atom.size;
706
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
707

    
708
    if (st->codec->extradata) {
709
        strcpy(st->codec->extradata, "SVQ3"); // fake
710
        get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
711
        dprintf("Reading SMI %Ld  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
712
    } else
713
        url_fskip(pb, atom.size);
714

    
715
    return 0;
716
}
717

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

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

    
725
    if (st->codec->codec_id == CODEC_ID_QDM2) {
726
        // pass all frma atom to codec, needed at least for QDM2
727
        av_free(st->codec->extradata);
728
        st->codec->extradata_size = atom.size;
729
        st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
730

    
731
        if (st->codec->extradata) {
732
            get_buffer(pb, st->codec->extradata, atom.size);
733
        } else
734
            url_fskip(pb, atom.size);
735
    } else if (atom.size > 8) { /* to read frma, esds atoms */
736
        mov_read_default(c, pb, atom);
737
    } else if (atom.size > 0)
738
        url_fskip(pb, atom.size);
739
    return 0;
740
}
741

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

    
746
    if((uint64_t)atom.size > (1<<30))
747
        return -1;
748

    
749
    av_free(st->codec->extradata);
750

    
751
    st->codec->extradata_size = atom.size;
752
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
753

    
754
    if (st->codec->extradata) {
755
        get_buffer(pb, st->codec->extradata, atom.size);
756
    } else
757
        url_fskip(pb, atom.size);
758

    
759
    return 0;
760
}
761

    
762
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
763
{
764
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
765
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
766
    unsigned int i, entries;
767

    
768
    get_byte(pb); /* version */
769
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
770

    
771
    entries = get_be32(pb);
772

    
773
    if(entries >= UINT_MAX/sizeof(int64_t))
774
        return -1;
775

    
776
    sc->chunk_count = entries;
777
    sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t));
778
    if (!sc->chunk_offsets)
779
        return -1;
780
    if (atom.type == MKTAG('s', 't', 'c', 'o')) {
781
        for(i=0; i<entries; i++) {
782
            sc->chunk_offsets[i] = get_be32(pb);
783
        }
784
    } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
785
        for(i=0; i<entries; i++) {
786
            sc->chunk_offsets[i] = get_be64(pb);
787
        }
788
    } else
789
        return -1;
790

    
791
    for(i=0; i<c->fc->nb_streams; i++){
792
        MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
793
        if(sc2 && sc2->chunk_offsets){
794
            int64_t first= sc2->chunk_offsets[0];
795
            int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
796
            if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
797
                c->ni=1;
798
        }
799
    }
800
    return 0;
801
}
802

    
803
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
804
{
805
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
806
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
807
    int entries, frames_per_sample;
808
    uint32_t format;
809
    uint8_t codec_name[32];
810

    
811
    /* for palette traversal */
812
    int color_depth;
813
    int color_start;
814
    int color_count;
815
    int color_end;
816
    int color_index;
817
    int color_dec;
818
    int color_greyscale;
819
    unsigned char *color_table;
820
    int j;
821
    unsigned char r, g, b;
822

    
823
    get_byte(pb); /* version */
824
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
825

    
826
    entries = get_be32(pb);
827

    
828
    while(entries--) { //Parsing Sample description table
829
        enum CodecID id;
830
        offset_t start_pos = url_ftell(pb);
831
        int size = get_be32(pb); /* size */
832
        format = get_le32(pb); /* data format */
833

    
834
        get_be32(pb); /* reserved */
835
        get_be16(pb); /* reserved */
836
        get_be16(pb); /* index */
837

    
838
        /* for MPEG4: set codec type by looking for it */
839
        id = codec_get_id(mov_video_tags, format);
840
        if(id <= 0)
841
            id = codec_get_id(codec_bmp_tags, format);
842
        if (id >= 0) {
843
            AVCodec *codec;
844
            codec = avcodec_find_decoder(id);
845
            if (codec)
846
                st->codec->codec_type = codec->type;
847
        }
848
        dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
849
                size,
850
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
851
                st->codec->codec_type);
852
        st->codec->codec_tag = format;
853
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
854
            MOV_atom_t a = { 0, 0, 0 };
855
            st->codec->codec_id = id;
856
            get_be16(pb); /* version */
857
            get_be16(pb); /* revision level */
858
            get_be32(pb); /* vendor */
859
            get_be32(pb); /* temporal quality */
860
            get_be32(pb); /* spacial quality */
861
            if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
862
                get_be16(pb);
863
                get_be16(pb);
864
            }else{
865
                st->codec->width = get_be16(pb); /* width */
866
                st->codec->height = get_be16(pb); /* height */
867
            }
868
            get_be32(pb); /* horiz resolution */
869
            get_be32(pb); /* vert resolution */
870
            get_be32(pb); /* data size, always 0 */
871
            frames_per_sample = get_be16(pb); /* frames per samples */
872
#ifdef DEBUG
873
            av_log(NULL, AV_LOG_DEBUG, "frames/samples = %d\n", frames_per_sample);
874
#endif
875
        get_buffer(pb, codec_name, 32); /* codec name, pascal string (FIXME: true for mp4?) */
876
        if (codec_name[0] <= 31) {
877
            memcpy(st->codec->codec_name, &codec_name[1],codec_name[0]);
878
            st->codec->codec_name[codec_name[0]] = 0;
879
        }
880

    
881
            st->codec->bits_per_sample = get_be16(pb); /* depth */
882
            st->codec->color_table_id = get_be16(pb); /* colortable id */
883

    
884
/*          These are set in mov_read_stts and might already be set!
885
            st->codec->time_base.den      = 25;
886
            st->codec->time_base.num = 1;
887
*/
888
#if 0
889
            while (size >= 8) {
890
                MOV_atom_t a;
891
                int64_t start_pos;
892

893
                a.size = get_be32(pb);
894
                a.type = get_le32(pb);
895
                size -= 8;
896
#ifdef DEBUG
897
                av_log(NULL, AV_LOG_DEBUG, "VIDEO: atom_type=%c%c%c%c atom.size=%Ld size_left=%d\n",
898
                       (a.type >> 0) & 0xff,
899
                       (a.type >> 8) & 0xff,
900
                       (a.type >> 16) & 0xff,
901
                       (a.type >> 24) & 0xff,
902
                       a.size, size);
903
#endif
904
                start_pos = url_ftell(pb);
905

    
906
                switch(a.type) {
907
                case MKTAG('e', 's', 'd', 's'):
908
                    {
909
                        int tag, len;
910
                        /* Well, broken but suffisant for some MP4 streams */
911
                        get_be32(pb); /* version + flags */
912
                        len = mov_mp4_read_descr(pb, &tag);
913
                        if (tag == 0x03) {
914
                            /* MP4ESDescrTag */
915
                            get_be16(pb); /* ID */
916
                            get_byte(pb); /* priority */
917
                            len = mov_mp4_read_descr(pb, &tag);
918
                            if (tag != 0x04)
919
                                goto fail;
920
                            /* MP4DecConfigDescrTag */
921
                            get_byte(pb); /* objectTypeId */
922
                            get_be32(pb); /* streamType + buffer size */
923
                            get_be32(pb); /* max bit rate */
924
                            get_be32(pb); /* avg bit rate */
925
                            len = mov_mp4_read_descr(pb, &tag);
926
                            if (tag != 0x05)
927
                                goto fail;
928
                            /* MP4DecSpecificDescrTag */
929
                            sc->header_data = av_mallocz(len);
930
                            if (sc->header_data) {
931
                                get_buffer(pb, sc->header_data, len);
932
                                sc->header_len = len;
933
                            }
934
                        }
935
                        /* in any case, skip garbage */
936
                    }
937
                    break;
938
                default:
939
                    break;
940
                }
941
            fail:
942
                dprintf("ATOMENEWSIZE %Ld   %d\n", atom.size, url_ftell(pb) - start_pos);
943
                if (atom.size > 8) {
944
                    url_fskip(pb, (atom.size - 8) -
945
                              ((url_ftell(pb) - start_pos)));
946
                    size -= atom.size - 8;
947
                }
948
            }
949
            if (size > 0) {
950
                /* unknown extension */
951
                url_fskip(pb, size);
952
            }
953
#else
954

    
955
            /* figure out the palette situation */
956
            color_depth = st->codec->bits_per_sample & 0x1F;
957
            color_greyscale = st->codec->bits_per_sample & 0x20;
958

    
959
            /* if the depth is 2, 4, or 8 bpp, file is palettized */
960
            if ((color_depth == 2) || (color_depth == 4) ||
961
                (color_depth == 8)) {
962

    
963
                if (color_greyscale) {
964

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

    
978
                } else if (st->codec->color_table_id & 0x08) {
979

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

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

    
997
                } else {
998

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

    
1020
                st->codec->palctrl = &c->palette_control;
1021
                st->codec->palctrl->palette_changed = 1;
1022
            } else
1023
                st->codec->palctrl = NULL;
1024

    
1025
            a.size = size - (url_ftell(pb) - start_pos);
1026
            if (a.size > 8)
1027
                mov_read_default(c, pb, a);
1028
            else if (a.size > 0)
1029
                url_fskip(pb, a.size);
1030
#endif
1031
        } else {
1032
            st->codec->codec_id = codec_get_id(mov_audio_tags, format);
1033
            if(st->codec->codec_id==CODEC_ID_AMR_NB || st->codec->codec_id==CODEC_ID_AMR_WB) //from TS26.244
1034
            {
1035
               dprintf("AMR audio identified %d!!\n", st->codec->codec_id);
1036
               get_be32(pb);get_be32(pb); //Reserved_8
1037
               get_be16(pb);//Reserved_2
1038
               get_be16(pb);//Reserved_2
1039
               get_be32(pb);//Reserved_4
1040
               get_be16(pb);//TimeScale
1041
               get_be16(pb);//Reserved_2
1042

    
1043
                //AMRSpecificBox.(10 bytes)
1044

    
1045
               get_be32(pb); //size
1046
               get_be32(pb); //type=='damr'
1047
               get_be32(pb); //vendor
1048
               get_byte(pb); //decoder version
1049
               get_be16(pb); //mode_set
1050
               get_byte(pb); //mode_change_period
1051
               get_byte(pb); //frames_per_sample
1052

    
1053
               st->duration = AV_NOPTS_VALUE;//Not possible to get from this info, must count number of AMR frames
1054
               if(st->codec->codec_id==CODEC_ID_AMR_NB)
1055
               {
1056
                   st->codec->sample_rate=8000;
1057
                   st->codec->channels=1;
1058
               }
1059
               else //AMR-WB
1060
               {
1061
                   st->codec->sample_rate=16000;
1062
                   st->codec->channels=1;
1063
               }
1064
               st->codec->bits_per_sample=16;
1065
               st->codec->bit_rate=0; /*It is not possible to tell this before we have
1066
                                       an audio frame and even then every frame can be different*/
1067
            }
1068
            else if( st->codec->codec_tag == MKTAG( 'm', 'p', '4', 's' ))
1069
            {
1070
                //This is some stuff for the hint track, lets ignore it!
1071
                //Do some mp4 auto detect.
1072
                c->mp4=1;
1073
                size-=(16);
1074
                url_fskip(pb, size); /* The mp4s atom also contians a esds atom that we can skip*/
1075
            }
1076
            else if( st->codec->codec_tag == MKTAG( 'm', 'p', '4', 'a' ))
1077
            {
1078
                MOV_atom_t a;
1079
                int mp4_version;
1080

    
1081
                /* Handle mp4 audio tag */
1082
                mp4_version=get_be16(pb);/*version*/
1083
                get_be16(pb); /*revesion*/
1084
                get_be32(pb);
1085
                st->codec->channels = get_be16(pb); /* channels */
1086
                st->codec->bits_per_sample = get_be16(pb); /* bits per sample */
1087
                get_be32(pb);
1088
                st->codec->sample_rate = get_be16(pb); /* sample rate, not always correct */
1089
                if(st->codec->sample_rate == 1) //nonsese rate? -> ignore
1090
                    st->codec->sample_rate= 0;
1091

    
1092
                get_be16(pb);
1093
                c->mp4=1;
1094

    
1095
                if(mp4_version==1)
1096
                {
1097
                    url_fskip(pb,16);
1098
                    a.size=size-(16+20+16);
1099
                }
1100
                else
1101
                    a.size=size-(16+20);
1102

    
1103
                a.offset=url_ftell(pb);
1104

    
1105
                mov_read_default(c, pb, a);
1106

    
1107
                /* Get correct sample rate from extradata */
1108
                if(st->codec->extradata_size) {
1109
                   const int samplerate_table[] = {
1110
                     96000, 88200, 64000, 48000, 44100, 32000,
1111
                     24000, 22050, 16000, 12000, 11025, 8000,
1112
                     7350, 0, 0, 0
1113
                   };
1114
                   unsigned char *px = st->codec->extradata;
1115
                   // 5 bits objectTypeIndex, 4 bits sampleRateIndex, 4 bits channels
1116
                   int samplerate_index = ((px[0] & 7) << 1) + ((px[1] >> 7) & 1);
1117
                   st->codec->sample_rate = samplerate_table[samplerate_index];
1118
                   st->codec->channels = (px[1] >> 3) & 15;
1119
                }
1120
            }
1121
            else if( st->codec->codec_tag == MKTAG( 'a', 'l', 'a', 'c' ))
1122
            {
1123
                /* Handle alac audio tag + special extradata */
1124
                get_be32(pb); /* version */
1125
                get_be32(pb);
1126
                st->codec->channels = get_be16(pb); /* channels */
1127
                st->codec->bits_per_sample = get_be16(pb); /* bits per sample */
1128
                get_be32(pb);
1129
                st->codec->sample_rate = get_be16(pb);
1130
                get_be16(pb);
1131

    
1132
                /* fetch the 36-byte extradata needed for alac decoding */
1133
                st->codec->extradata_size = 36;
1134
                st->codec->extradata = (uint8_t*)
1135
                    av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
1136
                get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
1137
            }
1138
            else if(size>=(16+20))
1139
            {//16 bytes read, reading atleast 20 more
1140
                uint16_t version;
1141
                version = get_be16(pb); /* version */
1142
                get_be16(pb); /* revision level */
1143
                get_be32(pb); /* vendor */
1144

    
1145
                st->codec->channels = get_be16(pb);             /* channel count */
1146
                st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1147

    
1148
                /* handle specific s8 codec */
1149
                get_be16(pb); /* compression id = 0*/
1150
                get_be16(pb); /* packet size = 0 */
1151

    
1152
                st->codec->sample_rate = ((get_be32(pb) >> 16));
1153

    
1154
                switch (st->codec->codec_id) {
1155
                case CODEC_ID_PCM_S16BE:
1156
                    if (st->codec->bits_per_sample == 8)
1157
                        st->codec->codec_id = CODEC_ID_PCM_S8;
1158
                    /* fall */
1159
                case CODEC_ID_PCM_U8:
1160
                    st->codec->bit_rate = st->codec->sample_rate * 8;
1161
                    break;
1162
                default:
1163
                    ;
1164
                }
1165

    
1166
                //Read QT version 1 fields. In version 0 theese dont exist
1167
                dprintf("version =%d mp4=%d\n",version,c->mp4);
1168
                if((version==1) && size>=(16+20+16))
1169
                {
1170
                    get_be32(pb); /* samples per packet */
1171
                    get_be32(pb); /* bytes per packet */
1172
                    get_be32(pb); /* bytes per frame */
1173
                    get_be32(pb); /* bytes per sample */
1174
                    if(size>(16+20+16))
1175
                    {
1176
                        //Optional, additional atom-based fields
1177
                        MOV_atom_t a = { format, url_ftell(pb), size - (16 + 20 + 16 + 8) };
1178
                        mov_read_default(c, pb, a);
1179
                    }
1180
                }
1181
                else
1182
                {
1183
                    //We should be down to 0 bytes here, but lets make sure.
1184
                    size-=(16+20);
1185
                    if(size>0) {
1186
                        dprintf("skipping 0x%X bytes\n",size-(16+20));
1187
                        url_fskip(pb, size);
1188
                    }
1189
                }
1190
            }
1191
            else
1192
            {
1193
                size-=16;
1194
                //Unknown size, but lets do our best and skip the rest.
1195
                dprintf("Strange size, skipping 0x%X bytes\n",size);
1196
                url_fskip(pb, size);
1197
            }
1198
        }
1199
    }
1200

    
1201
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1202
        st->codec->sample_rate= sc->time_scale;
1203
    }
1204

    
1205
    return 0;
1206
}
1207

    
1208
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1209
{
1210
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1211
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1212
    unsigned int i, entries;
1213

    
1214
    get_byte(pb); /* version */
1215
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1216

    
1217
    entries = get_be32(pb);
1218

    
1219
    if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1220
        return -1;
1221

    
1222
#ifdef DEBUG
1223
av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1224
#endif
1225
    sc->sample_to_chunk_sz = entries;
1226
    sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1227
    if (!sc->sample_to_chunk)
1228
        return -1;
1229
    for(i=0; i<entries; i++) {
1230
        sc->sample_to_chunk[i].first = get_be32(pb);
1231
        sc->sample_to_chunk[i].count = get_be32(pb);
1232
        sc->sample_to_chunk[i].id = get_be32(pb);
1233
    }
1234
    return 0;
1235
}
1236

    
1237
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1238
{
1239
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1240
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1241
    unsigned int i, entries;
1242

    
1243
    get_byte(pb); /* version */
1244
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1245

    
1246
    entries = get_be32(pb);
1247

    
1248
    if(entries >= UINT_MAX / sizeof(long))
1249
        return -1;
1250

    
1251
    sc->keyframe_count = entries;
1252
#ifdef DEBUG
1253
    av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1254
#endif
1255
    sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1256
    if (!sc->keyframes)
1257
        return -1;
1258
    for(i=0; i<entries; i++) {
1259
        sc->keyframes[i] = get_be32(pb);
1260
#ifdef DEBUG
1261
/*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1262
#endif
1263
    }
1264
    return 0;
1265
}
1266

    
1267
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1268
{
1269
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1270
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1271
    unsigned int i, entries;
1272

    
1273
    get_byte(pb); /* version */
1274
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1275

    
1276
    sc->sample_size = get_be32(pb);
1277
    entries = get_be32(pb);
1278
    if(entries >= UINT_MAX / sizeof(long))
1279
        return -1;
1280

    
1281
    sc->sample_count = entries;
1282
#ifdef DEBUG
1283
    av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1284
#endif
1285
    if(sc->sample_size)
1286
        return 0; /* there isn't any table following */
1287
    sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1288
    if (!sc->sample_sizes)
1289
        return -1;
1290
    for(i=0; i<entries; i++) {
1291
        sc->sample_sizes[i] = get_be32(pb);
1292
#ifdef DEBUG
1293
        av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1294
#endif
1295
    }
1296
    return 0;
1297
}
1298

    
1299
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1300
{
1301
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1302
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1303
    unsigned int i, entries;
1304
    int64_t duration=0;
1305
    int64_t total_sample_count=0;
1306

    
1307
    get_byte(pb); /* version */
1308
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1309
    entries = get_be32(pb);
1310
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1311
        return -1;
1312

    
1313
    sc->stts_count = entries;
1314
    sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1315

    
1316
#ifdef DEBUG
1317
av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1318
#endif
1319

    
1320
    sc->time_rate=0;
1321

    
1322
    for(i=0; i<entries; i++) {
1323
        int sample_duration;
1324
        int sample_count;
1325

    
1326
        sample_count=get_be32(pb);
1327
        sample_duration = get_be32(pb);
1328
        sc->stts_data[i].count= sample_count;
1329
        sc->stts_data[i].duration= sample_duration;
1330

    
1331
        sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1332

    
1333
        dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1334

    
1335
        duration+=sample_duration*sample_count;
1336
        total_sample_count+=sample_count;
1337
    }
1338

    
1339
    st->nb_frames= total_sample_count;
1340
    if(duration)
1341
        st->duration= duration;
1342
    return 0;
1343
}
1344

    
1345
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1346
{
1347
    unsigned int i, entries;
1348

    
1349
    get_byte(pb); /* version */
1350
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1351
    entries = get_be32(pb);
1352
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1353
        return -1;
1354

    
1355
    c->streams[c->fc->nb_streams-1]->ctts_count = entries;
1356
    c->streams[c->fc->nb_streams-1]->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1357

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

    
1360
    for(i=0; i<entries; i++) {
1361
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].count= get_be32(pb);
1362
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].duration= get_be32(pb);
1363
    }
1364
    return 0;
1365
}
1366

    
1367
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1368
{
1369
    AVStream *st;
1370
    MOVStreamContext *sc;
1371

    
1372
    st = av_new_stream(c->fc, c->fc->nb_streams);
1373
    if (!st) return -2;
1374
    sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1375
    if (!sc) {
1376
        av_free(st);
1377
        return -1;
1378
    }
1379

    
1380
    sc->sample_to_chunk_index = -1;
1381
    st->priv_data = sc;
1382
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1383
    st->start_time = 0; /* XXX: check */
1384
    c->streams[c->fc->nb_streams-1] = sc;
1385

    
1386
    return mov_read_default(c, pb, atom);
1387
}
1388

    
1389
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1390
{
1391
    AVStream *st;
1392

    
1393
    st = c->fc->streams[c->fc->nb_streams-1];
1394

    
1395
    get_byte(pb); /* version */
1396

    
1397
    get_byte(pb); get_byte(pb);
1398
    get_byte(pb); /* flags */
1399
    /*
1400
    MOV_TRACK_ENABLED 0x0001
1401
    MOV_TRACK_IN_MOVIE 0x0002
1402
    MOV_TRACK_IN_PREVIEW 0x0004
1403
    MOV_TRACK_IN_POSTER 0x0008
1404
    */
1405

    
1406
    get_be32(pb); /* creation time */
1407
    get_be32(pb); /* modification time */
1408
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1409
    get_be32(pb); /* reserved */
1410
    st->start_time = 0; /* check */
1411
    get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1412
    get_be32(pb); /* reserved */
1413
    get_be32(pb); /* reserved */
1414

    
1415
    get_be16(pb); /* layer */
1416
    get_be16(pb); /* alternate group */
1417
    get_be16(pb); /* volume */
1418
    get_be16(pb); /* reserved */
1419

    
1420
    url_fskip(pb, 36); /* display matrix */
1421

    
1422
    /* those are fixed-point */
1423
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1424
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1425

    
1426
    return 0;
1427
}
1428

    
1429
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1430
/* like the files created with Adobe Premiere 5.0, for samples see */
1431
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1432
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1433
{
1434
    int err;
1435

    
1436
    if (atom.size < 8)
1437
        return 0; /* continue */
1438
    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1439
        url_fskip(pb, atom.size - 4);
1440
        return 0;
1441
    }
1442
    atom.type = get_le32(pb);
1443
    atom.offset += 8;
1444
    atom.size -= 8;
1445
    if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1446
        url_fskip(pb, atom.size);
1447
        return 0;
1448
    }
1449
    err = mov_read_mdat(c, pb, atom);
1450
    return err;
1451
}
1452

    
1453

    
1454
#ifdef CONFIG_ZLIB
1455
static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1456
{
1457
    return -1;
1458
}
1459

    
1460
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1461
{
1462
    ByteIOContext ctx;
1463
    uint8_t *cmov_data;
1464
    uint8_t *moov_data; /* uncompressed data */
1465
    long cmov_len, moov_len;
1466
    int ret;
1467

    
1468
    get_be32(pb); /* dcom atom */
1469
    if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1470
        return -1;
1471
    if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1472
        av_log(NULL, AV_LOG_ERROR, "unknown compression for cmov atom !");
1473
        return -1;
1474
    }
1475
    get_be32(pb); /* cmvd atom */
1476
    if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1477
        return -1;
1478
    moov_len = get_be32(pb); /* uncompressed size */
1479
    cmov_len = atom.size - 6 * 4;
1480

    
1481
    cmov_data = (uint8_t *) av_malloc(cmov_len);
1482
    if (!cmov_data)
1483
        return -1;
1484
    moov_data = (uint8_t *) av_malloc(moov_len);
1485
    if (!moov_data) {
1486
        av_free(cmov_data);
1487
        return -1;
1488
    }
1489
    get_buffer(pb, cmov_data, cmov_len);
1490
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1491
        return -1;
1492
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1493
        return -1;
1494
    ctx.buf_end = ctx.buffer + moov_len;
1495
    atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1496
    atom.offset = 0;
1497
    atom.size = moov_len;
1498
#ifdef DEBUG
1499
//    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1500
#endif
1501
    ret = mov_read_default(c, &ctx, atom);
1502
    av_free(moov_data);
1503
    av_free(cmov_data);
1504

    
1505
    return ret;
1506
}
1507
#endif
1508

    
1509
/* edit list atom */
1510
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1511
{
1512
  int i, edit_count;
1513

    
1514
  get_byte(pb); /* version */
1515
  get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1516
  edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1517

    
1518
  for(i=0; i<edit_count; i++){
1519
    get_be32(pb); /* Track duration */
1520
    get_be32(pb); /* Media time */
1521
    get_be32(pb); /* Media rate */
1522
  }
1523
  dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1524
  return 0;
1525
}
1526

    
1527
static const MOVParseTableEntry mov_default_parse_table[] = {
1528
/* mp4 atoms */
1529
{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1530
{ MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1531
{ MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1532
{ MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1533
{ MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1534
{ MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1535
{ MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1536
{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1537
{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1538
{ MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1539
{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1540
{ MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1541
{ MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1542
{ MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
1543
{ MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1544
{ MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1545
{ MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1546
{ MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1547
{ MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
1548
{ MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },
1549
{ MKTAG( 'm', 'p', '4', 's' ), mov_read_default },
1550
{ MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },
1551
{ MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },
1552
{ MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
1553
{ MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },
1554
{ MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },
1555
{ MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },
1556
{ MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },
1557
{ MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */
1558
{ MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
1559
{ MKTAG( 'a', 'v', 'c', 'C' ), mov_read_avcC },
1560
{ MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1561
{ MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1562
{ MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1563
{ MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1564
{ MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1565
{ MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1566
{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1567
{ MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1568
{ MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1569
{ MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1570
{ MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1571
{ MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1572
{ MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1573
{ MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1574
{ MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1575
{ MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1576
{ MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1577
{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1578
/* extra mp4 */
1579
{ MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1580
/* QT atoms */
1581
{ MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1582
{ MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1583
{ MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1584
{ MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1585
{ MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1586
{ MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1587
{ MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1588
{ MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1589
{ MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1590
{ MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1591
{ MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1592
{ MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1593
{ MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1594
{ MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1595
{ MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1596
{ MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1597
//{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1598
#ifdef CONFIG_ZLIB
1599
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1600
#else
1601
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1602
#endif
1603
{ 0L, mov_read_leaf }
1604
};
1605

    
1606
static void mov_free_stream_context(MOVStreamContext *sc)
1607
{
1608
    if(sc) {
1609
        av_freep(&sc->chunk_offsets);
1610
        av_freep(&sc->sample_to_chunk);
1611
        av_freep(&sc->sample_sizes);
1612
        av_freep(&sc->keyframes);
1613
        av_freep(&sc->stts_data);
1614
        av_freep(&sc->ctts_data);
1615
        av_freep(&sc);
1616
    }
1617
}
1618

    
1619
static inline uint32_t mov_to_tag(uint8_t *buf)
1620
{
1621
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1622
}
1623

    
1624
static inline uint32_t to_be32(uint8_t *buf)
1625
{
1626
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1627
}
1628

    
1629
/* XXX: is it sufficient ? */
1630
static int mov_probe(AVProbeData *p)
1631
{
1632
    unsigned int offset;
1633
    uint32_t tag;
1634
    int score = 0;
1635

    
1636
    /* check file header */
1637
    if (p->buf_size <= 12)
1638
        return 0;
1639
    offset = 0;
1640
    for(;;) {
1641
        /* ignore invalid offset */
1642
        if ((offset + 8) > (unsigned int)p->buf_size)
1643
            return score;
1644
        tag = mov_to_tag(p->buf + offset + 4);
1645
        switch(tag) {
1646
        /* check for obvious tags */
1647
        case MKTAG( 'm', 'o', 'o', 'v' ):
1648
        case MKTAG( 'm', 'd', 'a', 't' ):
1649
        case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1650
        case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1651
            return AVPROBE_SCORE_MAX;
1652
        /* those are more common words, so rate then a bit less */
1653
        case MKTAG( 'w', 'i', 'd', 'e' ):
1654
        case MKTAG( 'f', 'r', 'e', 'e' ):
1655
        case MKTAG( 'j', 'u', 'n', 'k' ):
1656
        case MKTAG( 'p', 'i', 'c', 't' ):
1657
            return AVPROBE_SCORE_MAX - 5;
1658
        case MKTAG( 'f', 't', 'y', 'p' ):
1659
        case MKTAG( 's', 'k', 'i', 'p' ):
1660
        case MKTAG( 'u', 'u', 'i', 'd' ):
1661
            offset = to_be32(p->buf+offset) + offset;
1662
            /* if we only find those cause probedata is too small at least rate them */
1663
            score = AVPROBE_SCORE_MAX - 50;
1664
            break;
1665
        default:
1666
            /* unrecognized tag */
1667
            return score;
1668
        }
1669
    }
1670
    return score;
1671
}
1672

    
1673
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1674
{
1675
    MOVContext *mov = (MOVContext *) s->priv_data;
1676
    ByteIOContext *pb = &s->pb;
1677
    int i, j, nb, err;
1678
    MOV_atom_t atom = { 0, 0, 0 };
1679

    
1680
    mov->fc = s;
1681
    mov->parse_table = mov_default_parse_table;
1682
#if 0
1683
    /* XXX: I think we should auto detect */
1684
    if(s->iformat->name[1] == 'p')
1685
        mov->mp4 = 1;
1686
#endif
1687
    if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1688
        atom.size = url_fsize(pb);
1689
    else
1690
        atom.size = 0x7FFFFFFFFFFFFFFFLL;
1691

    
1692
    /* check MOV header */
1693
    err = mov_read_default(mov, pb, atom);
1694
    if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1695
        av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1696
                err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1697
        return -1;
1698
    }
1699
    dprintf("on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1700

    
1701
    /* some cleanup : make sure we are on the mdat atom */
1702
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1703
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1704

    
1705
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1706
    mov->total_streams = nb = s->nb_streams;
1707

    
1708
#if 1
1709
    for(i=0; i<s->nb_streams;) {
1710
        if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1711
            av_free(s->streams[i]);
1712
            for(j=i+1; j<s->nb_streams; j++)
1713
                s->streams[j-1] = s->streams[j];
1714
            s->nb_streams--;
1715
        } else
1716
            i++;
1717
    }
1718
    for(i=0; i<s->nb_streams;i++) {
1719
        MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
1720

    
1721
        if(!sc->time_rate)
1722
            sc->time_rate=1;
1723
        av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1724

    
1725
        assert(s->streams[i]->duration % sc->time_rate == 0);
1726
        s->streams[i]->duration /= sc->time_rate;
1727

    
1728
        sc->ffindex = i;
1729
        sc->is_ff_stream = 1;
1730
    }
1731
#endif
1732
    return 0;
1733
}
1734

    
1735
/* Yes, this is ugly... I didn't write the specs of QT :p */
1736
/* XXX:remove useless commented code sometime */
1737
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1738
{
1739
    MOVContext *mov = (MOVContext *) s->priv_data;
1740
    MOVStreamContext *sc;
1741
    AVStream *st;
1742
    int64_t offset = INT64_MAX;
1743
    int64_t best_dts = INT64_MAX;
1744
    int i, a, b, m;
1745
    int size;
1746
    int idx;
1747
    size = 0x0FFFFFFF;
1748

    
1749
    if (mov->partial) {
1750
        sc = mov->partial;
1751
        idx = sc->sample_to_chunk_index;
1752

    
1753
        if (idx < 0) return 0;
1754
        dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1755
        //size = sc->sample_sizes[sc->current_sample];
1756
        // that ain't working...
1757
        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1758
        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1759

    
1760
        sc->current_sample++;
1761
        sc->left_in_chunk--;
1762

    
1763
        if (sc->left_in_chunk <= 0)
1764
            mov->partial = 0;
1765
        offset = mov->next_chunk_offset;
1766
        /* extract the sample */
1767

    
1768
        goto readchunk;
1769
    }
1770

    
1771
again:
1772
    sc = 0;
1773
    if(offset == INT64_MAX)
1774
        best_dts= INT64_MAX;
1775
    for(i=0; i<mov->total_streams; i++) {
1776
        MOVStreamContext *msc = mov->streams[i];
1777

    
1778
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1779
            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1780
                int64_t dts;
1781
                int index= msc->sample_to_time_index;
1782
                int sample= msc->sample_to_time_sample;
1783
                int time= msc->sample_to_time_time;
1784
                int duration = msc->stts_data[index].duration;
1785
                int count = msc->stts_data[index].count;
1786
                if (sample + count < msc->current_sample) {
1787
                    sample += count;
1788
                    time   += count*duration;
1789
                    index ++;
1790
                    duration = msc->stts_data[index].duration;
1791
                }
1792
                dts = time + (msc->current_sample-1 - sample) * (int64_t)duration;
1793
                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1794
                dprintf("stream: %d dts: %Ld best_dts: %Ld offset: %Ld \n", i, dts, best_dts, offset);
1795
                if(dts < best_dts){
1796
                    best_dts= dts;
1797
                    sc = msc;
1798
                    offset = msc->chunk_offsets[msc->next_chunk];
1799
                }
1800
            }else{
1801
                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1802
                    sc = msc;
1803
                    offset = msc->chunk_offsets[msc->next_chunk];
1804
                }
1805
            }
1806
        }
1807
    }
1808
    if (!sc || offset==INT64_MAX)
1809
        return -1;
1810

    
1811
    sc->next_chunk++;
1812

    
1813
    if(mov->next_chunk_offset < offset) { /* some meta data */
1814
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1815
        mov->next_chunk_offset = offset;
1816
    }
1817

    
1818
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1819
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1820
        mov->next_chunk_offset = offset;
1821
        offset = INT64_MAX;
1822
        goto again;
1823
    }
1824

    
1825
    /* now get the chunk size... */
1826

    
1827
    for(i=0; i<mov->total_streams; i++) {
1828
        MOVStreamContext *msc = mov->streams[i];
1829
        if ((msc->next_chunk < msc->chunk_count)
1830
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1831
            && msc->chunk_offsets[msc->next_chunk] > offset)
1832
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1833
    }
1834

    
1835
#ifdef MOV_MINOLTA_FIX
1836
    //Make sure that size is according to sample_size (Needed by .mov files
1837
    //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1838
    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1839
    //but I have no such movies
1840
    if (sc->sample_size > 0) {
1841
        int foundsize=0;
1842
        for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1843
            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1844
            {
1845
                // I can't figure out why for PCM audio sample_size is always 1
1846
                // (it should actually be channels*bits_per_second/8) but it is.
1847
                AVCodecContext* cod = s->streams[sc->ffindex]->codec;
1848
                if (sc->sample_size == 1 && (cod->codec_id == CODEC_ID_PCM_S16BE || cod->codec_id == CODEC_ID_PCM_S16LE))
1849
                    foundsize=(sc->sample_to_chunk[i].count*cod->channels*cod->bits_per_sample)/8;
1850
                else
1851
                    foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
1852
            }
1853
            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);
1854
        }
1855
        if( (foundsize>0) && (foundsize<size) )
1856
        {
1857
            size=foundsize;
1858
        }
1859
    }
1860
#endif //MOV_MINOLTA_FIX
1861

    
1862
    idx = sc->sample_to_chunk_index;
1863
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1864
        idx++;
1865
    sc->sample_to_chunk_index = idx;
1866
    /* split chunks into samples */
1867
    if (sc->sample_size == 0 || sc->sample_size > 100) {
1868
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1869
            mov->partial = sc;
1870
            /* we'll have to get those samples before next chunk */
1871
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1872
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1873
        }
1874

    
1875
        sc->current_sample++;
1876
    }else if(idx + 1 < sc->sample_to_chunk_sz){
1877
        sc->current_sample += sc->sample_size * sc->sample_to_chunk[idx].count;
1878
    }
1879

    
1880
readchunk:
1881
    dprintf("chunk: %lli -> %lli (%i)\n", offset, offset + size, size);
1882
    if(size == 0x0FFFFFFF)
1883
        size = mov->mdat_size + mov->mdat_offset - offset;
1884
    if(size < 0)
1885
        return -1;
1886
    if(size == 0)
1887
        return -1;
1888
    url_fseek(&s->pb, offset, SEEK_SET);
1889

    
1890
    av_get_packet(&s->pb, pkt, size);
1891
    pkt->stream_index = sc->ffindex;
1892

    
1893
    // If the keyframes table exists, mark any samples that are in the table as key frames.
1894
    // If no table exists, treat very sample as a key frame.
1895
    if (sc->keyframes) {
1896
        a = 0;
1897
        b = sc->keyframe_count - 1;
1898

    
1899
        while (a < b) {
1900
            m = (a + b + 1) >> 1;
1901
            if (sc->keyframes[m] > sc->current_sample) {
1902
                b = m - 1;
1903
            } else {
1904
                a = m;
1905
            }
1906
        }
1907

    
1908
        if (sc->keyframes[a] == sc->current_sample)
1909
            pkt->flags |= PKT_FLAG_KEY;
1910
    }
1911
    else
1912
        pkt->flags |= PKT_FLAG_KEY;
1913

    
1914
    mov->next_chunk_offset = offset + size;
1915

    
1916
    /* find the corresponding dts */
1917
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1918
      unsigned int count;
1919
      uint64_t dts, pts;
1920
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1921
      count = sc->stts_data[sc->sample_to_time_index].count;
1922
      if ((sc->sample_to_time_sample + count) < sc->current_sample) {
1923
        sc->sample_to_time_sample += count;
1924
        sc->sample_to_time_time   += count*duration;
1925
        sc->sample_to_time_index ++;
1926
        duration = sc->stts_data[sc->sample_to_time_index].duration;
1927
      }
1928
      dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * (int64_t)duration;
1929
        /* find the corresponding pts */
1930
        if (sc->sample_to_ctime_index < sc->ctts_count) {
1931
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1932
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1933

    
1934
            if ((sc->sample_to_ctime_sample + count) < sc->current_sample) {
1935
                sc->sample_to_ctime_sample += count;
1936
                sc->sample_to_ctime_index ++;
1937
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1938
            }
1939
            pts = dts + duration;
1940
        }else
1941
            pts = dts;
1942

    
1943
        st= s->streams[ sc->ffindex ];
1944
        assert(pts % st->time_base.num == 0);
1945
        assert(dts % st->time_base.num == 0);
1946

    
1947
        pkt->pts = pts / st->time_base.num;
1948
        pkt->dts = dts / st->time_base.num;
1949
        dprintf("stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n"
1950
                , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1951
                , sc->sample_to_time_sample
1952
                , sc->sample_to_time_time
1953
                , sc->sample_to_time_index
1954
                , sc->stts_count
1955
                , count
1956
                , duration);
1957
    }
1958

    
1959
    return 0;
1960
}
1961

    
1962
#if defined(MOV_SEEK)
1963
/**
1964
 * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1965
 */
1966
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1967
{
1968
    MOVContext* mov = (MOVContext *) s->priv_data;
1969
    MOVStreamContext* sc;
1970
    int32_t i, a, b, m;
1971
    int64_t start_time;
1972
    int32_t seek_sample, sample;
1973
    int32_t duration;
1974
    int32_t count;
1975
    int32_t chunk;
1976
    int32_t left_in_chunk;
1977
    int64_t chunk_file_offset;
1978
    int64_t sample_file_offset;
1979
    int32_t first_chunk_sample;
1980
    int32_t sample_to_chunk_idx;
1981
    int sample_to_time_index;
1982
    long sample_to_time_sample = 0;
1983
    uint64_t sample_to_time_time = 0;
1984
    int mov_idx;
1985

    
1986
    // Find the corresponding mov stream
1987
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1988
        if (mov->streams[mov_idx]->ffindex == stream_index)
1989
            break;
1990
    if (mov_idx == mov->total_streams) {
1991
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1992
        return -1;
1993
    }
1994
    sc = mov->streams[mov_idx];
1995

    
1996
    sample_time *= s->streams[stream_index]->time_base.num;
1997

    
1998
    // Step 1. Find the edit that contains the requested time (elst)
1999
    if (sc->edit_count && 0) {
2000
        // FIXME should handle edit list
2001
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
2002
        return -1;
2003
    }
2004

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

    
2010
    for (i = 0; i < sc->stts_count; i++) {
2011
        count = sc->stts_data[i].count;
2012
        duration = sc->stts_data[i].duration;
2013
        if ((start_time + count*duration) > sample_time) {
2014
            sample_to_time_time = start_time;
2015
            sample_to_time_index = i;
2016
            sample_to_time_sample = sample;
2017
            sample += (sample_time - start_time) / duration;
2018
            break;
2019
        }
2020
        sample += count;
2021
        start_time += count * duration;
2022
    }
2023
    sample_to_time_time = start_time;
2024
    sample_to_time_index = i;
2025
    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
2026
       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
2027

    
2028
    dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
2029
    if (sample > sc->sample_count) {
2030
        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);
2031
        return -1;
2032
    }
2033

    
2034
    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
2035
    if (sc->keyframes) {
2036
        a = 0;
2037
        b = sc->keyframe_count - 1;
2038
        while (a < b) {
2039
            m = (a + b + 1) >> 1;
2040
            if (sc->keyframes[m] > sample) {
2041
                b = m - 1;
2042
            } else {
2043
                a = m;
2044
            }
2045
        }
2046
        // for low latency prob: always use the previous keyframe, just uncomment the next line
2047
        // if (a) a--;
2048
        seek_sample = sc->keyframes[a];
2049
    }
2050
    else
2051
        seek_sample = sample; // else all samples are key frames
2052
    dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
2053

    
2054
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2055
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2056
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2057
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2058
            break;
2059
        first_chunk_sample += b;
2060
    }
2061
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2062
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2063
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2064
    sample_to_chunk_idx = i;
2065
    dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2066

    
2067
    // Step 5. Find the offset of the chunk using the chunk offset atom
2068
    if (!sc->chunk_offsets) {
2069
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2070
        return -1;
2071
    }
2072
    if (chunk > sc->chunk_count) {
2073
        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);
2074
        return -1;
2075
    }
2076
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
2077
    dprintf("Chunk file offset is #%llu \n", chunk_file_offset);
2078

    
2079
    // Step 6. Find the byte offset within the chunk using the sample size atom
2080
    sample_file_offset = chunk_file_offset;
2081
    if (sc->sample_size)
2082
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2083
    else {
2084
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2085
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2086
        }
2087
    }
2088
    dprintf("Sample file offset is #%llu \n", sample_file_offset);
2089

    
2090
    // Step 6. Update the parser
2091
    mov->partial = sc;
2092
    mov->next_chunk_offset = sample_file_offset;
2093
    // Update current stream state
2094
    sc->current_sample = seek_sample - 1;  // zero based
2095
    sc->left_in_chunk = left_in_chunk;
2096
    sc->next_chunk = chunk; // +1 -1 (zero based)
2097
    sc->sample_to_chunk_index = sample_to_chunk_idx;
2098

    
2099
    // Update other streams
2100
    for (i = 0; i<mov->total_streams; i++) {
2101
        MOVStreamContext *msc;
2102
        if (i == mov_idx) continue;
2103
        // Find the nearest 'next' chunk
2104
        msc = mov->streams[i];
2105
        a = 0;
2106
        b = msc->chunk_count - 1;
2107
        while (a < b) {
2108
            m = (a + b + 1) >> 1;
2109
            if (msc->chunk_offsets[m] > chunk_file_offset) {
2110
                b = m - 1;
2111
            } else {
2112
                a = m;
2113
            }
2114
        }
2115
        msc->next_chunk = a;
2116
        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2117
            msc->next_chunk ++;
2118
        dprintf("Nearest next chunk for stream #%i is #%li @%lli\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2119

    
2120
        // Compute sample count and index in the sample_to_chunk table (what a pity)
2121
        msc->sample_to_chunk_index = 0;
2122
        msc->current_sample = 0;
2123
        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2124
            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2125
            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2126
            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2127
        }
2128
        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;
2129
        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2130
        // Find corresponding position in stts (used later to compute dts)
2131
        sample = 0;
2132
        start_time = 0;
2133
        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2134
            count = msc->stts_data[msc->sample_to_time_index].count;
2135
            duration = msc->stts_data[msc->sample_to_time_index].duration;
2136
            if ((sample + count - 1) > msc->current_sample) {
2137
                msc->sample_to_time_time = start_time;
2138
                msc->sample_to_time_sample = sample;
2139
                break;
2140
            }
2141
            sample += count;
2142
            start_time += count * duration;
2143
        }
2144
        sample = 0;
2145
        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2146
            count = msc->ctts_data[msc->sample_to_ctime_index].count;
2147
            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2148
            if ((sample + count - 1) > msc->current_sample) {
2149
                msc->sample_to_ctime_sample = sample;
2150
                break;
2151
            }
2152
            sample += count;
2153
        }
2154
        dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2155
    }
2156
    return 0;
2157
}
2158
#endif
2159

    
2160
static int mov_read_close(AVFormatContext *s)
2161
{
2162
    int i;
2163
    MOVContext *mov = (MOVContext *) s->priv_data;
2164
    for(i=0; i<mov->total_streams; i++)
2165
        mov_free_stream_context(mov->streams[i]);
2166
    /* free color tabs */
2167
    for(i=0; i<mov->ctab_size; i++)
2168
        av_freep(&mov->ctab[i]);
2169
    av_freep(&mov->ctab);
2170
    return 0;
2171
}
2172

    
2173
static AVInputFormat mov_iformat = {
2174
    "mov,mp4,m4a,3gp,3g2",
2175
    "QuickTime/MPEG4 format",
2176
    sizeof(MOVContext),
2177
    mov_probe,
2178
    mov_read_header,
2179
    mov_read_packet,
2180
    mov_read_close,
2181
#if defined(MOV_SEEK)
2182
    mov_read_seek,
2183
#endif
2184
};
2185

    
2186
int mov_init(void)
2187
{
2188
    av_register_input_format(&mov_iformat);
2189
    return 0;
2190
}