Statistics
| Branch: | Revision:

ffmpeg / libavformat / mov.c @ dbb4f00a

History | View | Annotate | Download (78.1 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 (MOV_SPLIT_CHUNKS should also be defined) */
67
#define MOV_SEEK
68

    
69
/* allows chunk splitting - should work now... */
70
/* in case you can't read a file, try commenting */
71
#define MOV_SPLIT_CHUNKS
72

    
73
/* Special handling for movies created with Minolta Dimaxe Xi*/
74
/* this fix should not interfere with other .mov files, but just in case*/
75
#define MOV_MINOLTA_FIX
76

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

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

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

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

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

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

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

    
212
typedef struct MOV_sample_to_chunk_tbl {
213
    long first;
214
    long count;
215
    long id;
216
} MOV_sample_to_chunk_tbl;
217

    
218
typedef struct {
219
    uint32_t type;
220
    int64_t offset;
221
    int64_t size; /* total size (excluding the size and type fields) */
222
} MOV_atom_t;
223

    
224
typedef struct {
225
    int seed;
226
    int flags;
227
    int size;
228
    void* clrs;
229
} MOV_ctab_t;
230

    
231
typedef struct {
232
    uint8_t  version;
233
    uint32_t flags; // 24bit
234

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

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

    
270
    /* 0x05 DecSpecificDescrTag */
271
    uint8_t  decoder_cfg_len;
272
    uint8_t *decoder_cfg;
273

    
274
    /* 0x06 SLConfigDescrTag */
275
    uint8_t  sl_config_len;
276
    uint8_t *sl_config;
277
} MOV_esds_t;
278

    
279
struct MOVParseTableEntry;
280

    
281
typedef struct Time2Sample{
282
    int count;
283
    int duration;
284
}Time2Sample;
285

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

    
317
typedef struct MOVContext {
318
    int mp4; /* set to 1 as soon as we are sure that the file is an .mp4 file (even some header parsing depends on this) */
319
    AVFormatContext *fc;
320
    int time_scale;
321
    int duration; /* duration of the longest track */
322
    int found_moov; /* when both 'moov' and 'mdat' sections has been found */
323
    int found_mdat; /* we suppose we have enough data to read the file */
324
    int64_t mdat_size;
325
    int64_t mdat_offset;
326
    int ni;                                         ///< non interleaved mode
327
    int total_streams;
328
    /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio
329
     * but we need the info to be able to skip data from those streams in the 'mdat' section
330
     */
331
    MOVStreamContext *streams[MAX_STREAMS];
332

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

    
340
    AVPaletteControl palette_control;
341
} MOVContext;
342

    
343

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

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

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

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

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

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

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

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

    
425
    a.offset = atom.offset;
426

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

    
453
        a.size -= 8;
454

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

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

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

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

    
472
    return err;
473
}
474

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

    
496
    return 0;
497
}
498

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

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

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

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

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

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

    
548
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
549
    return 0;
550
}
551

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

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

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

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

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

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

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

    
628
/* this atom should contain all header atoms */
629
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
630
{
631
    int err;
632

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

    
642

    
643
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
644
{
645
    int version;
646
    int lang;
647

    
648
    version = get_byte(pb); /* version */
649
    if (version > 1)
650
        return 1; /* unsupported */
651

    
652
    get_byte(pb); get_byte(pb);
653
    get_byte(pb); /* flags */
654

    
655
    (version==1)?get_be64(pb):get_be32(pb); /* creation time */
656
    (version==1)?get_be64(pb):get_be32(pb); /* modification time */
657

    
658
    c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb);
659
    c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
660

    
661
    lang = get_be16(pb); /* language */
662
    ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
663
    get_be16(pb); /* quality */
664

    
665
    return 0;
666
}
667

    
668
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
669
{
670
    get_byte(pb); /* version */
671
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
672

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

    
682
    get_be16(pb); /* preferred volume */
683

    
684
    url_fskip(pb, 10); /* reserved */
685

    
686
    url_fskip(pb, 36); /* display matrix */
687

    
688
    get_be32(pb); /* preview time */
689
    get_be32(pb); /* preview duration */
690
    get_be32(pb); /* poster time */
691
    get_be32(pb); /* selection time */
692
    get_be32(pb); /* selection duration */
693
    get_be32(pb); /* current time */
694
    get_be32(pb); /* next track ID */
695

    
696
    return 0;
697
}
698

    
699
static int mov_read_smi(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
700
{
701
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
702

    
703
    if((uint64_t)atom.size > (1<<30))
704
        return -1;
705

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

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

    
719
    return 0;
720
}
721

    
722
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
723
{
724
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
725

    
726
    if((uint64_t)atom.size > (1<<30))
727
        return -1;
728

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

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

    
746
static int mov_read_avcC(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
747
{
748
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
749

    
750
    if((uint64_t)atom.size > (1<<30))
751
        return -1;
752

    
753
    av_free(st->codec->extradata);
754

    
755
    st->codec->extradata_size = atom.size;
756
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
757

    
758
    if (st->codec->extradata) {
759
        get_buffer(pb, st->codec->extradata, atom.size);
760
    } else
761
        url_fskip(pb, atom.size);
762

    
763
    return 0;
764
}
765

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

    
772
    get_byte(pb); /* version */
773
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
774

    
775
    entries = get_be32(pb);
776

    
777
    if(entries >= UINT_MAX/sizeof(int64_t))
778
        return -1;
779

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

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

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

    
815
    /* for palette traversal */
816
    int color_depth;
817
    int color_start;
818
    int color_count;
819
    int color_end;
820
    int color_index;
821
    int color_dec;
822
    int color_greyscale;
823
    unsigned char *color_table;
824
    int j;
825
    unsigned char r, g, b;
826

    
827
    get_byte(pb); /* version */
828
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
829

    
830
    entries = get_be32(pb);
831

    
832
    while(entries--) { //Parsing Sample description table
833
        enum CodecID id;
834
        offset_t start_pos = url_ftell(pb);
835
        int size = get_be32(pb); /* size */
836
        format = get_le32(pb); /* data format */
837

    
838
        get_be32(pb); /* reserved */
839
        get_be16(pb); /* reserved */
840
        get_be16(pb); /* index */
841

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

    
885
            st->codec->bits_per_sample = get_be16(pb); /* depth */
886
            st->codec->color_table_id = get_be16(pb); /* colortable id */
887

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

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

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

    
959
            /* figure out the palette situation */
960
            color_depth = st->codec->bits_per_sample & 0x1F;
961
            color_greyscale = st->codec->bits_per_sample & 0x20;
962

    
963
            /* if the depth is 2, 4, or 8 bpp, file is palettized */
964
            if ((color_depth == 2) || (color_depth == 4) ||
965
                (color_depth == 8)) {
966

    
967
                if (color_greyscale) {
968

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

    
982
                } else if (st->codec->color_table_id & 0x08) {
983

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

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

    
1001
                } else {
1002

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

    
1024
                st->codec->palctrl = &c->palette_control;
1025
                st->codec->palctrl->palette_changed = 1;
1026
            } else
1027
                st->codec->palctrl = NULL;
1028

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

    
1047
                //AMRSpecificBox.(10 bytes)
1048

    
1049
               get_be32(pb); //size
1050
               get_be32(pb); //type=='damr'
1051
               get_be32(pb); //vendor
1052
               get_byte(pb); //decoder version
1053
               get_be16(pb); //mode_set
1054
               get_byte(pb); //mode_change_period
1055
               get_byte(pb); //frames_per_sample
1056

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

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

    
1096
                get_be16(pb);
1097
                c->mp4=1;
1098

    
1099
                if(mp4_version==1)
1100
                {
1101
                    url_fskip(pb,16);
1102
                    a.size=size-(16+20+16);
1103
                }
1104
                else
1105
                    a.size=size-(16+20);
1106

    
1107
                a.offset=url_ftell(pb);
1108

    
1109
                mov_read_default(c, pb, a);
1110

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

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

    
1149
                st->codec->channels = get_be16(pb);             /* channel count */
1150
                st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1151

    
1152
                /* handle specific s8 codec */
1153
                get_be16(pb); /* compression id = 0*/
1154
                get_be16(pb); /* packet size = 0 */
1155

    
1156
                st->codec->sample_rate = ((get_be32(pb) >> 16));
1157

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

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

    
1205
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1206
        st->codec->sample_rate= sc->time_scale;
1207
    }
1208

    
1209
    return 0;
1210
}
1211

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

    
1218
    get_byte(pb); /* version */
1219
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1220

    
1221
    entries = get_be32(pb);
1222

    
1223
    if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1224
        return -1;
1225

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

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

    
1247
    get_byte(pb); /* version */
1248
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1249

    
1250
    entries = get_be32(pb);
1251

    
1252
    if(entries >= UINT_MAX / sizeof(long))
1253
        return -1;
1254

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

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

    
1277
    get_byte(pb); /* version */
1278
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1279

    
1280
    sc->sample_size = get_be32(pb);
1281
    entries = get_be32(pb);
1282
    if(entries >= UINT_MAX / sizeof(long))
1283
        return -1;
1284

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

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

    
1311
    get_byte(pb); /* version */
1312
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1313
    entries = get_be32(pb);
1314
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1315
        return -1;
1316

    
1317
    sc->stts_count = entries;
1318
    sc->stts_data = av_malloc(entries * sizeof(Time2Sample));
1319

    
1320
#ifdef DEBUG
1321
av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1322
#endif
1323

    
1324
    sc->time_rate=0;
1325

    
1326
    for(i=0; i<entries; i++) {
1327
        int sample_duration;
1328
        int sample_count;
1329

    
1330
        sample_count=get_be32(pb);
1331
        sample_duration = get_be32(pb);
1332
        sc->stts_data[i].count= sample_count;
1333
        sc->stts_data[i].duration= sample_duration;
1334

    
1335
        sc->time_rate= ff_gcd(sc->time_rate, sample_duration);
1336

    
1337
        dprintf("sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1338

    
1339
        duration+=sample_duration*sample_count;
1340
        total_sample_count+=sample_count;
1341
    }
1342

    
1343
    st->nb_frames= total_sample_count;
1344
    if(duration)
1345
        st->duration= duration;
1346
    return 0;
1347
}
1348

    
1349
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1350
{
1351
    unsigned int i, entries;
1352

    
1353
    get_byte(pb); /* version */
1354
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1355
    entries = get_be32(pb);
1356
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1357
        return -1;
1358

    
1359
    c->streams[c->fc->nb_streams-1]->ctts_count = entries;
1360
    c->streams[c->fc->nb_streams-1]->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1361

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

    
1364
    for(i=0; i<entries; i++) {
1365
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].count= get_be32(pb);
1366
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].duration= get_be32(pb);
1367
    }
1368
    return 0;
1369
}
1370

    
1371
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1372
{
1373
    AVStream *st;
1374
    MOVStreamContext *sc;
1375

    
1376
    st = av_new_stream(c->fc, c->fc->nb_streams);
1377
    if (!st) return -2;
1378
    sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1379
    if (!sc) {
1380
        av_free(st);
1381
        return -1;
1382
    }
1383

    
1384
    sc->sample_to_chunk_index = -1;
1385
    st->priv_data = sc;
1386
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1387
    st->start_time = 0; /* XXX: check */
1388
    c->streams[c->fc->nb_streams-1] = sc;
1389

    
1390
    return mov_read_default(c, pb, atom);
1391
}
1392

    
1393
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1394
{
1395
    AVStream *st;
1396

    
1397
    st = c->fc->streams[c->fc->nb_streams-1];
1398

    
1399
    get_byte(pb); /* version */
1400

    
1401
    get_byte(pb); get_byte(pb);
1402
    get_byte(pb); /* flags */
1403
    /*
1404
    MOV_TRACK_ENABLED 0x0001
1405
    MOV_TRACK_IN_MOVIE 0x0002
1406
    MOV_TRACK_IN_PREVIEW 0x0004
1407
    MOV_TRACK_IN_POSTER 0x0008
1408
    */
1409

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

    
1419
    get_be16(pb); /* layer */
1420
    get_be16(pb); /* alternate group */
1421
    get_be16(pb); /* volume */
1422
    get_be16(pb); /* reserved */
1423

    
1424
    url_fskip(pb, 36); /* display matrix */
1425

    
1426
    /* those are fixed-point */
1427
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1428
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1429

    
1430
    return 0;
1431
}
1432

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

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

    
1457

    
1458
#ifdef CONFIG_ZLIB
1459
static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1460
{
1461
    return -1;
1462
}
1463

    
1464
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1465
{
1466
    ByteIOContext ctx;
1467
    uint8_t *cmov_data;
1468
    uint8_t *moov_data; /* uncompressed data */
1469
    long cmov_len, moov_len;
1470
    int ret;
1471

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

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

    
1509
    return ret;
1510
}
1511
#endif
1512

    
1513
/* edit list atom */
1514
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1515
{
1516
  int i, edit_count;
1517

    
1518
  get_byte(pb); /* version */
1519
  get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1520
  edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1521

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

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

    
1610
static void mov_free_stream_context(MOVStreamContext *sc)
1611
{
1612
    if(sc) {
1613
        av_freep(&sc->chunk_offsets);
1614
        av_freep(&sc->sample_to_chunk);
1615
        av_freep(&sc->sample_sizes);
1616
        av_freep(&sc->keyframes);
1617
        av_freep(&sc->stts_data);
1618
        av_freep(&sc->ctts_data);
1619
        av_freep(&sc);
1620
    }
1621
}
1622

    
1623
static inline uint32_t mov_to_tag(uint8_t *buf)
1624
{
1625
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1626
}
1627

    
1628
static inline uint32_t to_be32(uint8_t *buf)
1629
{
1630
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1631
}
1632

    
1633
/* XXX: is it sufficient ? */
1634
static int mov_probe(AVProbeData *p)
1635
{
1636
    unsigned int offset;
1637
    uint32_t tag;
1638
    int score = 0;
1639

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

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

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

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

    
1705
    /* some cleanup : make sure we are on the mdat atom */
1706
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1707
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1708

    
1709
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1710
    mov->total_streams = nb = s->nb_streams;
1711

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

    
1725
        if(!sc->time_rate)
1726
            sc->time_rate=1;
1727
        av_set_pts_info(s->streams[i], 64, sc->time_rate, sc->time_scale);
1728

    
1729
        assert(s->streams[i]->duration % sc->time_rate == 0);
1730
        s->streams[i]->duration /= sc->time_rate;
1731

    
1732
        sc->ffindex = i;
1733
        sc->is_ff_stream = 1;
1734
    }
1735
#endif
1736
    return 0;
1737
}
1738

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

    
1753
#ifdef MOV_SPLIT_CHUNKS
1754
    if (mov->partial) {
1755
        sc = mov->partial;
1756
        idx = sc->sample_to_chunk_index;
1757

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

    
1765
        sc->current_sample++;
1766
        sc->left_in_chunk--;
1767

    
1768
        if (sc->left_in_chunk <= 0)
1769
            mov->partial = 0;
1770
        offset = mov->next_chunk_offset;
1771
        /* extract the sample */
1772

    
1773
        goto readchunk;
1774
    }
1775
#endif
1776

    
1777
again:
1778
    sc = 0;
1779
    if(offset == INT64_MAX)
1780
        best_dts= INT64_MAX;
1781
    for(i=0; i<mov->total_streams; i++) {
1782
        MOVStreamContext *msc = mov->streams[i];
1783

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

    
1817
    sc->next_chunk++;
1818

    
1819
    if(mov->next_chunk_offset < offset) { /* some meta data */
1820
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1821
        mov->next_chunk_offset = offset;
1822
    }
1823

    
1824
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1825
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1826
        mov->next_chunk_offset = offset;
1827
        offset = INT64_MAX;
1828
        goto again;
1829
    }
1830

    
1831
    /* now get the chunk size... */
1832

    
1833
    for(i=0; i<mov->total_streams; i++) {
1834
        MOVStreamContext *msc = mov->streams[i];
1835
        if ((msc->next_chunk < msc->chunk_count)
1836
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1837
            && msc->chunk_offsets[msc->next_chunk] > offset)
1838
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1839
    }
1840

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

    
1868
    idx = sc->sample_to_chunk_index;
1869
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1870
        idx++;
1871
    sc->sample_to_chunk_index = idx;
1872
#ifdef MOV_SPLIT_CHUNKS
1873
    /* split chunks into samples */
1874
    if (sc->sample_size == 0 || sc->sample_size > 100) {
1875
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1876
            mov->partial = sc;
1877
            /* we'll have to get those samples before next chunk */
1878
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1879
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1880
        }
1881

    
1882
        sc->current_sample++;
1883
    }else if(idx + 1 < sc->sample_to_chunk_sz){
1884
        sc->current_sample += sc->sample_size * sc->sample_to_chunk[idx].count;
1885
    }
1886
#endif
1887

    
1888
readchunk:
1889
    dprintf("chunk: %lli -> %lli (%i)\n", offset, offset + size, size);
1890
    if(size == 0x0FFFFFFF)
1891
        size = mov->mdat_size + mov->mdat_offset - offset;
1892
    if(size < 0)
1893
        return -1;
1894
    if(size == 0)
1895
        return -1;
1896
    url_fseek(&s->pb, offset, SEEK_SET);
1897

    
1898
    av_get_packet(&s->pb, pkt, size);
1899
    pkt->stream_index = sc->ffindex;
1900

    
1901
    // If the keyframes table exists, mark any samples that are in the table as key frames.
1902
    // If no table exists, treat very sample as a key frame.
1903
    if (sc->keyframes) {
1904
        a = 0;
1905
        b = sc->keyframe_count - 1;
1906

    
1907
        while (a < b) {
1908
            m = (a + b + 1) >> 1;
1909
            if (sc->keyframes[m] > sc->current_sample) {
1910
                b = m - 1;
1911
            } else {
1912
                a = m;
1913
            }
1914
        }
1915

    
1916
        if (sc->keyframes[a] == sc->current_sample)
1917
            pkt->flags |= PKT_FLAG_KEY;
1918
    }
1919
    else
1920
        pkt->flags |= PKT_FLAG_KEY;
1921

    
1922
    mov->next_chunk_offset = offset + size;
1923

    
1924
    /* find the corresponding dts */
1925
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1926
      unsigned int count;
1927
      uint64_t dts, pts;
1928
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1929
      count = sc->stts_data[sc->sample_to_time_index].count;
1930
      if ((sc->sample_to_time_sample + count) < sc->current_sample) {
1931
        sc->sample_to_time_sample += count;
1932
        sc->sample_to_time_time   += count*duration;
1933
        sc->sample_to_time_index ++;
1934
        duration = sc->stts_data[sc->sample_to_time_index].duration;
1935
      }
1936
      dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * (int64_t)duration;
1937
        /* find the corresponding pts */
1938
        if (sc->sample_to_ctime_index < sc->ctts_count) {
1939
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1940
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1941

    
1942
            if ((sc->sample_to_ctime_sample + count) < sc->current_sample) {
1943
                sc->sample_to_ctime_sample += count;
1944
                sc->sample_to_ctime_index ++;
1945
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1946
            }
1947
            pts = dts + duration;
1948
        }else
1949
            pts = dts;
1950

    
1951
        st= s->streams[ sc->ffindex ];
1952
        assert(pts % st->time_base.num == 0);
1953
        assert(dts % st->time_base.num == 0);
1954

    
1955
        pkt->pts = pts / st->time_base.num;
1956
        pkt->dts = dts / st->time_base.num;
1957
        dprintf("stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n"
1958
                , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1959
                , sc->sample_to_time_sample
1960
                , sc->sample_to_time_time
1961
                , sc->sample_to_time_index
1962
                , sc->stts_count
1963
                , count
1964
                , duration);
1965
    }
1966

    
1967
    return 0;
1968
}
1969

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

    
1994
    // Find the corresponding mov stream
1995
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1996
        if (mov->streams[mov_idx]->ffindex == stream_index)
1997
            break;
1998
    if (mov_idx == mov->total_streams) {
1999
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
2000
        return -1;
2001
    }
2002
    sc = mov->streams[mov_idx];
2003

    
2004
    sample_time *= s->streams[stream_index]->time_base.num;
2005

    
2006
    // Step 1. Find the edit that contains the requested time (elst)
2007
    if (sc->edit_count && 0) {
2008
        // FIXME should handle edit list
2009
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
2010
        return -1;
2011
    }
2012

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

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

    
2036
    dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
2037
    if (sample > sc->sample_count) {
2038
        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);
2039
        return -1;
2040
    }
2041

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

    
2062
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2063
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2064
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2065
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2066
            break;
2067
        first_chunk_sample += b;
2068
    }
2069
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2070
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2071
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2072
    sample_to_chunk_idx = i;
2073
    dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2074

    
2075
    // Step 5. Find the offset of the chunk using the chunk offset atom
2076
    if (!sc->chunk_offsets) {
2077
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2078
        return -1;
2079
    }
2080
    if (chunk > sc->chunk_count) {
2081
        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);
2082
        return -1;
2083
    }
2084
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
2085
    dprintf("Chunk file offset is #%llu \n", chunk_file_offset);
2086

    
2087
    // Step 6. Find the byte offset within the chunk using the sample size atom
2088
    sample_file_offset = chunk_file_offset;
2089
    if (sc->sample_size)
2090
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2091
    else {
2092
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2093
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2094
        }
2095
    }
2096
    dprintf("Sample file offset is #%llu \n", sample_file_offset);
2097

    
2098
    // Step 6. Update the parser
2099
    mov->partial = sc;
2100
    mov->next_chunk_offset = sample_file_offset;
2101
    // Update current stream state
2102
    sc->current_sample = seek_sample - 1;  // zero based
2103
    sc->left_in_chunk = left_in_chunk;
2104
    sc->next_chunk = chunk; // +1 -1 (zero based)
2105
    sc->sample_to_chunk_index = sample_to_chunk_idx;
2106

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

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

    
2168
static int mov_read_close(AVFormatContext *s)
2169
{
2170
    int i;
2171
    MOVContext *mov = (MOVContext *) s->priv_data;
2172
    for(i=0; i<mov->total_streams; i++)
2173
        mov_free_stream_context(mov->streams[i]);
2174
    /* free color tabs */
2175
    for(i=0; i<mov->ctab_size; i++)
2176
        av_freep(&mov->ctab[i]);
2177
    av_freep(&mov->ctab);
2178
    return 0;
2179
}
2180

    
2181
static AVInputFormat mov_iformat = {
2182
    "mov,mp4,m4a,3gp,3g2",
2183
    "QuickTime/MPEG4 format",
2184
    sizeof(MOVContext),
2185
    mov_probe,
2186
    mov_read_header,
2187
    mov_read_packet,
2188
    mov_read_close,
2189
#if defined(MOV_SPLIT_CHUNKS) && defined(MOV_SEEK)
2190
    mov_read_seek,
2191
#endif
2192
};
2193

    
2194
int mov_init(void)
2195
{
2196
    av_register_input_format(&mov_iformat);
2197
    return 0;
2198
}