Statistics
| Branch: | Revision:

ffmpeg / libavformat / mov.c @ ab561df9

History | View | Annotate | Download (83.3 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18
 */
19

    
20
#include <limits.h>
21

    
22
#include "avformat.h"
23
#include "avi.h"
24

    
25
#ifdef CONFIG_ZLIB
26
#include <zlib.h>
27
#endif
28

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

    
57
//#define DEBUG
58
#ifdef DEBUG
59
#include <stdio.h>
60
#include <fcntl.h>
61
#endif
62

    
63
#include "qtpalette.h"
64

    
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
static const CodecTag mov_video_tags[] = {
83
/*  { CODEC_ID_, MKTAG('c', 'v', 'i', 'd') }, *//* Cinepak */
84
/*  { CODEC_ID_H263, MKTAG('r', 'a', 'w', ' ') }, *//* Uncompressed RGB */
85
/*  { CODEC_ID_H263, MKTAG('Y', 'u', 'v', '2') }, *//* Uncompressed YUV422 */
86
/*    { CODEC_ID_RAWVIDEO, MKTAG('A', 'V', 'U', 'I') }, *//* YUV with alpha-channel (AVID Uncompressed) */
87
/* Graphics */
88
/* Animation */
89
/* Apple video */
90
/* Kodak Photo CD */
91
    { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */
92
    { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
93
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */
94
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */
95
    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */
96
/*    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */
97
/*    { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, *//* embedded gif files as frames (usually one "click to play movie" frame) */
98
/* Sorenson video */
99
    { CODEC_ID_SVQ1, MKTAG('S', 'V', 'Q', '1') }, /* Sorenson Video v1 */
100
    { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', '1') }, /* Sorenson Video v1 */
101
    { CODEC_ID_SVQ1, MKTAG('s', 'v', 'q', 'i') }, /* Sorenson Video v1 (from QT specs)*/
102
    { CODEC_ID_SVQ3, MKTAG('S', 'V', 'Q', '3') }, /* Sorenson Video v3 */
103
    { CODEC_ID_MPEG4, MKTAG('m', 'p', '4', 'v') },
104
    { CODEC_ID_MPEG4, MKTAG('D', 'I', 'V', 'X') }, /* OpenDiVX *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
105
    { CODEC_ID_MPEG4, MKTAG('X', 'V', 'I', 'D') },
106
    { CODEC_ID_MPEG4, MKTAG('3', 'I', 'V', '2') }, /* experimental: 3IVX files before ivx D4 4.5.1 */
107
/*    { CODEC_ID_, MKTAG('I', 'V', '5', '0') }, *//* Indeo 5.0 */
108
    { CODEC_ID_H263, MKTAG('h', '2', '6', '3') }, /* H263 */
109
    { CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H263 ?? works */
110
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */
111
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */
112
/*    { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, *//* AVID dv */
113
    { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */
114
    { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */
115
    { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */
116
    { CODEC_ID_8BPS, MKTAG('8', 'B', 'P', 'S') }, /* Planar RGB (8BPS) */
117
    { CODEC_ID_SMC, MKTAG('s', 'm', 'c', ' ') }, /* Apple Graphics (SMC) */
118
    { CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, /* Apple Animation (RLE) */
119
    { CODEC_ID_QDRAW, MKTAG('q', 'd', 'r', 'w') }, /* QuickDraw */
120
    { CODEC_ID_H264, MKTAG('a', 'v', 'c', '1') }, /* AVC-1/H.264 */
121
    { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 produced by Sony HD camera */
122
    { CODEC_ID_NONE, 0 },
123
};
124

    
125
static const CodecTag mov_audio_tags[] = {
126
/*    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */
127
    { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
128
    /* { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') },*/ /* 8 bits */
129
    { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
130
    { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /*  */
131
    { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /*  */
132
    { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /*  */
133
    { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */
134
    { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */
135
    { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */
136

    
137
    { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */
138
    { CODEC_ID_MP2, 0x6D730055 }, /* MPEG layer 3 */
139
    { CODEC_ID_MP2, 0x5500736D }, /* MPEG layer 3 *//* XXX: check endianness */
140
/*    { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
141
/* MP4 tags */
142
    { CODEC_ID_AAC, MKTAG('m', 'p', '4', 'a') }, /* MPEG-4 AAC */
143
    /* The standard for mpeg4 audio is still not normalised AFAIK anyway */
144
    { CODEC_ID_AMR_NB, MKTAG('s', 'a', 'm', 'r') }, /* AMR-NB 3gp */
145
    { CODEC_ID_AMR_WB, MKTAG('s', 'a', 'w', 'b') }, /* AMR-WB 3gp */
146
    { CODEC_ID_AC3, MKTAG('m', 's', 0x20, 0x00) }, /* Dolby AC-3 */
147
    { CODEC_ID_ALAC,MKTAG('a', 'l', 'a', 'c') }, /* Apple Lossless */
148
    { CODEC_ID_QDM2,MKTAG('Q', 'D', 'M', '2') }, /* QDM2 */
149
    { CODEC_ID_NONE, 0 },
150
};
151

    
152
/* map numeric codes from mdhd atom to ISO 639 */
153
/* cf. QTFileFormat.pdf p253, qtff.pdf p205 */
154
/* http://developer.apple.com/documentation/mac/Text/Text-368.html */
155
/* deprecated by putting the code as 3*5bit ascii */
156
static const char *mov_mdhd_language_map[] = { 
157
/* 0-9 */
158
"eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor", 
159
"heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/, 
160
"urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav",  NULL, 
161
"fo ",  NULL, "rus", "chi",  NULL, "iri", "alb", "ron", "ces", "slk", 
162
"slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
163
/*?*/ 
164
"aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon",  NULL, "pus",
165
"kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
166
"pa ", "ori", "mal", "kan", "tam", "tel",  NULL, "bur", "khm", "lao",
167
/*                   roman? arabic? */
168
"vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
169
/*==rundi?*/
170
 NULL, "run",  NULL, "mlg", "epo",  NULL,  NULL,  NULL,  NULL,  NULL, 
171
/* 100 */
172
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, 
173
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, 
174
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, "wel", "baq",
175
"cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
176
};
177

    
178
/* the QuickTime file format is quite convoluted...
179
 * it has lots of index tables, each indexing something in another one...
180
 * Here we just use what is needed to read the chunks
181
 */
182

    
183
typedef struct MOV_sample_to_chunk_tbl {
184
    long first;
185
    long count;
186
    long id;
187
} MOV_sample_to_chunk_tbl;
188

    
189
typedef struct {
190
    uint32_t type;
191
    int64_t offset;
192
    int64_t size; /* total size (excluding the size and type fields) */
193
} MOV_atom_t;
194

    
195
typedef struct {
196
    int seed;
197
    int flags;
198
    int size;
199
    void* clrs;
200
} MOV_ctab_t;
201

    
202
typedef struct {
203
    uint8_t  version;
204
    uint32_t flags; // 24bit
205

    
206
    /* 0x03 ESDescrTag */
207
    uint16_t es_id;
208
#define MP4ODescrTag                    0x01
209
#define MP4IODescrTag                   0x02
210
#define MP4ESDescrTag                   0x03
211
#define MP4DecConfigDescrTag            0x04
212
#define MP4DecSpecificDescrTag          0x05
213
#define MP4SLConfigDescrTag             0x06
214
#define MP4ContentIdDescrTag            0x07
215
#define MP4SupplContentIdDescrTag       0x08
216
#define MP4IPIPtrDescrTag               0x09
217
#define MP4IPMPPtrDescrTag              0x0A
218
#define MP4IPMPDescrTag                 0x0B
219
#define MP4RegistrationDescrTag         0x0D
220
#define MP4ESIDIncDescrTag              0x0E
221
#define MP4ESIDRefDescrTag              0x0F
222
#define MP4FileIODescrTag               0x10
223
#define MP4FileODescrTag                0x11
224
#define MP4ExtProfileLevelDescrTag      0x13
225
#define MP4ExtDescrTagsStart            0x80
226
#define MP4ExtDescrTagsEnd              0xFE
227
    uint8_t  stream_priority;
228

    
229
    /* 0x04 DecConfigDescrTag */
230
    uint8_t  object_type_id;
231
    uint8_t  stream_type;
232
    /* XXX: really streamType is
233
     * only 6bit, followed by:
234
     * 1bit  upStream
235
     * 1bit  reserved
236
     */
237
    uint32_t buffer_size_db; // 24
238
    uint32_t max_bitrate;
239
    uint32_t avg_bitrate;
240

    
241
    /* 0x05 DecSpecificDescrTag */
242
    uint8_t  decoder_cfg_len;
243
    uint8_t *decoder_cfg;
244

    
245
    /* 0x06 SLConfigDescrTag */
246
    uint8_t  sl_config_len;
247
    uint8_t *sl_config;
248
} MOV_esds_t;
249

    
250
struct MOVParseTableEntry;
251

    
252
typedef struct Time2Sample{
253
    int count;
254
    int duration;
255
}Time2Sample;
256

    
257
typedef struct MOVStreamContext {
258
    int ffindex; /* the ffmpeg stream id */
259
    int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */
260
    long next_chunk;
261
    long chunk_count;
262
    int64_t *chunk_offsets;
263
    int stts_count;
264
    Time2Sample *stts_data;
265
    int ctts_count;
266
    Time2Sample *ctts_data;
267
    int edit_count;             /* number of 'edit' (elst atom) */
268
    long sample_to_chunk_sz;
269
    MOV_sample_to_chunk_tbl *sample_to_chunk;
270
    long sample_to_chunk_index;
271
    int sample_to_time_index;
272
    long sample_to_time_sample;
273
    uint64_t sample_to_time_time;
274
    int sample_to_ctime_index;
275
    int sample_to_ctime_sample;
276
    long sample_size;
277
    long sample_count;
278
    long *sample_sizes;
279
    long keyframe_count;
280
    long *keyframes;
281
    int time_scale;
282
    long current_sample;
283
    long left_in_chunk; /* how many samples before next chunk */
284
    MOV_esds_t esds;
285
} MOVStreamContext;
286

    
287
typedef struct MOVContext {
288
    int mp4; /* set to 1 as soon as we are sure that the file is an .mp4 file (even some header parsing depends on this) */
289
    AVFormatContext *fc;
290
    int time_scale;
291
    int duration; /* duration of the longest track */
292
    int found_moov; /* when both 'moov' and 'mdat' sections has been found */
293
    int found_mdat; /* we suppose we have enough data to read the file */
294
    int64_t mdat_size;
295
    int64_t mdat_offset;
296
    int ni;                                         ///< non interleaved mode
297
    int total_streams;
298
    /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio
299
     * but we need the info to be able to skip data from those streams in the 'mdat' section
300
     */
301
    MOVStreamContext *streams[MAX_STREAMS];
302

    
303
    int64_t next_chunk_offset;
304
    MOVStreamContext *partial; /* != 0 : there is still to read in the current chunk */
305
    int ctab_size;
306
    MOV_ctab_t **ctab;           /* color tables */
307
    const struct MOVParseTableEntry *parse_table; /* could be eventually used to change the table */
308
    /* NOTE: for recursion save to/ restore from local variable! */
309

    
310
    AVPaletteControl palette_control;
311
} MOVContext;
312

    
313

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

    
316
/* those functions parse an atom */
317
/* return code:
318
 1: found what I wanted, exit
319
 0: continue to parse next atom
320
 -1: error occured, exit
321
 */
322
typedef int (*mov_parse_function)(MOVContext *ctx, ByteIOContext *pb, MOV_atom_t atom);
323

    
324
/* links atom IDs to parse functions */
325
typedef struct MOVParseTableEntry {
326
    uint32_t type;
327
    mov_parse_function func;
328
} MOVParseTableEntry;
329

    
330
#ifdef DEBUG
331
/*
332
 * XXX: static sux, even more in a multithreaded environment...
333
 * Avoid them. This is here just to help debugging.
334
 */
335
static int debug_indent = 0;
336
void print_atom(const char *str, MOV_atom_t atom)
337
{
338
    unsigned int tag, i;
339
    tag = (unsigned int) atom.type;
340
    i=debug_indent;
341
    if(tag == 0) tag = MKTAG('N', 'U', 'L', 'L');
342
    while(i--)
343
        av_log(NULL, AV_LOG_DEBUG, "|");
344
    av_log(NULL, AV_LOG_DEBUG, "parse:");
345
    av_log(NULL, AV_LOG_DEBUG, " %s: tag=%c%c%c%c offset=0x%x size=0x%x\n",
346
           str, tag & 0xff,
347
           (tag >> 8) & 0xff,
348
           (tag >> 16) & 0xff,
349
           (tag >> 24) & 0xff,
350
           (unsigned int)atom.offset,
351
           (unsigned int)atom.size);
352
    assert((unsigned int)atom.size < 0x7fffffff);// catching errors
353
}
354
#else
355
#define print_atom(a,b)
356
#endif
357

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

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

    
408
static int mov_read_leaf(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
409
{
410
    print_atom("leaf", 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
#ifdef DEBUG
426
    print_atom("default", atom);
427
    debug_indent++;
428
#endif
429

    
430
    a.offset = atom.offset;
431

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

    
458
        a.size -= 8;
459

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

    
463
//        av_log(NULL, AV_LOG_DEBUG, " i=%ld\n", i);
464
        if (c->parse_table[i].type == 0) { /* skip leaf atoms data */
465
//            url_seek(pb, atom.offset+atom.size, SEEK_SET);
466
#ifdef DEBUG
467
            print_atom("unknown", a);
468
#endif
469
            url_fskip(pb, a.size);
470
        } else {
471
#ifdef DEBUG
472
            //char b[5] = { type & 0xff, (type >> 8) & 0xff, (type >> 16) & 0xff, (type >> 24) & 0xff, 0 };
473
            //print_atom(b, type, offset, size);
474
#endif
475
            err = (c->parse_table[i].func)(c, pb, a);
476
        }
477

    
478
        a.offset += a.size;
479
        total_size += a.size;
480
    }
481

    
482
    if (!err && total_size < atom.size && atom.size < 0x7ffff) {
483
        //av_log(NULL, AV_LOG_DEBUG, "RESET  %Ld  %Ld  err:%d\n", atom.size, total_size, err);
484
        url_fskip(pb, atom.size - total_size);
485
    }
486

    
487
#ifdef DEBUG
488
    debug_indent--;
489
#endif
490
    return err;
491
}
492

    
493
static int mov_read_ctab(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
494
{
495
#if 1
496
    url_fskip(pb, atom.size); // for now
497
#else
498
    VERY VERY BROKEN, NEVER execute this, needs rewrite
499
    unsigned int len;
500
    MOV_ctab_t *t;
501
    c->ctab = av_realloc(c->ctab, ++c->ctab_size);
502
    t = c->ctab[c->ctab_size];
503
    t->seed = get_be32(pb);
504
    t->flags = get_be16(pb);
505
    t->size = get_be16(pb) + 1;
506
    len = 2 * t->size * 4;
507
    if (len > 0) {
508
        t->clrs = av_malloc(len); // 16bit A R G B
509
        if (t->clrs)
510
            get_buffer(pb, t->clrs, len);
511
    }
512
#endif
513

    
514
    return 0;
515
}
516

    
517
static int mov_read_hdlr(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
518
{
519
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
520
    int len = 0;
521
    uint32_t type;
522
    uint32_t ctype;
523

    
524
    print_atom("hdlr", atom);
525

    
526
    get_byte(pb); /* version */
527
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
528

    
529
    /* component type */
530
    ctype = get_le32(pb);
531
    type = get_le32(pb); /* component subtype */
532

    
533
#ifdef DEBUG
534
    av_log(NULL, AV_LOG_DEBUG, "ctype= %c%c%c%c (0x%08lx)\n", *((char *)&ctype), ((char *)&ctype)[1], ((char *)&ctype)[2], ((char *)&ctype)[3], (long) ctype);
535
    av_log(NULL, AV_LOG_DEBUG, "stype= %c%c%c%c\n", *((char *)&type), ((char *)&type)[1], ((char *)&type)[2], ((char *)&type)[3]);
536
#endif
537
#ifdef DEBUG
538
/* XXX: yeah this is ugly... */
539
    if(ctype == MKTAG('m', 'h', 'l', 'r')) { /* MOV */
540
        if(type == MKTAG('v', 'i', 'd', 'e'))
541
            puts("hdlr: vide");
542
        else if(type == MKTAG('s', 'o', 'u', 'n'))
543
            puts("hdlr: soun");
544
    } else if(ctype == 0) { /* MP4 */
545
        if(type == MKTAG('v', 'i', 'd', 'e'))
546
            puts("hdlr: vide");
547
        else if(type == MKTAG('s', 'o', 'u', 'n'))
548
            puts("hdlr: soun");
549
        else if(type == MKTAG('o', 'd', 's', 'm'))
550
            puts("hdlr: odsm");
551
        else if(type == MKTAG('s', 'd', 's', 'm'))
552
            puts("hdlr: sdsm");
553
    } else puts("hdlr: meta");
554
#endif
555

    
556
    if(ctype == MKTAG('m', 'h', 'l', 'r')) { /* MOV */
557
        /* helps parsing the string hereafter... */
558
        c->mp4 = 0;
559
        if(type == MKTAG('v', 'i', 'd', 'e'))
560
            st->codec->codec_type = CODEC_TYPE_VIDEO;
561
        else if(type == MKTAG('s', 'o', 'u', 'n'))
562
            st->codec->codec_type = CODEC_TYPE_AUDIO;
563
    } else if(ctype == 0) { /* MP4 */
564
        /* helps parsing the string hereafter... */
565
        c->mp4 = 1;
566
        if(type == MKTAG('v', 'i', 'd', 'e'))
567
            st->codec->codec_type = CODEC_TYPE_VIDEO;
568
        else if(type == MKTAG('s', 'o', 'u', 'n'))
569
            st->codec->codec_type = CODEC_TYPE_AUDIO;
570
    }
571
    get_be32(pb); /* component  manufacture */
572
    get_be32(pb); /* component flags */
573
    get_be32(pb); /* component flags mask */
574

    
575
    if(atom.size <= 24)
576
        return 0; /* nothing left to read */
577
    /* XXX: MP4 uses a C string, not a pascal one */
578
    /* component name */
579

    
580
    if(c->mp4) {
581
        /* .mp4: C string */
582
        while(get_byte(pb) && (++len < (atom.size - 24)));
583
    } else {
584
        /* .mov: PASCAL string */
585
#ifdef DEBUG
586
        char* buf;
587
#endif
588
        len = get_byte(pb);
589
#ifdef DEBUG
590
        buf = (uint8_t*) av_malloc(len+1);
591
        if (buf) {
592
            get_buffer(pb, buf, len);
593
            buf[len] = '\0';
594
            av_log(NULL, AV_LOG_DEBUG, "**buf='%s'\n", buf);
595
            av_free(buf);
596
        } else
597
#endif
598
            url_fskip(pb, len);
599
    }
600

    
601
    url_fskip(pb, atom.size - (url_ftell(pb) - atom.offset));
602
    return 0;
603
}
604

    
605
static int mov_mp4_read_descr_len(ByteIOContext *pb)
606
{
607
    int len = 0;
608
    int count = 4;
609
    while (count--) {
610
        int c = get_byte(pb);
611
        len = (len << 7) | (c & 0x7f);
612
        if (!(c & 0x80))
613
            break;
614
    }
615
    return len;
616
}
617

    
618
static int mov_mp4_read_descr(ByteIOContext *pb, int *tag)
619
{
620
    int len;
621
    *tag = get_byte(pb);
622
    len = mov_mp4_read_descr_len(pb);
623
#ifdef DEBUG
624
    av_log(NULL, AV_LOG_DEBUG, "MPEG4 description: tag=0x%02x len=%d\n", *tag, len);
625
#endif
626
    return len;
627
}
628

    
629
static int mov_read_esds(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
630
{
631
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
632
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
633
    int64_t start_pos = url_ftell(pb);
634
    int tag, len;
635

    
636
    print_atom("esds", atom);
637

    
638
    /* Well, broken but suffisant for some MP4 streams */
639
    get_be32(pb); /* version + flags */
640
    len = mov_mp4_read_descr(pb, &tag);
641
    if (tag == MP4ESDescrTag) {
642
        get_be16(pb); /* ID */
643
        get_byte(pb); /* priority */
644
    } else
645
        get_be16(pb); /* ID */
646

    
647
    len = mov_mp4_read_descr(pb, &tag);
648
    if (tag == MP4DecConfigDescrTag) {
649
        sc->esds.object_type_id = get_byte(pb);
650
        sc->esds.stream_type = get_byte(pb);
651
        sc->esds.buffer_size_db = get_be24(pb);
652
        sc->esds.max_bitrate = get_be32(pb);
653
        sc->esds.avg_bitrate = get_be32(pb);
654

    
655
        len = mov_mp4_read_descr(pb, &tag);
656
        //av_log(NULL, AV_LOG_DEBUG, "LEN %d  TAG %d  m:%d a:%d\n", len, tag, sc->esds.max_bitrate, sc->esds.avg_bitrate);
657
        if (tag == MP4DecSpecificDescrTag) {
658
#ifdef DEBUG
659
            av_log(NULL, AV_LOG_DEBUG, "Specific MPEG4 header len=%d\n", len);
660
#endif
661
            st->codec->extradata = (uint8_t*) av_mallocz(len + FF_INPUT_BUFFER_PADDING_SIZE);
662
            if (st->codec->extradata) {
663
                get_buffer(pb, st->codec->extradata, len);
664
                st->codec->extradata_size = len;
665
            }
666
        }
667
    }
668
    /* in any case, skip garbage */
669
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
670
    return 0;
671
}
672

    
673
/* this atom contains actual media data */
674
static int mov_read_mdat(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
675
{
676
    print_atom("mdat", atom);
677

    
678
    if(atom.size == 0) /* wrong one (MP4) */
679
        return 0;
680
    c->found_mdat=1;
681
    c->mdat_offset = atom.offset;
682
    c->mdat_size = atom.size;
683
    if(c->found_moov)
684
        return 1; /* found both, just go */
685
    url_fskip(pb, atom.size);
686
    return 0; /* now go for moov */
687
}
688

    
689
/* this atom should contain all header atoms */
690
static int mov_read_moov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
691
{
692
    int err;
693

    
694
    print_atom("moov", atom);
695

    
696
    err = mov_read_default(c, pb, atom);
697
    /* we parsed the 'moov' atom, we can terminate the parsing as soon as we find the 'mdat' */
698
    /* so we don't parse the whole file if over a network */
699
    c->found_moov=1;
700
    if(c->found_mdat)
701
        return 1; /* found both, just go */
702
    return 0; /* now go for mdat */
703
}
704

    
705

    
706
static int mov_read_mdhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
707
{
708
    int version;
709
    int lang;
710
    print_atom("mdhd", atom);
711

    
712
    version = get_byte(pb); /* version */
713
    if (version > 1)
714
        return 1; /* unsupported */
715

    
716
    get_byte(pb); get_byte(pb);
717
    get_byte(pb); /* flags */
718

    
719
    (version==1)?get_be64(pb):get_be32(pb); /* creation time */
720
    (version==1)?get_be64(pb):get_be32(pb); /* modification time */
721

    
722
    c->streams[c->fc->nb_streams-1]->time_scale = get_be32(pb);
723
    av_set_pts_info(c->fc->streams[c->fc->nb_streams-1], 64, 1, c->streams[c->fc->nb_streams-1]->time_scale);
724

    
725
#ifdef DEBUG
726
    av_log(NULL, AV_LOG_DEBUG, "track[%i].time_scale = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->time_scale); /* time scale */
727
#endif
728
    c->fc->streams[c->fc->nb_streams-1]->duration = (version==1)?get_be64(pb):get_be32(pb); /* duration */
729

    
730
    lang = get_be16(pb); /* language */
731
    ff_mov_lang_to_iso639(lang, c->fc->streams[c->fc->nb_streams-1]->language);
732
    get_be16(pb); /* quality */
733

    
734
    return 0;
735
}
736

    
737
static int mov_read_mvhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
738
{
739
    print_atom("mvhd", atom);
740

    
741
    get_byte(pb); /* version */
742
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
743

    
744
    get_be32(pb); /* creation time */
745
    get_be32(pb); /* modification time */
746
    c->time_scale = get_be32(pb); /* time scale */
747
#ifdef DEBUG
748
    av_log(NULL, AV_LOG_DEBUG, "time scale = %i\n", c->time_scale);
749
#endif
750
    c->duration = get_be32(pb); /* duration */
751
    get_be32(pb); /* preferred scale */
752

    
753
    get_be16(pb); /* preferred volume */
754

    
755
    url_fskip(pb, 10); /* reserved */
756

    
757
    url_fskip(pb, 36); /* display matrix */
758

    
759
    get_be32(pb); /* preview time */
760
    get_be32(pb); /* preview duration */
761
    get_be32(pb); /* poster time */
762
    get_be32(pb); /* selection time */
763
    get_be32(pb); /* selection duration */
764
    get_be32(pb); /* current time */
765
    get_be32(pb); /* next track ID */
766

    
767
    return 0;
768
}
769

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

    
774
    if((uint64_t)atom.size > (1<<30))
775
        return -1;
776

    
777
    // currently SVQ3 decoder expect full STSD header - so let's fake it
778
    // this should be fixed and just SMI header should be passed
779
    av_free(st->codec->extradata);
780
    st->codec->extradata_size = 0x5a + atom.size;
781
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
782

    
783
    if (st->codec->extradata) {
784
        strcpy(st->codec->extradata, "SVQ3"); // fake
785
        get_buffer(pb, st->codec->extradata + 0x5a, atom.size);
786
        //av_log(NULL, AV_LOG_DEBUG, "Reading SMI %Ld  %s\n", atom.size, (char*)st->codec->extradata + 0x5a);
787
    } else
788
        url_fskip(pb, atom.size);
789

    
790
    return 0;
791
}
792

    
793
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
794
{
795
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
796

    
797
    if((uint64_t)atom.size > (1<<30))
798
        return -1;
799

    
800
    // pass all frma atom to codec, needed at least for QDM2
801
    av_free(st->codec->extradata);
802
    st->codec->extradata_size = atom.size;
803
    st->codec->extradata = (uint8_t*) av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
804

    
805
    if (st->codec->extradata) {
806
        get_buffer(pb, st->codec->extradata, atom.size);
807
        //av_log(NULL, AV_LOG_DEBUG, "Reading frma %Ld  %s\n", atom.size, (char*)st->codec->extradata);
808
    } else
809
        url_fskip(pb, atom.size);
810

    
811
    return 0;
812
}
813

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

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

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

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

    
826
    if (st->codec->extradata) {
827
        get_buffer(pb, st->codec->extradata, atom.size);
828
    } else
829
        url_fskip(pb, atom.size);
830

    
831
    return 0;
832
}
833

    
834
static int mov_read_stco(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
835
{
836
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
837
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
838
    unsigned int i, entries;
839

    
840
    print_atom("stco", atom);
841

    
842
    get_byte(pb); /* version */
843
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
844

    
845
    entries = get_be32(pb);
846

    
847
    if(entries >= UINT_MAX/sizeof(int64_t))
848
        return -1;
849

    
850
    sc->chunk_count = entries;
851
    sc->chunk_offsets = (int64_t*) av_malloc(entries * sizeof(int64_t));
852
    if (!sc->chunk_offsets)
853
        return -1;
854
    if (atom.type == MKTAG('s', 't', 'c', 'o')) {
855
        for(i=0; i<entries; i++) {
856
            sc->chunk_offsets[i] = get_be32(pb);
857
        }
858
    } else if (atom.type == MKTAG('c', 'o', '6', '4')) {
859
        for(i=0; i<entries; i++) {
860
            sc->chunk_offsets[i] = get_be64(pb);
861
        }
862
    } else
863
        return -1;
864

    
865
    for(i=0; i<c->fc->nb_streams; i++){
866
        MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
867
        if(sc2 && sc2->chunk_offsets){
868
            int64_t first= sc2->chunk_offsets[0];
869
            int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
870
            if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
871
                c->ni=1;
872
        }
873
    }
874
#ifdef DEBUG
875
/*
876
    for(i=0; i<entries; i++) {
877
        av_log(NULL, AV_LOG_DEBUG, "chunk offset=0x%Lx\n", sc->chunk_offsets[i]);
878
    }
879
*/
880
#endif
881
    return 0;
882
}
883

    
884
static int mov_read_stsd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
885
{
886
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
887
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
888
    int entries, frames_per_sample;
889
    uint32_t format;
890
    uint8_t codec_name[32];
891

    
892
    /* for palette traversal */
893
    int color_depth;
894
    int color_start;
895
    int color_count;
896
    int color_end;
897
    int color_index;
898
    int color_dec;
899
    int color_greyscale;
900
    unsigned char *color_table;
901
    int j;
902
    unsigned char r, g, b;
903

    
904
    print_atom("stsd", atom);
905

    
906
    get_byte(pb); /* version */
907
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
908

    
909
    entries = get_be32(pb);
910

    
911
    while(entries--) { //Parsing Sample description table
912
        enum CodecID id;
913
        int size = get_be32(pb); /* size */
914
        format = get_le32(pb); /* data format */
915

    
916
        get_be32(pb); /* reserved */
917
        get_be16(pb); /* reserved */
918
        get_be16(pb); /* index */
919

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

    
966
            st->codec->bits_per_sample = get_be16(pb); /* depth */
967
            st->codec->color_table_id = get_be16(pb); /* colortable id */
968

    
969
/*          These are set in mov_read_stts and might already be set!
970
            st->codec->time_base.den      = 25;
971
            st->codec->time_base.num = 1;
972
*/
973
            size -= (16+8*4+2+32+2*2);
974
#if 0
975
            while (size >= 8) {
976
                MOV_atom_t a;
977
                int64_t start_pos;
978

979
                a.size = get_be32(pb);
980
                a.type = get_le32(pb);
981
                size -= 8;
982
#ifdef DEBUG
983
                av_log(NULL, AV_LOG_DEBUG, "VIDEO: atom_type=%c%c%c%c atom.size=%Ld size_left=%d\n",
984
                       (a.type >> 0) & 0xff,
985
                       (a.type >> 8) & 0xff,
986
                       (a.type >> 16) & 0xff,
987
                       (a.type >> 24) & 0xff,
988
                       a.size, size);
989
#endif
990
                start_pos = url_ftell(pb);
991

    
992
                switch(a.type) {
993
                case MKTAG('e', 's', 'd', 's'):
994
                    {
995
                        int tag, len;
996
                        /* Well, broken but suffisant for some MP4 streams */
997
                        get_be32(pb); /* version + flags */
998
                        len = mov_mp4_read_descr(pb, &tag);
999
                        if (tag == 0x03) {
1000
                            /* MP4ESDescrTag */
1001
                            get_be16(pb); /* ID */
1002
                            get_byte(pb); /* priority */
1003
                            len = mov_mp4_read_descr(pb, &tag);
1004
                            if (tag != 0x04)
1005
                                goto fail;
1006
                            /* MP4DecConfigDescrTag */
1007
                            get_byte(pb); /* objectTypeId */
1008
                            get_be32(pb); /* streamType + buffer size */
1009
                            get_be32(pb); /* max bit rate */
1010
                            get_be32(pb); /* avg bit rate */
1011
                            len = mov_mp4_read_descr(pb, &tag);
1012
                            if (tag != 0x05)
1013
                                goto fail;
1014
                            /* MP4DecSpecificDescrTag */
1015
#ifdef DEBUG
1016
                            av_log(NULL, AV_LOG_DEBUG, "Specific MPEG4 header len=%d\n", len);
1017
#endif
1018
                            sc->header_data = av_mallocz(len);
1019
                            if (sc->header_data) {
1020
                                get_buffer(pb, sc->header_data, len);
1021
                                sc->header_len = len;
1022
                            }
1023
                        }
1024
                        /* in any case, skip garbage */
1025
                    }
1026
                    break;
1027
                default:
1028
                    break;
1029
                }
1030
            fail:
1031
                av_log(NULL, AV_LOG_DEBUG, "ATOMENEWSIZE %Ld   %d\n", atom.size, url_ftell(pb) - start_pos);
1032
                if (atom.size > 8) {
1033
                    url_fskip(pb, (atom.size - 8) -
1034
                              ((url_ftell(pb) - start_pos)));
1035
                    size -= atom.size - 8;
1036
                }
1037
            }
1038
            if (size > 0) {
1039
                /* unknown extension */
1040
                url_fskip(pb, size);
1041
            }
1042
#else
1043

    
1044
            /* figure out the palette situation */
1045
            color_depth = st->codec->bits_per_sample & 0x1F;
1046
            color_greyscale = st->codec->bits_per_sample & 0x20;
1047

    
1048
            /* if the depth is 2, 4, or 8 bpp, file is palettized */
1049
            if ((color_depth == 2) || (color_depth == 4) ||
1050
                (color_depth == 8)) {
1051

    
1052
                if (color_greyscale) {
1053

    
1054
                    /* compute the greyscale palette */
1055
                    color_count = 1 << color_depth;
1056
                    color_index = 255;
1057
                    color_dec = 256 / (color_count - 1);
1058
                    for (j = 0; j < color_count; j++) {
1059
                        r = g = b = color_index;
1060
                        c->palette_control.palette[j] =
1061
                            (r << 16) | (g << 8) | (b);
1062
                        color_index -= color_dec;
1063
                        if (color_index < 0)
1064
                            color_index = 0;
1065
                    }
1066

    
1067
                } else if (st->codec->color_table_id & 0x08) {
1068

    
1069
                    /* if flag bit 3 is set, use the default palette */
1070
                    color_count = 1 << color_depth;
1071
                    if (color_depth == 2)
1072
                        color_table = ff_qt_default_palette_4;
1073
                    else if (color_depth == 4)
1074
                        color_table = ff_qt_default_palette_16;
1075
                    else
1076
                        color_table = ff_qt_default_palette_256;
1077

    
1078
                    for (j = 0; j < color_count; j++) {
1079
                        r = color_table[j * 4 + 0];
1080
                        g = color_table[j * 4 + 1];
1081
                        b = color_table[j * 4 + 2];
1082
                        c->palette_control.palette[j] =
1083
                            (r << 16) | (g << 8) | (b);
1084
                    }
1085

    
1086
                } else {
1087

    
1088
                    /* load the palette from the file */
1089
                    color_start = get_be32(pb);
1090
                    color_count = get_be16(pb);
1091
                    color_end = get_be16(pb);
1092
                    for (j = color_start; j <= color_end; j++) {
1093
                        /* each R, G, or B component is 16 bits;
1094
                         * only use the top 8 bits; skip alpha bytes
1095
                         * up front */
1096
                        get_byte(pb);
1097
                        get_byte(pb);
1098
                        r = get_byte(pb);
1099
                        get_byte(pb);
1100
                        g = get_byte(pb);
1101
                        get_byte(pb);
1102
                        b = get_byte(pb);
1103
                        get_byte(pb);
1104
                        c->palette_control.palette[j] =
1105
                            (r << 16) | (g << 8) | (b);
1106
                    }
1107
                }
1108

    
1109
                st->codec->palctrl = &c->palette_control;
1110
                st->codec->palctrl->palette_changed = 1;
1111
            } else
1112
                st->codec->palctrl = NULL;
1113

    
1114
            a.size = size;
1115
            mov_read_default(c, pb, a);
1116
#endif
1117
        } else {
1118
            st->codec->codec_id = codec_get_id(mov_audio_tags, format);
1119
            if(st->codec->codec_id==CODEC_ID_AMR_NB || st->codec->codec_id==CODEC_ID_AMR_WB) //from TS26.244
1120
            {
1121
#ifdef DEBUG
1122
               av_log(NULL, AV_LOG_DEBUG, "AMR-NB or AMR-WB audio identified!!\n");
1123
#endif
1124
               get_be32(pb);get_be32(pb); //Reserved_8
1125
               get_be16(pb);//Reserved_2
1126
               get_be16(pb);//Reserved_2
1127
               get_be32(pb);//Reserved_4
1128
               get_be16(pb);//TimeScale
1129
               get_be16(pb);//Reserved_2
1130

    
1131
                //AMRSpecificBox.(10 bytes)
1132

    
1133
               get_be32(pb); //size
1134
               get_be32(pb); //type=='damr'
1135
               get_be32(pb); //vendor
1136
               get_byte(pb); //decoder version
1137
               get_be16(pb); //mode_set
1138
               get_byte(pb); //mode_change_period
1139
               get_byte(pb); //frames_per_sample
1140

    
1141
               st->duration = AV_NOPTS_VALUE;//Not possible to get from this info, must count number of AMR frames
1142
               if(st->codec->codec_id==CODEC_ID_AMR_NB)
1143
               {
1144
                   st->codec->sample_rate=8000;
1145
                   st->codec->channels=1;
1146
               }
1147
               else //AMR-WB
1148
               {
1149
                   st->codec->sample_rate=16000;
1150
                   st->codec->channels=1;
1151
               }
1152
               st->codec->bits_per_sample=16;
1153
               st->codec->bit_rate=0; /*It is not possible to tell this before we have
1154
                                       an audio frame and even then every frame can be different*/
1155
            }
1156
            else if( st->codec->codec_tag == MKTAG( 'm', 'p', '4', 's' ))
1157
            {
1158
                //This is some stuff for the hint track, lets ignore it!
1159
                //Do some mp4 auto detect.
1160
                c->mp4=1;
1161
                size-=(16);
1162
                url_fskip(pb, size); /* The mp4s atom also contians a esds atom that we can skip*/
1163
            }
1164
            else if( st->codec->codec_tag == MKTAG( 'm', 'p', '4', 'a' ))
1165
            {
1166
                MOV_atom_t a;
1167
                int mp4_version;
1168

    
1169
                /* Handle mp4 audio tag */
1170
                mp4_version=get_be16(pb);/*version*/
1171
                get_be16(pb); /*revesion*/
1172
                get_be32(pb);
1173
                st->codec->channels = get_be16(pb); /* channels */
1174
                st->codec->bits_per_sample = get_be16(pb); /* bits per sample */
1175
                get_be32(pb);
1176
                st->codec->sample_rate = get_be16(pb); /* sample rate, not always correct */
1177
                if(st->codec->sample_rate == 1) //nonsese rate? -> ignore
1178
                    st->codec->sample_rate= 0;
1179

    
1180
                get_be16(pb);
1181
                c->mp4=1;
1182

    
1183
                if(mp4_version==1)
1184
                {
1185
                    url_fskip(pb,16);
1186
                    a.size=size-(16+20+16);
1187
                }
1188
                else
1189
                    a.size=size-(16+20);
1190

    
1191
                a.offset=url_ftell(pb);
1192

    
1193
                mov_read_default(c, pb, a);
1194

    
1195
                /* Get correct sample rate from extradata */
1196
                if(st->codec->extradata_size) {
1197
                   const int samplerate_table[] = {
1198
                     96000, 88200, 64000, 48000, 44100, 32000,
1199
                     24000, 22050, 16000, 12000, 11025, 8000,
1200
                     7350, 0, 0, 0
1201
                   };
1202
                   unsigned char *px = st->codec->extradata;
1203
                   // 5 bits objectTypeIndex, 4 bits sampleRateIndex, 4 bits channels
1204
                   int samplerate_index = ((px[0] & 7) << 1) + ((px[1] >> 7) & 1);
1205
                   st->codec->sample_rate = samplerate_table[samplerate_index];
1206
                   st->codec->channels = (px[1] >> 3) & 15;
1207
                }
1208
            }
1209
            else if( st->codec->codec_tag == MKTAG( 'a', 'l', 'a', 'c' ))
1210
            {
1211
                /* Handle alac audio tag + special extradata */
1212
                get_be32(pb); /* version */
1213
                get_be32(pb);
1214
                st->codec->channels = get_be16(pb); /* channels */
1215
                st->codec->bits_per_sample = get_be16(pb); /* bits per sample */
1216
                get_be32(pb);
1217
                st->codec->sample_rate = get_be16(pb);
1218
                get_be16(pb);
1219

    
1220
                /* fetch the 36-byte extradata needed for alac decoding */
1221
                st->codec->extradata_size = 36;
1222
                st->codec->extradata = (uint8_t*)
1223
                    av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
1224
                get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
1225
            }
1226
            else if(size>=(16+20))
1227
            {//16 bytes read, reading atleast 20 more
1228
                uint16_t version;
1229
#ifdef DEBUG
1230
                av_log(NULL, AV_LOG_DEBUG, "audio size=0x%X\n",size);
1231
#endif
1232
                version = get_be16(pb); /* version */
1233
                get_be16(pb); /* revision level */
1234
                get_be32(pb); /* vendor */
1235

    
1236
                st->codec->channels = get_be16(pb);             /* channel count */
1237
                st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1238

    
1239
                /* handle specific s8 codec */
1240
                get_be16(pb); /* compression id = 0*/
1241
                get_be16(pb); /* packet size = 0 */
1242

    
1243
                st->codec->sample_rate = ((get_be32(pb) >> 16));
1244
                //av_log(NULL, AV_LOG_DEBUG, "CODECID %d  %d  %.4s\n", st->codec->codec_id, CODEC_ID_PCM_S16BE, (char*)&format);
1245

    
1246
                switch (st->codec->codec_id) {
1247
                case CODEC_ID_PCM_S16BE:
1248
                    if (st->codec->bits_per_sample == 8)
1249
                        st->codec->codec_id = CODEC_ID_PCM_S8;
1250
                    /* fall */
1251
                case CODEC_ID_PCM_U8:
1252
                    st->codec->bit_rate = st->codec->sample_rate * 8;
1253
                    break;
1254
                default:
1255
                    ;
1256
                }
1257

    
1258
                //Read QT version 1 fields. In version 0 theese dont exist
1259
#ifdef DEBUG
1260
                av_log(NULL, AV_LOG_DEBUG, "version =%d mp4=%d\n",version,c->mp4);
1261
                av_log(NULL, AV_LOG_DEBUG, "size-(16+20+16)=%d\n",size-(16+20+16));
1262
#endif
1263
                if((version==1) && size>=(16+20+16))
1264
                {
1265
                    get_be32(pb); /* samples per packet */
1266
                    get_be32(pb); /* bytes per packet */
1267
                    get_be32(pb); /* bytes per frame */
1268
                    get_be32(pb); /* bytes per sample */
1269
                    if(size>(16+20+16))
1270
                    {
1271
                        //Optional, additional atom-based fields
1272
                        MOV_atom_t a = { format, url_ftell(pb), size - (16 + 20 + 16 + 8) };
1273
#ifdef DEBUG
1274
                        av_log(NULL, AV_LOG_DEBUG, "offest=0x%X, sizeleft=%d=0x%x,format=%c%c%c%c\n",(int)url_ftell(pb),size - (16 + 20 + 16 ),size - (16 + 20 + 16 ),
1275
                            (format >> 0) & 0xff,
1276
                            (format >> 8) & 0xff,
1277
                            (format >> 16) & 0xff,
1278
                            (format >> 24) & 0xff);
1279
#endif
1280
                        mov_read_default(c, pb, a);
1281
                    }
1282
                }
1283
                else
1284
                {
1285
                    //We should be down to 0 bytes here, but lets make sure.
1286
                    size-=(16+20);
1287
#ifdef DEBUG
1288
                    if(size>0)
1289
                        av_log(NULL, AV_LOG_DEBUG, "skipping 0x%X bytes\n",size-(16+20));
1290
#endif
1291
                    url_fskip(pb, size);
1292
                }
1293
            }
1294
            else
1295
            {
1296
                size-=16;
1297
                //Unknown size, but lets do our best and skip the rest.
1298
#ifdef DEBUG
1299
                av_log(NULL, AV_LOG_DEBUG, "Strange size, skipping 0x%X bytes\n",size);
1300
#endif
1301
                url_fskip(pb, size);
1302
            }
1303
        }
1304
    }
1305

    
1306
    if(st->codec->codec_type==CODEC_TYPE_AUDIO && st->codec->sample_rate==0 && sc->time_scale>1) {
1307
        st->codec->sample_rate= sc->time_scale;
1308
    }
1309

    
1310
    return 0;
1311
}
1312

    
1313
static int mov_read_stsc(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1314
{
1315
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1316
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1317
    unsigned int i, entries;
1318

    
1319
    print_atom("stsc", atom);
1320

    
1321
    get_byte(pb); /* version */
1322
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1323

    
1324
    entries = get_be32(pb);
1325

    
1326
    if(entries >= UINT_MAX / sizeof(MOV_sample_to_chunk_tbl))
1327
        return -1;
1328

    
1329
#ifdef DEBUG
1330
av_log(NULL, AV_LOG_DEBUG, "track[%i].stsc.entries = %i\n", c->fc->nb_streams-1, entries);
1331
#endif
1332
    sc->sample_to_chunk_sz = entries;
1333
    sc->sample_to_chunk = (MOV_sample_to_chunk_tbl*) av_malloc(entries * sizeof(MOV_sample_to_chunk_tbl));
1334
    if (!sc->sample_to_chunk)
1335
        return -1;
1336
    for(i=0; i<entries; i++) {
1337
        sc->sample_to_chunk[i].first = get_be32(pb);
1338
        sc->sample_to_chunk[i].count = get_be32(pb);
1339
        sc->sample_to_chunk[i].id = get_be32(pb);
1340
#ifdef DEBUG
1341
/*        av_log(NULL, AV_LOG_DEBUG, "sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id); */
1342
#endif
1343
    }
1344
    return 0;
1345
}
1346

    
1347
static int mov_read_stss(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1348
{
1349
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1350
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1351
    unsigned int i, entries;
1352

    
1353
    print_atom("stss", atom);
1354

    
1355
    get_byte(pb); /* version */
1356
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1357

    
1358
    entries = get_be32(pb);
1359

    
1360
    if(entries >= UINT_MAX / sizeof(long))
1361
        return -1;
1362

    
1363
    sc->keyframe_count = entries;
1364
#ifdef DEBUG
1365
    av_log(NULL, AV_LOG_DEBUG, "keyframe_count = %ld\n", sc->keyframe_count);
1366
#endif
1367
    sc->keyframes = (long*) av_malloc(entries * sizeof(long));
1368
    if (!sc->keyframes)
1369
        return -1;
1370
    for(i=0; i<entries; i++) {
1371
        sc->keyframes[i] = get_be32(pb);
1372
#ifdef DEBUG
1373
/*        av_log(NULL, AV_LOG_DEBUG, "keyframes[]=%ld\n", sc->keyframes[i]); */
1374
#endif
1375
    }
1376
    return 0;
1377
}
1378

    
1379
static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1380
{
1381
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1382
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1383
    unsigned int i, entries;
1384

    
1385
    print_atom("stsz", atom);
1386

    
1387
    get_byte(pb); /* version */
1388
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1389

    
1390
    sc->sample_size = get_be32(pb);
1391
    entries = get_be32(pb);
1392
    if(entries >= UINT_MAX / sizeof(long))
1393
        return -1;
1394

    
1395
    sc->sample_count = entries;
1396
#ifdef DEBUG
1397
    av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1398
#endif
1399
    if(sc->sample_size)
1400
        return 0; /* there isn't any table following */
1401
    sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1402
    if (!sc->sample_sizes)
1403
        return -1;
1404
    for(i=0; i<entries; i++) {
1405
        sc->sample_sizes[i] = get_be32(pb);
1406
#ifdef DEBUG
1407
        av_log(NULL, AV_LOG_DEBUG, "sample_sizes[]=%ld\n", sc->sample_sizes[i]);
1408
#endif
1409
    }
1410
    return 0;
1411
}
1412

    
1413
static int mov_read_stts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1414
{
1415
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1416
    //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1417
    unsigned int i, entries;
1418
    int64_t duration=0;
1419
    int64_t total_sample_count=0;
1420

    
1421
    print_atom("stts", atom);
1422

    
1423
    get_byte(pb); /* version */
1424
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1425
    entries = get_be32(pb);
1426
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1427
        return -1;
1428

    
1429
    c->streams[c->fc->nb_streams-1]->stts_count = entries;
1430
    c->streams[c->fc->nb_streams-1]->stts_data = av_malloc(entries * sizeof(Time2Sample));
1431

    
1432
#ifdef DEBUG
1433
av_log(NULL, AV_LOG_DEBUG, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries);
1434
#endif
1435
    for(i=0; i<entries; i++) {
1436
        int sample_duration;
1437
        int sample_count;
1438

    
1439
        sample_count=get_be32(pb);
1440
        sample_duration = get_be32(pb);
1441
        c->streams[c->fc->nb_streams - 1]->stts_data[i].count= sample_count;
1442
        c->streams[c->fc->nb_streams - 1]->stts_data[i].duration= sample_duration;
1443

    
1444
#ifdef DEBUG
1445
        av_log(NULL, AV_LOG_DEBUG, "sample_count=%d, sample_duration=%d\n",sample_count,sample_duration);
1446
#endif
1447
        duration+=sample_duration*sample_count;
1448
        total_sample_count+=sample_count;
1449
    }
1450

    
1451
    st->nb_frames= total_sample_count;
1452
    if(duration)
1453
        st->duration= duration;
1454
    return 0;
1455
}
1456

    
1457
static int mov_read_ctts(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1458
{
1459
//    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1460
    //MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1461
    unsigned int i, entries;
1462

    
1463
    print_atom("ctts", atom);
1464

    
1465
    get_byte(pb); /* version */
1466
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1467
    entries = get_be32(pb);
1468
    if(entries >= UINT_MAX / sizeof(Time2Sample))
1469
        return -1;
1470

    
1471
    c->streams[c->fc->nb_streams-1]->ctts_count = entries;
1472
    c->streams[c->fc->nb_streams-1]->ctts_data = av_malloc(entries * sizeof(Time2Sample));
1473

    
1474
// #ifdef DEBUG
1475
av_log(NULL, AV_LOG_DEBUG, "track[%i].ctts.entries = %i\n", c->fc->nb_streams-1, entries);
1476
// #endif
1477
    for(i=0; i<entries; i++) {
1478
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].count= get_be32(pb);
1479
        c->streams[c->fc->nb_streams - 1]->ctts_data[i].duration= get_be32(pb);
1480
    }
1481
    return 0;
1482
}
1483

    
1484
static int mov_read_trak(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1485
{
1486
    AVStream *st;
1487
    MOVStreamContext *sc;
1488

    
1489
    print_atom("trak", atom);
1490

    
1491
    st = av_new_stream(c->fc, c->fc->nb_streams);
1492
    if (!st) return -2;
1493
    sc = (MOVStreamContext*) av_mallocz(sizeof(MOVStreamContext));
1494
    if (!sc) {
1495
        av_free(st);
1496
        return -1;
1497
    }
1498

    
1499
    sc->sample_to_chunk_index = -1;
1500
    st->priv_data = sc;
1501
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
1502
    st->start_time = 0; /* XXX: check */
1503
    c->streams[c->fc->nb_streams-1] = sc;
1504

    
1505
    return mov_read_default(c, pb, atom);
1506
}
1507

    
1508
static int mov_read_tkhd(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1509
{
1510
    AVStream *st;
1511

    
1512
    print_atom("tkhd", atom);
1513

    
1514
    st = c->fc->streams[c->fc->nb_streams-1];
1515

    
1516
    get_byte(pb); /* version */
1517

    
1518
    get_byte(pb); get_byte(pb);
1519
    get_byte(pb); /* flags */
1520
    /*
1521
    MOV_TRACK_ENABLED 0x0001
1522
    MOV_TRACK_IN_MOVIE 0x0002
1523
    MOV_TRACK_IN_PREVIEW 0x0004
1524
    MOV_TRACK_IN_POSTER 0x0008
1525
    */
1526

    
1527
    get_be32(pb); /* creation time */
1528
    get_be32(pb); /* modification time */
1529
    st->id = (int)get_be32(pb); /* track id (NOT 0 !)*/
1530
    get_be32(pb); /* reserved */
1531
    st->start_time = 0; /* check */
1532
    get_be32(pb); /* highlevel (considering edits) duration in movie timebase */
1533
    get_be32(pb); /* reserved */
1534
    get_be32(pb); /* reserved */
1535

    
1536
    get_be16(pb); /* layer */
1537
    get_be16(pb); /* alternate group */
1538
    get_be16(pb); /* volume */
1539
    get_be16(pb); /* reserved */
1540

    
1541
    url_fskip(pb, 36); /* display matrix */
1542

    
1543
    /* those are fixed-point */
1544
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1545
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
1546

    
1547
    return 0;
1548
}
1549

    
1550
/* this atom should be null (from specs), but some buggy files put the 'moov' atom inside it... */
1551
/* like the files created with Adobe Premiere 5.0, for samples see */
1552
/* http://graphics.tudelft.nl/~wouter/publications/soundtests/ */
1553
static int mov_read_wide(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1554
{
1555
    int err;
1556

    
1557
#ifdef DEBUG
1558
    print_atom("wide", atom);
1559
    debug_indent++;
1560
#endif
1561
    if (atom.size < 8)
1562
        return 0; /* continue */
1563
    if (get_be32(pb) != 0) { /* 0 sized mdat atom... use the 'wide' atom size */
1564
        url_fskip(pb, atom.size - 4);
1565
        return 0;
1566
    }
1567
    atom.type = get_le32(pb);
1568
    atom.offset += 8;
1569
    atom.size -= 8;
1570
    if (atom.type != MKTAG('m', 'd', 'a', 't')) {
1571
        url_fskip(pb, atom.size);
1572
        return 0;
1573
    }
1574
    err = mov_read_mdat(c, pb, atom);
1575
#ifdef DEBUG
1576
    debug_indent--;
1577
#endif
1578
    return err;
1579
}
1580

    
1581

    
1582
#ifdef CONFIG_ZLIB
1583
static int null_read_packet(void *opaque, uint8_t *buf, int buf_size)
1584
{
1585
    return -1;
1586
}
1587

    
1588
static int mov_read_cmov(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1589
{
1590
    ByteIOContext ctx;
1591
    uint8_t *cmov_data;
1592
    uint8_t *moov_data; /* uncompressed data */
1593
    long cmov_len, moov_len;
1594
    int ret;
1595

    
1596
    print_atom("cmov", atom);
1597

    
1598
    get_be32(pb); /* dcom atom */
1599
    if (get_le32(pb) != MKTAG( 'd', 'c', 'o', 'm' ))
1600
        return -1;
1601
    if (get_le32(pb) != MKTAG( 'z', 'l', 'i', 'b' )) {
1602
        av_log(NULL, AV_LOG_DEBUG, "unknown compression for cmov atom !");
1603
        return -1;
1604
    }
1605
    get_be32(pb); /* cmvd atom */
1606
    if (get_le32(pb) != MKTAG( 'c', 'm', 'v', 'd' ))
1607
        return -1;
1608
    moov_len = get_be32(pb); /* uncompressed size */
1609
    cmov_len = atom.size - 6 * 4;
1610

    
1611
    cmov_data = (uint8_t *) av_malloc(cmov_len);
1612
    if (!cmov_data)
1613
        return -1;
1614
    moov_data = (uint8_t *) av_malloc(moov_len);
1615
    if (!moov_data) {
1616
        av_free(cmov_data);
1617
        return -1;
1618
    }
1619
    get_buffer(pb, cmov_data, cmov_len);
1620
    if(uncompress (moov_data, (uLongf *) &moov_len, (const Bytef *)cmov_data, cmov_len) != Z_OK)
1621
        return -1;
1622
    if(init_put_byte(&ctx, moov_data, moov_len, 0, NULL, null_read_packet, NULL, NULL) != 0)
1623
        return -1;
1624
    ctx.buf_end = ctx.buffer + moov_len;
1625
    atom.type = MKTAG( 'm', 'o', 'o', 'v' );
1626
    atom.offset = 0;
1627
    atom.size = moov_len;
1628
#ifdef DEBUG
1629
    { int fd = open("/tmp/uncompheader.mov", O_WRONLY | O_CREAT); write(fd, moov_data, moov_len); close(fd); }
1630
#endif
1631
    ret = mov_read_default(c, &ctx, atom);
1632
    av_free(moov_data);
1633
    av_free(cmov_data);
1634

    
1635
    return ret;
1636
}
1637
#endif
1638

    
1639
/* edit list atom */
1640
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1641
{
1642
  int i, edit_count;
1643
  print_atom("elst", atom);
1644

    
1645
  get_byte(pb); /* version */
1646
  get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1647
  edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1648

    
1649
  for(i=0; i<edit_count; i++){
1650
    get_be32(pb); /* Track duration */
1651
    get_be32(pb); /* Media time */
1652
    get_be32(pb); /* Media rate */
1653
  }
1654
#ifdef DEBUG
1655
  av_log(NULL, AV_LOG_DEBUG, "track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1656
#endif
1657
  return 0;
1658
}
1659

    
1660
static const MOVParseTableEntry mov_default_parse_table[] = {
1661
/* mp4 atoms */
1662
{ MKTAG( 'c', 'o', '6', '4' ), mov_read_stco },
1663
{ MKTAG( 'c', 'p', 'r', 't' ), mov_read_default },
1664
{ MKTAG( 'c', 'r', 'h', 'd' ), mov_read_default },
1665
{ MKTAG( 'c', 't', 't', 's' ), mov_read_ctts }, /* composition time to sample */
1666
{ MKTAG( 'd', 'i', 'n', 'f' ), mov_read_default }, /* data information */
1667
{ MKTAG( 'd', 'p', 'n', 'd' ), mov_read_leaf },
1668
{ MKTAG( 'd', 'r', 'e', 'f' ), mov_read_leaf },
1669
{ MKTAG( 'e', 'd', 't', 's' ), mov_read_default },
1670
{ MKTAG( 'e', 'l', 's', 't' ), mov_read_elst },
1671
{ MKTAG( 'f', 'r', 'e', 'e' ), mov_read_leaf },
1672
{ MKTAG( 'h', 'd', 'l', 'r' ), mov_read_hdlr },
1673
{ MKTAG( 'h', 'i', 'n', 't' ), mov_read_leaf },
1674
{ MKTAG( 'h', 'm', 'h', 'd' ), mov_read_leaf },
1675
{ MKTAG( 'i', 'o', 'd', 's' ), mov_read_leaf },
1676
{ MKTAG( 'm', 'd', 'a', 't' ), mov_read_mdat },
1677
{ MKTAG( 'm', 'd', 'h', 'd' ), mov_read_mdhd },
1678
{ MKTAG( 'm', 'd', 'i', 'a' ), mov_read_default },
1679
{ MKTAG( 'm', 'i', 'n', 'f' ), mov_read_default },
1680
{ MKTAG( 'm', 'o', 'o', 'v' ), mov_read_moov },
1681
{ MKTAG( 'm', 'p', '4', 'a' ), mov_read_default },
1682
{ MKTAG( 'm', 'p', '4', 's' ), mov_read_default },
1683
{ MKTAG( 'm', 'p', '4', 'v' ), mov_read_default },
1684
{ MKTAG( 'm', 'p', 'o', 'd' ), mov_read_leaf },
1685
{ MKTAG( 'm', 'v', 'h', 'd' ), mov_read_mvhd },
1686
{ MKTAG( 'n', 'm', 'h', 'd' ), mov_read_leaf },
1687
{ MKTAG( 'o', 'd', 'h', 'd' ), mov_read_default },
1688
{ MKTAG( 's', 'd', 'h', 'd' ), mov_read_default },
1689
{ MKTAG( 's', 'k', 'i', 'p' ), mov_read_leaf },
1690
{ MKTAG( 's', 'm', 'h', 'd' ), mov_read_leaf }, /* sound media info header */
1691
{ MKTAG( 'S', 'M', 'I', ' ' ), mov_read_smi }, /* Sorenson extension ??? */
1692
{ MKTAG( 'a', 'v', 'c', 'C' ), mov_read_avcC },
1693
{ MKTAG( 's', 't', 'b', 'l' ), mov_read_default },
1694
{ MKTAG( 's', 't', 'c', 'o' ), mov_read_stco },
1695
{ MKTAG( 's', 't', 'd', 'p' ), mov_read_default },
1696
{ MKTAG( 's', 't', 's', 'c' ), mov_read_stsc },
1697
{ MKTAG( 's', 't', 's', 'd' ), mov_read_stsd }, /* sample description */
1698
{ MKTAG( 's', 't', 's', 'h' ), mov_read_default },
1699
{ MKTAG( 's', 't', 's', 's' ), mov_read_stss }, /* sync sample */
1700
{ MKTAG( 's', 't', 's', 'z' ), mov_read_stsz }, /* sample size */
1701
{ MKTAG( 's', 't', 't', 's' ), mov_read_stts },
1702
{ MKTAG( 't', 'k', 'h', 'd' ), mov_read_tkhd }, /* track header */
1703
{ MKTAG( 't', 'r', 'a', 'k' ), mov_read_trak },
1704
{ MKTAG( 't', 'r', 'e', 'f' ), mov_read_default }, /* not really */
1705
{ MKTAG( 'u', 'd', 't', 'a' ), mov_read_leaf },
1706
{ MKTAG( 'u', 'r', 'l', ' ' ), mov_read_leaf },
1707
{ MKTAG( 'u', 'r', 'n', ' ' ), mov_read_leaf },
1708
{ MKTAG( 'u', 'u', 'i', 'd' ), mov_read_leaf },
1709
{ MKTAG( 'v', 'm', 'h', 'd' ), mov_read_leaf }, /* video media info header */
1710
{ MKTAG( 'w', 'a', 'v', 'e' ), mov_read_wave },
1711
/* extra mp4 */
1712
{ MKTAG( 'M', 'D', 'E', 'S' ), mov_read_leaf },
1713
/* QT atoms */
1714
{ MKTAG( 'c', 'h', 'a', 'p' ), mov_read_leaf },
1715
{ MKTAG( 'c', 'l', 'i', 'p' ), mov_read_default },
1716
{ MKTAG( 'c', 'r', 'g', 'n' ), mov_read_leaf },
1717
{ MKTAG( 'c', 't', 'a', 'b' ), mov_read_ctab },
1718
{ MKTAG( 'e', 's', 'd', 's' ), mov_read_esds },
1719
{ MKTAG( 'k', 'm', 'a', 't' ), mov_read_leaf },
1720
{ MKTAG( 'm', 'a', 't', 't' ), mov_read_default },
1721
{ MKTAG( 'r', 'd', 'r', 'f' ), mov_read_leaf },
1722
{ MKTAG( 'r', 'm', 'd', 'a' ), mov_read_default },
1723
{ MKTAG( 'r', 'm', 'd', 'r' ), mov_read_leaf },
1724
{ MKTAG( 'r', 'm', 'r', 'a' ), mov_read_default },
1725
{ MKTAG( 's', 'c', 'p', 't' ), mov_read_leaf },
1726
{ MKTAG( 's', 's', 'r', 'c' ), mov_read_leaf },
1727
{ MKTAG( 's', 'y', 'n', 'c' ), mov_read_leaf },
1728
{ MKTAG( 't', 'c', 'm', 'd' ), mov_read_leaf },
1729
{ MKTAG( 'w', 'i', 'd', 'e' ), mov_read_wide }, /* place holder */
1730
//{ MKTAG( 'r', 'm', 'q', 'u' ), mov_read_leaf },
1731
#ifdef CONFIG_ZLIB
1732
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_cmov },
1733
#else
1734
{ MKTAG( 'c', 'm', 'o', 'v' ), mov_read_leaf },
1735
#endif
1736
{ 0L, mov_read_leaf }
1737
};
1738

    
1739
static void mov_free_stream_context(MOVStreamContext *sc)
1740
{
1741
    if(sc) {
1742
        av_freep(&sc->chunk_offsets);
1743
        av_freep(&sc->sample_to_chunk);
1744
        av_freep(&sc->sample_sizes);
1745
        av_freep(&sc->keyframes);
1746
        av_freep(&sc->stts_data);
1747
        av_freep(&sc->ctts_data);
1748
        av_freep(&sc);
1749
    }
1750
}
1751

    
1752
static inline uint32_t mov_to_tag(uint8_t *buf)
1753
{
1754
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1755
}
1756

    
1757
static inline uint32_t to_be32(uint8_t *buf)
1758
{
1759
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1760
}
1761

    
1762
/* XXX: is it sufficient ? */
1763
static int mov_probe(AVProbeData *p)
1764
{
1765
    unsigned int offset;
1766
    uint32_t tag;
1767
    int score = 0;
1768

    
1769
    /* check file header */
1770
    if (p->buf_size <= 12)
1771
        return 0;
1772
    offset = 0;
1773
    for(;;) {
1774
        /* ignore invalid offset */
1775
        if ((offset + 8) > (unsigned int)p->buf_size)
1776
            return score;
1777
        tag = mov_to_tag(p->buf + offset + 4);
1778
        switch(tag) {
1779
        /* check for obvious tags */
1780
        case MKTAG( 'm', 'o', 'o', 'v' ):
1781
        case MKTAG( 'm', 'd', 'a', 't' ):
1782
        case MKTAG( 'p', 'n', 'o', 't' ): /* detect movs with preview pics like ew.mov and april.mov */
1783
        case MKTAG( 'u', 'd', 't', 'a' ): /* Packet Video PVAuthor adds this and a lot of more junk */
1784
            return AVPROBE_SCORE_MAX;
1785
        /* those are more common words, so rate then a bit less */
1786
        case MKTAG( 'w', 'i', 'd', 'e' ):
1787
        case MKTAG( 'f', 'r', 'e', 'e' ):
1788
        case MKTAG( 'j', 'u', 'n', 'k' ):
1789
        case MKTAG( 'p', 'i', 'c', 't' ):
1790
            return AVPROBE_SCORE_MAX - 5;
1791
        case MKTAG( 'f', 't', 'y', 'p' ):
1792
        case MKTAG( 's', 'k', 'i', 'p' ):
1793
        case MKTAG( 'u', 'u', 'i', 'd' ):
1794
            offset = to_be32(p->buf+offset) + offset;
1795
            /* if we only find those cause probedata is too small at least rate them */
1796
            score = AVPROBE_SCORE_MAX - 50;
1797
            break;
1798
        default:
1799
            /* unrecognized tag */
1800
            return score;
1801
        }
1802
    }
1803
    return score;
1804
}
1805

    
1806
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1807
{
1808
    MOVContext *mov = (MOVContext *) s->priv_data;
1809
    ByteIOContext *pb = &s->pb;
1810
    int i, j, nb, err;
1811
    MOV_atom_t atom = { 0, 0, 0 };
1812

    
1813
    mov->fc = s;
1814
    mov->parse_table = mov_default_parse_table;
1815
#if 0
1816
    /* XXX: I think we should auto detect */
1817
    if(s->iformat->name[1] == 'p')
1818
        mov->mp4 = 1;
1819
#endif
1820
    if(!url_is_streamed(pb)) /* .mov and .mp4 aren't streamable anyway (only progressive download if moov is before mdat) */
1821
        atom.size = url_fsize(pb);
1822
    else
1823
        atom.size = 0x7FFFFFFFFFFFFFFFLL;
1824

    
1825
#ifdef DEBUG
1826
    av_log(NULL, AV_LOG_DEBUG, "filesz=%Ld\n", atom.size);
1827
#endif
1828

    
1829
    /* check MOV header */
1830
    err = mov_read_default(mov, pb, atom);
1831
    if (err<0 || (!mov->found_moov && !mov->found_mdat)) {
1832
        av_log(s, AV_LOG_ERROR, "mov: header not found !!! (err:%d, moov:%d, mdat:%d) pos:%"PRId64"\n",
1833
                err, mov->found_moov, mov->found_mdat, url_ftell(pb));
1834
        return -1;
1835
    }
1836
#ifdef DEBUG
1837
    av_log(NULL, AV_LOG_DEBUG, "on_parse_exit_offset=%d\n", (int) url_ftell(pb));
1838
#endif
1839
    /* some cleanup : make sure we are on the mdat atom */
1840
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1841
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1842

    
1843
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1844

    
1845
#ifdef DEBUG
1846
    av_log(NULL, AV_LOG_DEBUG, "mdat_reset_offset=%d\n", (int) url_ftell(pb));
1847
#endif
1848

    
1849
#ifdef DEBUG
1850
    av_log(NULL, AV_LOG_DEBUG, "streams= %d\n", s->nb_streams);
1851
#endif
1852
    mov->total_streams = nb = s->nb_streams;
1853

    
1854
#if 1
1855
    for(i=0; i<s->nb_streams;) {
1856
        if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1857
            av_free(s->streams[i]);
1858
            for(j=i+1; j<s->nb_streams; j++)
1859
                s->streams[j-1] = s->streams[j];
1860
            s->nb_streams--;
1861
        } else
1862
            i++;
1863
    }
1864
    for(i=0; i<s->nb_streams;i++) {
1865
        MOVStreamContext *sc;
1866
        sc = (MOVStreamContext *)s->streams[i]->priv_data;
1867
        sc->ffindex = i;
1868
        sc->is_ff_stream = 1;
1869
    }
1870
#endif
1871
#ifdef DEBUG
1872
    av_log(NULL, AV_LOG_DEBUG, "real streams= %d\n", s->nb_streams);
1873
#endif
1874
    return 0;
1875
}
1876

    
1877
/* Yes, this is ugly... I didn't write the specs of QT :p */
1878
/* XXX:remove useless commented code sometime */
1879
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1880
{
1881
    MOVContext *mov = (MOVContext *) s->priv_data;
1882
    MOVStreamContext *sc;
1883
    int64_t offset = INT64_MAX;
1884
    int64_t best_dts = INT64_MAX;
1885
    int i, a, b, m;
1886
    int size;
1887
    int idx;
1888
    size = 0x0FFFFFFF;
1889

    
1890
#ifdef MOV_SPLIT_CHUNKS
1891
    if (mov->partial) {
1892
        sc = mov->partial;
1893
        idx = sc->sample_to_chunk_index;
1894

    
1895
        if (idx < 0) return 0;
1896
#ifdef DEBUG
1897
        fprintf(stderr, "sc[ffid %d]->sample_size = %d\n", sc->ffindex, sc->sample_size);
1898
#endif
1899
        //size = sc->sample_sizes[sc->current_sample];
1900
        // that ain't working...
1901
        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1902
        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1903

    
1904
        sc->current_sample++;
1905
        sc->left_in_chunk--;
1906

    
1907
        if (sc->left_in_chunk <= 0)
1908
            mov->partial = 0;
1909
        offset = mov->next_chunk_offset;
1910
        /* extract the sample */
1911

    
1912
        goto readchunk;
1913
    }
1914
#endif
1915

    
1916
again:
1917
    sc = 0;
1918
    if(offset == INT64_MAX)
1919
        best_dts= INT64_MAX;
1920
    for(i=0; i<mov->total_streams; i++) {
1921
        MOVStreamContext *msc = mov->streams[i];
1922

    
1923
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1924
            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1925
                int64_t dts;
1926
                int index= msc->sample_to_time_index;
1927
                int sample= msc->sample_to_time_sample;
1928
                int time= msc->sample_to_time_time;
1929
                int duration = msc->stts_data[index].duration;
1930
                int count = msc->stts_data[index].count;
1931
                if (sample + count < msc->current_sample) {
1932
                    sample += count;
1933
                    time   += count*duration;
1934
                    index ++;
1935
                    duration = msc->stts_data[index].duration;
1936
                }
1937
                dts = time + (msc->current_sample-1 - sample) * (int64_t)duration;
1938
                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1939
//                av_log(NULL, AV_LOG_DEBUG, "%d %Ld %Ld %Ld \n", i, dts, best_dts, offset);
1940
                if(dts < best_dts){
1941
                    best_dts= dts;
1942
                    sc = msc;
1943
                    offset = msc->chunk_offsets[msc->next_chunk];
1944
                }
1945
            }else{
1946
            //av_log(NULL, AV_LOG_DEBUG, "MOCHUNK %ld  %d   %p  pos:%Ld\n", mov->streams[i]->next_chunk, mov->total_streams, mov->streams[i], url_ftell(&s->pb));
1947
                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1948
                    sc = msc;
1949
                    offset = msc->chunk_offsets[msc->next_chunk];
1950
                    //av_log(NULL, AV_LOG_DEBUG, "SELETED  %Ld  i:%d\n", offset, i);
1951
                }
1952
            }
1953
        }
1954
    }
1955
    if (!sc || offset==INT64_MAX)
1956
        return -1;
1957

    
1958
    sc->next_chunk++;
1959

    
1960
    if(mov->next_chunk_offset < offset) { /* some meta data */
1961
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1962
        mov->next_chunk_offset = offset;
1963
    }
1964

    
1965
//av_log(NULL, AV_LOG_DEBUG, "chunk: [%i] %lli -> %lli\n", st_id, mov->next_chunk_offset, offset);
1966
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1967
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1968
        mov->next_chunk_offset = offset;
1969
        offset = INT64_MAX;
1970
        goto again;
1971
    }
1972

    
1973
    /* now get the chunk size... */
1974

    
1975
    for(i=0; i<mov->total_streams; i++) {
1976
        MOVStreamContext *msc = mov->streams[i];
1977
        if ((msc->next_chunk < msc->chunk_count)
1978
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1979
            && msc->chunk_offsets[msc->next_chunk] > offset)
1980
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1981
    }
1982

    
1983
#ifdef MOV_MINOLTA_FIX
1984
    //Make sure that size is according to sample_size (Needed by .mov files
1985
    //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1986
    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1987
    //but I have no such movies
1988
    if (sc->sample_size > 0) {
1989
        int foundsize=0;
1990
        for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1991
            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1992
            {
1993
                // I can't figure out why for PCM audio sample_size is always 1
1994
                // (it should actually be channels*bits_per_second/8) but it is.
1995
                AVCodecContext* cod = s->streams[sc->ffindex]->codec;
1996
                if (sc->sample_size == 1 && (cod->codec_id == CODEC_ID_PCM_S16BE || cod->codec_id == CODEC_ID_PCM_S16LE))
1997
                    foundsize=(sc->sample_to_chunk[i].count*cod->channels*cod->bits_per_sample)/8;
1998
                else
1999
                    foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
2000
            }
2001
#ifdef DEBUG
2002
            av_log(NULL, AV_LOG_DEBUG, "sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id);
2003
#endif
2004
        }
2005
        if( (foundsize>0) && (foundsize<size) )
2006
        {
2007
#ifdef DEBUG
2008
            /*av_log(NULL, AV_LOG_DEBUG, "this size should actually be %d\n",foundsize);*/
2009
#endif
2010
            size=foundsize;
2011
        }
2012
    }
2013
#endif //MOV_MINOLTA_FIX
2014

    
2015
    idx = sc->sample_to_chunk_index;
2016
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
2017
        idx++;
2018
    sc->sample_to_chunk_index = idx;
2019
#ifdef MOV_SPLIT_CHUNKS
2020
    /* split chunks into samples */
2021
    if (sc->sample_size == 0 || sc->sample_size > 100) {
2022
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
2023
            mov->partial = sc;
2024
            /* we'll have to get those samples before next chunk */
2025
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
2026
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
2027
        }
2028

    
2029
        sc->current_sample++;
2030
    }else if(idx + 1 < sc->sample_to_chunk_sz){
2031
        sc->current_sample += sc->sample_size * sc->sample_to_chunk[idx].count;
2032
    }
2033
#endif
2034

    
2035
readchunk:
2036
#ifdef DEBUG
2037
    av_log(NULL, AV_LOG_DEBUG, "chunk: %lli -> %lli (%i)\n", offset, offset + size, size);
2038
#endif
2039
    if(size == 0x0FFFFFFF)
2040
        size = mov->mdat_size + mov->mdat_offset - offset;
2041
    if(size < 0)
2042
        return -1;
2043
    if(size == 0)
2044
        return -1;
2045
    url_fseek(&s->pb, offset, SEEK_SET);
2046

    
2047
    av_get_packet(&s->pb, pkt, size);
2048
    pkt->stream_index = sc->ffindex;
2049

    
2050
    // If the keyframes table exists, mark any samples that are in the table as key frames.
2051
    // If no table exists, treat very sample as a key frame.
2052
    if (sc->keyframes) {
2053
        a = 0;
2054
        b = sc->keyframe_count - 1;
2055

    
2056
        while (a < b) {
2057
            m = (a + b + 1) >> 1;
2058
            if (sc->keyframes[m] > sc->current_sample) {
2059
                b = m - 1;
2060
            } else {
2061
                a = m;
2062
            }
2063
        }
2064

    
2065
        if (sc->keyframes[a] == sc->current_sample)
2066
            pkt->flags |= PKT_FLAG_KEY;
2067
    }
2068
    else
2069
        pkt->flags |= PKT_FLAG_KEY;
2070

    
2071
#ifdef DEBUG
2072
/*
2073
    av_log(NULL, AV_LOG_DEBUG, "Packet (%d, %ld) ", pkt->stream_index, pkt->size);
2074
    for(i=0; i<8; i++)
2075
        av_log(NULL, AV_LOG_DEBUG, "%02x ", pkt->data[i]);
2076
    for(i=0; i<8; i++)
2077
        av_log(NULL, AV_LOG_DEBUG, "%c ", (pkt->data[i]) & 0x7F);
2078
    av_log(NULL, AV_LOG_DEBUG, "\n");
2079
*/
2080
#endif
2081

    
2082
    mov->next_chunk_offset = offset + size;
2083

    
2084
    /* find the corresponding dts */
2085
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
2086
      unsigned int count;
2087
      uint64_t dts, pts;
2088
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
2089
      count = sc->stts_data[sc->sample_to_time_index].count;
2090
      if ((sc->sample_to_time_sample + count) < sc->current_sample) {
2091
        sc->sample_to_time_sample += count;
2092
        sc->sample_to_time_time   += count*duration;
2093
        sc->sample_to_time_index ++;
2094
        duration = sc->stts_data[sc->sample_to_time_index].duration;
2095
      }
2096
      dts = sc->sample_to_time_time + (sc->current_sample-1 - sc->sample_to_time_sample) * (int64_t)duration;
2097
        /* find the corresponding pts */
2098
        if (sc->sample_to_ctime_index < sc->ctts_count) {
2099
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
2100
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
2101

    
2102
            if ((sc->sample_to_ctime_sample + count) < sc->current_sample) {
2103
                sc->sample_to_ctime_sample += count;
2104
                sc->sample_to_ctime_index ++;
2105
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
2106
            }
2107
            pts = dts + duration;
2108
        }else
2109
            pts = dts;
2110
        pkt->pts = pts;
2111
        pkt->dts = dts;
2112
#ifdef DEBUG
2113
    av_log(NULL, AV_LOG_DEBUG, "stream #%d smp #%ld dts = %lld pts = %lld (smp:%ld time:%lld idx:%d ent:%d count:%d dur:%d)\n"
2114
      , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
2115
      , sc->sample_to_time_sample
2116
      , sc->sample_to_time_time
2117
      , sc->sample_to_time_index
2118
      , sc->stts_count
2119
      , count
2120
      , duration);
2121
#endif
2122
    }
2123

    
2124
    return 0;
2125
}
2126

    
2127
#if defined(MOV_SPLIT_CHUNKS) && defined(MOV_SEEK)
2128
/**
2129
 * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
2130
 */
2131
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
2132
{
2133
    MOVContext* mov = (MOVContext *) s->priv_data;
2134
    MOVStreamContext* sc;
2135
    int32_t i, a, b, m;
2136
    int64_t start_time;
2137
    int32_t seek_sample, sample;
2138
    int32_t duration;
2139
    int32_t count;
2140
    int32_t chunk;
2141
    int32_t left_in_chunk;
2142
    int64_t chunk_file_offset;
2143
    int64_t sample_file_offset;
2144
    int32_t first_chunk_sample;
2145
    int32_t sample_to_chunk_idx;
2146
    int sample_to_time_index;
2147
    long sample_to_time_sample = 0;
2148
    uint64_t sample_to_time_time = 0;
2149
    int mov_idx;
2150

    
2151
    // Find the corresponding mov stream
2152
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
2153
        if (mov->streams[mov_idx]->ffindex == stream_index)
2154
            break;
2155
    if (mov_idx == mov->total_streams) {
2156
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
2157
        return -1;
2158
    }
2159
    sc = mov->streams[mov_idx];
2160

    
2161
    // Step 1. Find the edit that contains the requested time (elst)
2162
    if (sc->edit_count) {
2163
        // FIXME should handle edit list
2164
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
2165
        return -1;
2166
    }
2167

    
2168
    // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */
2169
#ifdef DEBUG
2170
  av_log(s, AV_LOG_DEBUG, "Searching for time %li in stream #%i (time_scale=%i)\n", (long)timestamp, mov_idx, sc->time_scale);
2171
#endif
2172
    start_time = 0; // FIXME use elst atom
2173
    sample = 1; // sample are 0 based in table
2174
#ifdef DEBUG
2175
    av_log(s, AV_LOG_DEBUG, "Searching for sample_time %li \n", (long)sample_time);
2176
#endif
2177
    for (i = 0; i < sc->stts_count; i++) {
2178
        count = sc->stts_data[i].count;
2179
        duration = sc->stts_data[i].duration;
2180
//av_log(s, AV_LOG_DEBUG, "> sample_time %lli \n", (long)sample_time);
2181
//av_log(s, AV_LOG_DEBUG, "> count=%i duration=%i\n", count, duration);
2182
        if ((start_time + count*duration) > sample_time) {
2183
            sample_to_time_time = start_time;
2184
            sample_to_time_index = i;
2185
            sample_to_time_sample = sample;
2186
            sample += (sample_time - start_time) / duration;
2187
            break;
2188
        }
2189
        sample += count;
2190
        start_time += count * duration;
2191
    }
2192
    sample_to_time_time = start_time;
2193
    sample_to_time_index = i;
2194
    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
2195
       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
2196

    
2197
#ifdef DEBUG
2198
    av_log(s, AV_LOG_DEBUG, "Found time %li at sample #%u\n", (long)sample_time, sample);
2199
#endif
2200
    if (sample > sc->sample_count) {
2201
        av_log(s, AV_LOG_ERROR, "mov: sample pos is too high, unable to seek (req. sample=%i, sample count=%ld)\n", sample, sc->sample_count);
2202
        return -1;
2203
    }
2204

    
2205
    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
2206
    if (sc->keyframes) {
2207
        a = 0;
2208
        b = sc->keyframe_count - 1;
2209
        while (a < b) {
2210
            m = (a + b + 1) >> 1;
2211
            if (sc->keyframes[m] > sample) {
2212
                b = m - 1;
2213
            } else {
2214
                a = m;
2215
            }
2216
#ifdef DEBUG
2217
         // av_log(s, AV_LOG_DEBUG, "a=%i (%i) b=%i (%i) m=%i (%i) stream #%i\n", a, sc->keyframes[a], b, sc->keyframes[b], m, sc->keyframes[m], mov_idx);
2218
#endif
2219
        }
2220
        // for low latency prob: always use the previous keyframe, just uncomment the next line
2221
        // if (a) a--;
2222
        seek_sample = sc->keyframes[a];
2223
    }
2224
    else
2225
        seek_sample = sample; // else all samples are key frames
2226
#ifdef DEBUG
2227
    av_log(s, AV_LOG_DEBUG, "Found nearest keyframe at sample #%i \n", seek_sample);
2228
#endif
2229

    
2230
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2231
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2232
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2233
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2234
            break;
2235
        first_chunk_sample += b;
2236
    }
2237
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2238
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2239
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2240
    sample_to_chunk_idx = i;
2241
#ifdef DEBUG
2242
    av_log(s, AV_LOG_DEBUG, "Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2243
#endif
2244

    
2245
    // Step 5. Find the offset of the chunk using the chunk offset atom
2246
    if (!sc->chunk_offsets) {
2247
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2248
        return -1;
2249
    }
2250
    if (chunk > sc->chunk_count) {
2251
        av_log(s, AV_LOG_ERROR, "mov: chunk offset atom too short, unable to seek (req. chunk=%i, chunk count=%li)\n", chunk, sc->chunk_count);
2252
        return -1;
2253
    }
2254
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
2255
#ifdef DEBUG
2256
    av_log(s, AV_LOG_DEBUG, "Chunk file offset is #%llu \n", chunk_file_offset);
2257
#endif
2258

    
2259
    // Step 6. Find the byte offset within the chunk using the sample size atom
2260
    sample_file_offset = chunk_file_offset;
2261
    if (sc->sample_size)
2262
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2263
    else {
2264
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2265
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2266
        }
2267
    }
2268
#ifdef DEBUG
2269
    av_log(s, AV_LOG_DEBUG, "Sample file offset is #%llu \n", sample_file_offset);
2270
#endif
2271

    
2272
    // Step 6. Update the parser
2273
    mov->partial = sc;
2274
    mov->next_chunk_offset = sample_file_offset;
2275
    // Update current stream state
2276
    sc->current_sample = seek_sample - 1;  // zero based
2277
    sc->left_in_chunk = left_in_chunk;
2278
    sc->next_chunk = chunk; // +1 -1 (zero based)
2279
    sc->sample_to_chunk_index = sample_to_chunk_idx;
2280

    
2281
    // Update other streams
2282
    for (i = 0; i<mov->total_streams; i++) {
2283
        MOVStreamContext *msc;
2284
        if (i == mov_idx) continue;
2285
        // Find the nearest 'next' chunk
2286
        msc = mov->streams[i];
2287
        a = 0;
2288
        b = msc->chunk_count - 1;
2289
        while (a < b) {
2290
            m = (a + b + 1) >> 1;
2291
            if (msc->chunk_offsets[m] > chunk_file_offset) {
2292
                b = m - 1;
2293
            } else {
2294
                a = m;
2295
            }
2296
#ifdef DEBUG
2297
/*            av_log(s, AV_LOG_DEBUG, "a=%i (%li) b=%i (%li) m=%i (%li) stream #%i\n"
2298
            , a, (long)msc->chunk_offsets[a], b, (long)msc->chunk_offsets[b], m, (long)msc->chunk_offsets[m],  i); */
2299
#endif
2300
        }
2301
        msc->next_chunk = a;
2302
        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2303
            msc->next_chunk ++;
2304
#ifdef DEBUG
2305
        av_log(s, AV_LOG_DEBUG, "Nearest next chunk for stream #%i is #%i @%lli\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2306
#endif
2307
        // Compute sample count and index in the sample_to_chunk table (what a pity)
2308
        msc->sample_to_chunk_index = 0;
2309
        msc->current_sample = 0;
2310
        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2311
            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2312
            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2313
            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2314
        }
2315
        msc->current_sample += (msc->next_chunk - (msc->sample_to_chunk[msc->sample_to_chunk_index].first - 1)) * sc->sample_to_chunk[msc->sample_to_chunk_index].count;
2316
        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2317
        // Find corresponding position in stts (used later to compute dts)
2318
        sample = 0;
2319
        start_time = 0;
2320
        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2321
            count = msc->stts_data[msc->sample_to_time_index].count;
2322
            duration = msc->stts_data[msc->sample_to_time_index].duration;
2323
            if ((sample + count - 1) > msc->current_sample) {
2324
                msc->sample_to_time_time = start_time;
2325
                msc->sample_to_time_sample = sample;
2326
                break;
2327
            }
2328
            sample += count;
2329
            start_time += count * duration;
2330
        }
2331
        sample = 0;
2332
        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2333
            count = msc->ctts_data[msc->sample_to_ctime_index].count;
2334
            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2335
            if ((sample + count - 1) > msc->current_sample) {
2336
                msc->sample_to_ctime_sample = sample;
2337
                break;
2338
            }
2339
            sample += count;
2340
        }
2341
#ifdef DEBUG
2342
        av_log(s, AV_LOG_DEBUG, "Next Sample for stream #%i is #%i @%i\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
2343
#endif
2344
    }
2345
    return 0;
2346
}
2347
#endif
2348

    
2349
static int mov_read_close(AVFormatContext *s)
2350
{
2351
    int i;
2352
    MOVContext *mov = (MOVContext *) s->priv_data;
2353
    for(i=0; i<mov->total_streams; i++)
2354
        mov_free_stream_context(mov->streams[i]);
2355
    /* free color tabs */
2356
    for(i=0; i<mov->ctab_size; i++)
2357
        av_freep(&mov->ctab[i]);
2358
    av_freep(&mov->ctab);
2359
    return 0;
2360
}
2361

    
2362
static AVInputFormat mov_iformat = {
2363
    "mov,mp4,m4a,3gp,3g2",
2364
    "QuickTime/MPEG4 format",
2365
    sizeof(MOVContext),
2366
    mov_probe,
2367
    mov_read_header,
2368
    mov_read_packet,
2369
    mov_read_close,
2370
#if defined(MOV_SPLIT_CHUNKS) && defined(MOV_SEEK)
2371
    mov_read_seek,
2372
#endif
2373
};
2374

    
2375
int mov_init(void)
2376
{
2377
    av_register_input_format(&mov_iformat);
2378
    return 0;
2379
}