~ubuntu-branches/ubuntu/hardy/ffmpeg/hardy

« back to all changes in this revision

Viewing changes to libavformat/mov.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Dröge
  • Date: 2006-08-23 14:35:52 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060823143552-8fxnur5b9gesr03m
Tags: 3:0.cvs20060823-0ubuntu1
* Sync with Debian:
  + Add the epoch again

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
//#define DEBUG
23
23
 
24
24
#include "avformat.h"
25
 
#include "avi.h"
26
 
#include "mov.h"
 
25
#include "riff.h"
 
26
#include "isom.h"
27
27
 
28
28
#ifdef CONFIG_ZLIB
29
29
#include <zlib.h>
63
63
#undef NDEBUG
64
64
#include <assert.h>
65
65
 
66
 
/* Allows seeking */
67
 
#define MOV_SEEK
68
 
 
69
 
/* Special handling for movies created with Minolta Dimaxe Xi*/
70
 
/* this fix should not interfere with other .mov files, but just in case*/
71
 
#define MOV_MINOLTA_FIX
72
 
 
73
 
/* some streams in QT (and in MP4 mostly) aren't either video nor audio */
74
 
/* so we first list them as this, then clean up the list of streams we give back, */
75
 
/* getting rid of these */
76
 
#define CODEC_TYPE_MOV_OTHER    (enum CodecType) 2
77
 
 
78
 
/* http://gpac.sourceforge.net/tutorial/mediatypes.htm */
79
 
const CodecTag ff_mov_obj_type[] = {
80
 
    { CODEC_ID_MPEG4     ,  32 },
81
 
    { CODEC_ID_H264      ,  33 },
82
 
    { CODEC_ID_AAC       ,  64 },
83
 
    { CODEC_ID_MPEG2VIDEO,  96 }, /* MPEG2 Simple */
84
 
    { CODEC_ID_MPEG2VIDEO,  97 }, /* MPEG2 Main */
85
 
    { CODEC_ID_MPEG2VIDEO,  98 }, /* MPEG2 SNR */
86
 
    { CODEC_ID_MPEG2VIDEO,  99 }, /* MPEG2 Spatial */
87
 
    { CODEC_ID_MPEG2VIDEO, 100 }, /* MPEG2 High */
88
 
    { CODEC_ID_MPEG2VIDEO, 101 }, /* MPEG2 422 */
89
 
    { CODEC_ID_AAC       , 102 }, /* MPEG2 AAC Main */
90
 
    { CODEC_ID_AAC       , 103 }, /* MPEG2 AAC Low */
91
 
    { CODEC_ID_AAC       , 104 }, /* MPEG2 AAC SSR */
92
 
    { CODEC_ID_MP3       , 105 },
93
 
    { CODEC_ID_MPEG1VIDEO, 106 },
94
 
    { CODEC_ID_MP2       , 107 },
95
 
    { CODEC_ID_MJPEG     , 108 },
96
 
    { CODEC_ID_PCM_S16LE , 224 },
97
 
    { CODEC_ID_VORBIS    , 221 },
98
 
    { CODEC_ID_AC3       , 226 },
99
 
    { CODEC_ID_PCM_ALAW  , 227 },
100
 
    { CODEC_ID_PCM_MULAW , 228 },
101
 
    { CODEC_ID_PCM_S16BE , 230 },
102
 
    { CODEC_ID_H263      , 242 },
103
 
    { CODEC_ID_H261      , 243 },
104
 
    { 0, 0 },
105
 
};
106
 
 
107
66
static const CodecTag mov_video_tags[] = {
108
67
/*  { CODEC_ID_, MKTAG('c', 'v', 'i', 'd') }, *//* Cinepak */
109
68
/*  { CODEC_ID_H263, MKTAG('r', 'a', 'w', ' ') }, *//* Uncompressed RGB */
116
75
    { CODEC_ID_MJPEG, MKTAG('j', 'p', 'e', 'g') }, /* PhotoJPEG */
117
76
    { CODEC_ID_MPEG1VIDEO, MKTAG('m', 'p', 'e', 'g') }, /* MPEG */
118
77
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'a') }, /* Motion-JPEG (format A) */
119
 
    { CODEC_ID_MJPEG, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */
 
78
    { CODEC_ID_MJPEGB, MKTAG('m', 'j', 'p', 'b') }, /* Motion-JPEG (format B) */
120
79
    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'D', 'J') }, /* MJPEG with alpha-channel (AVID JFIF meridien compressed) */
121
80
/*    { CODEC_ID_MJPEG, MKTAG('A', 'V', 'R', 'n') }, *//* MJPEG with alpha-channel (AVID ABVB/Truevision NuVista) */
122
81
/*    { CODEC_ID_GIF, MKTAG('g', 'i', 'f', ' ') }, *//* embedded gif files as frames (usually one "click to play movie" frame) */
134
93
    { CODEC_ID_H263, MKTAG('s', '2', '6', '3') }, /* H263 ?? works */
135
94
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', ' ') }, /* DV NTSC */
136
95
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'c', 'p') }, /* DV PAL */
137
 
/*    { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, *//* AVID dv */
138
96
    { CODEC_ID_VP3, MKTAG('V', 'P', '3', '1') }, /* On2 VP3 */
139
97
    { CODEC_ID_RPZA, MKTAG('r', 'p', 'z', 'a') }, /* Apple Video (RPZA) */
140
98
    { CODEC_ID_CINEPAK, MKTAG('c', 'v', 'i', 'd') }, /* Cinepak */
154
112
    //{ CODEC_ID_DVVIDEO, MKTAG('d', 'v', 'h', '6') }, /* DVCPRO HD 60i produced by FCP */
155
113
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'p') }, /* DVCPRO50 PAL produced by FCP */
156
114
    { CODEC_ID_DVVIDEO, MKTAG('d', 'v', '5', 'n') }, /* DVCPRO50 NTSC produced by FCP */
 
115
    { CODEC_ID_DVVIDEO, MKTAG('A', 'V', 'd', 'v') }, /* AVID DV */
157
116
    //{ CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */
 
117
    { CODEC_ID_RAWVIDEO, MKTAG('2', 'v', 'u', 'y') }, /* UNCOMPRESSED 8BIT 4:2:2 */
158
118
    { CODEC_ID_NONE, 0 },
159
119
};
160
120
 
161
121
static const CodecTag mov_audio_tags[] = {
162
122
    { CODEC_ID_PCM_S32BE, MKTAG('i', 'n', '3', '2') },
163
123
    { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') },
164
 
/*    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, *//* uncompressed */
 
124
    { CODEC_ID_PCM_S16BE, MKTAG('N', 'O', 'N', 'E') }, /* uncompressed */
165
125
    { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, /* 16 bits */
166
 
    /* { CODEC_ID_PCM_S8, MKTAG('t', 'w', 'o', 's') },*/ /* 8 bits */
167
126
    { CODEC_ID_PCM_U8, MKTAG('r', 'a', 'w', ' ') }, /* 8 bits unsigned */
168
127
    { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, /*  */
169
128
    { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, /*  */
170
129
    { CODEC_ID_PCM_ALAW, MKTAG('a', 'l', 'a', 'w') }, /*  */
171
130
    { CODEC_ID_ADPCM_IMA_QT, MKTAG('i', 'm', 'a', '4') }, /* IMA-4 ADPCM */
 
131
    { CODEC_ID_ADPCM_MS, MKTAG('m', 's', 0x00, 0x02) }, /* MS ADPCM */
172
132
    { CODEC_ID_MACE3, MKTAG('M', 'A', 'C', '3') }, /* Macintosh Audio Compression and Expansion 3:1 */
173
133
    { CODEC_ID_MACE6, MKTAG('M', 'A', 'C', '6') }, /* Macintosh Audio Compression and Expansion 6:1 */
174
134
 
175
 
    { CODEC_ID_MP2, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */
 
135
    { CODEC_ID_MP3, MKTAG('.', 'm', 'p', '3') }, /* MPEG layer 3 */ /* sample files at http://www.3ivx.com/showcase.html use this tag */
176
136
    { CODEC_ID_MP2, 0x6D730055 }, /* MPEG layer 3 */
177
137
    { CODEC_ID_MP2, 0x5500736D }, /* MPEG layer 3 *//* XXX: check endianness */
178
138
/*    { CODEC_ID_OGG_VORBIS, MKTAG('O', 'g', 'g', 'S') }, *//* sample files at http://heroinewarrior.com/xmovie.php3 use this tag */
187
147
    { CODEC_ID_NONE, 0 },
188
148
};
189
149
 
190
 
/* map numeric codes from mdhd atom to ISO 639 */
191
 
/* cf. QTFileFormat.pdf p253, qtff.pdf p205 */
192
 
/* http://developer.apple.com/documentation/mac/Text/Text-368.html */
193
 
/* deprecated by putting the code as 3*5bit ascii */
194
 
static const char *mov_mdhd_language_map[] = {
195
 
/* 0-9 */
196
 
"eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
197
 
"heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/,
198
 
"urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav",  NULL,
199
 
"fo ",  NULL, "rus", "chi",  NULL, "iri", "alb", "ron", "ces", "slk",
200
 
"slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
201
 
/*?*/
202
 
"aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon",  NULL, "pus",
203
 
"kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
204
 
"pa ", "ori", "mal", "kan", "tam", "tel",  NULL, "bur", "khm", "lao",
205
 
/*                   roman? arabic? */
206
 
"vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
207
 
/*==rundi?*/
208
 
 NULL, "run",  NULL, "mlg", "epo",  NULL,  NULL,  NULL,  NULL,  NULL,
209
 
/* 100 */
210
 
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
211
 
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,
212
 
 NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL,  NULL, "wel", "baq",
213
 
"cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
214
 
};
215
 
 
216
150
/* the QuickTime file format is quite convoluted...
217
151
 * it has lots of index tables, each indexing something in another one...
218
152
 * Here we just use what is needed to read the chunks
237
171
    void* clrs;
238
172
} MOV_ctab_t;
239
173
 
 
174
typedef struct MOV_mdat_atom_s {
 
175
    offset_t offset;
 
176
    int64_t size;
 
177
} MOV_mdat_atom_t;
 
178
 
240
179
typedef struct {
241
180
    uint8_t  version;
242
181
    uint32_t flags; // 24bit
289
228
 
290
229
typedef struct MOVStreamContext {
291
230
    int ffindex; /* the ffmpeg stream id */
292
 
    int is_ff_stream; /* Is this stream presented to ffmpeg ? i.e. is this an audio or video stream ? */
293
231
    long next_chunk;
294
232
    long chunk_count;
295
233
    int64_t *chunk_offsets;
300
238
    int edit_count;             /* number of 'edit' (elst atom) */
301
239
    long sample_to_chunk_sz;
302
240
    MOV_sample_to_chunk_tbl *sample_to_chunk;
303
 
    long sample_to_chunk_index;
304
 
    int sample_to_time_index;
305
 
    long sample_to_time_sample;
306
 
    uint64_t sample_to_time_time;
307
241
    int sample_to_ctime_index;
308
242
    int sample_to_ctime_sample;
309
243
    long sample_size;
314
248
    int time_scale;
315
249
    int time_rate;
316
250
    long current_sample;
317
 
    long left_in_chunk; /* how many samples before next chunk */
318
251
    MOV_esds_t esds;
 
252
    AVRational sample_size_v1;
319
253
} MOVStreamContext;
320
254
 
321
255
typedef struct MOVContext {
327
261
    int found_mdat; /* we suppose we have enough data to read the file */
328
262
    int64_t mdat_size;
329
263
    int64_t mdat_offset;
330
 
    int ni;                                         ///< non interleaved mode
331
264
    int total_streams;
332
265
    /* some streams listed here aren't presented to the ffmpeg API, since they aren't either video nor audio
333
266
     * but we need the info to be able to skip data from those streams in the 'mdat' section
334
267
     */
335
268
    MOVStreamContext *streams[MAX_STREAMS];
336
269
 
337
 
    int64_t next_chunk_offset;
338
 
    MOVStreamContext *partial; /* != 0 : there is still to read in the current chunk */
339
270
    int ctab_size;
340
271
    MOV_ctab_t **ctab;           /* color tables */
341
272
    const struct MOVParseTableEntry *parse_table; /* could be eventually used to change the table */
342
273
    /* NOTE: for recursion save to/ restore from local variable! */
343
274
 
344
275
    AVPaletteControl palette_control;
 
276
    MOV_mdat_atom_t *mdat_list;
 
277
    int mdat_count;
345
278
} MOVContext;
346
279
 
347
280
 
361
294
    mov_parse_function func;
362
295
} MOVParseTableEntry;
363
296
 
364
 
static int ff_mov_lang_to_iso639(int code, char *to)
365
 
{
366
 
    int i;
367
 
    /* is it the mangled iso code? */
368
 
    /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */
369
 
    if (code > 138) {
370
 
        for (i = 2; i >= 0; i--) {
371
 
            to[i] = 0x60 + (code & 0x1f);
372
 
            code >>= 5;
373
 
        }
374
 
        return 1;
375
 
    }
376
 
    /* old fashion apple lang code */
377
 
    if (code >= (sizeof(mov_mdhd_language_map)/sizeof(char *)))
378
 
        return 0;
379
 
    if (!mov_mdhd_language_map[code])
380
 
        return 0;
381
 
    strncpy(to, mov_mdhd_language_map[code], 4);
382
 
    return 1;
383
 
}
384
 
 
385
 
extern int ff_mov_iso639_to_lang(const char *lang, int mp4); /* for movenc.c */
386
 
int ff_mov_iso639_to_lang(const char *lang, int mp4)
387
 
{
388
 
    int i, code = 0;
389
 
 
390
 
    /* old way, only for QT? */
391
 
    for (i = 0; !mp4 && (i < (sizeof(mov_mdhd_language_map)/sizeof(char *))); i++) {
392
 
        if (mov_mdhd_language_map[i] && !strcmp(lang, mov_mdhd_language_map[i]))
393
 
            return i;
394
 
    }
395
 
    /* XXX:can we do that in mov too? */
396
 
    if (!mp4)
397
 
        return 0;
398
 
    /* handle undefined as such */
399
 
    if (lang[0] == '\0')
400
 
        lang = "und";
401
 
    /* 5bit ascii */
402
 
    for (i = 0; i < 3; i++) {
403
 
        unsigned char c = (unsigned char)lang[i];
404
 
        if (c < 0x60)
405
 
            return 0;
406
 
        if (c > 0x60 + 0x1f)
407
 
            return 0;
408
 
        code <<= 5;
409
 
        code |= (c - 0x60);
410
 
    }
411
 
    return code;
412
 
}
413
 
 
414
297
static int mov_read_leaf(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
415
298
{
416
299
    if (atom.size>1)
462
345
        if (c->parse_table[i].type == 0) { /* skip leaf atoms data */
463
346
            url_fskip(pb, a.size);
464
347
        } else {
 
348
            offset_t start_pos = url_ftell(pb);
 
349
            int64_t left;
465
350
            err = (c->parse_table[i].func)(c, pb, a);
 
351
            left = a.size - url_ftell(pb) + start_pos;
 
352
            if (left > 0) /* skip garbage at atom end */
 
353
                url_fskip(pb, left);
466
354
        }
467
355
 
468
356
        a.offset += a.size;
572
460
{
573
461
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
574
462
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
575
 
    int64_t start_pos = url_ftell(pb);
576
463
    int tag, len;
577
464
 
578
465
    /* Well, broken but suffisant for some MP4 streams */
593
480
        sc->esds.avg_bitrate = get_be32(pb);
594
481
 
595
482
        st->codec->codec_id= codec_get_id(ff_mov_obj_type, sc->esds.object_type_id);
 
483
        dprintf("esds object type id %d\n", sc->esds.object_type_id);
596
484
        len = mov_mp4_read_descr(pb, &tag);
597
485
        if (tag == MP4DecSpecificDescrTag) {
598
486
            dprintf("Specific MPEG4 header len=%d\n", len);
607
495
            }
608
496
        }
609
497
    }
610
 
    /* in any case, skip garbage */
611
 
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
612
498
    return 0;
613
499
}
614
500
 
617
503
{
618
504
    if(atom.size == 0) /* wrong one (MP4) */
619
505
        return 0;
 
506
    c->mdat_list = av_realloc(c->mdat_list, (c->mdat_count + 1) * sizeof(*c->mdat_list));
 
507
    c->mdat_list[c->mdat_count].offset = atom.offset;
 
508
    c->mdat_list[c->mdat_count].size = atom.size;
 
509
    c->mdat_count++;
620
510
    c->found_mdat=1;
621
511
    c->mdat_offset = atom.offset;
622
512
    c->mdat_size = atom.size;
802
692
 
803
693
static int mov_read_wave(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
804
694
{
805
 
    offset_t start_pos = url_ftell(pb);
806
695
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
807
696
 
808
697
    if((uint64_t)atom.size > (1<<30))
820
709
            url_fskip(pb, atom.size);
821
710
    } else if (atom.size > 8) { /* to read frma, esds atoms */
822
711
        mov_read_default(c, pb, atom);
823
 
    } else if (atom.size > 0)
 
712
    } else
824
713
        url_fskip(pb, atom.size);
825
 
    /* in any case, skip garbage */
826
 
    url_fskip(pb, atom.size - ((url_ftell(pb) - start_pos)));
827
714
    return 0;
828
715
}
829
716
 
897
784
    } else
898
785
        return -1;
899
786
 
900
 
    for(i=0; i<c->fc->nb_streams; i++){
901
 
        MOVStreamContext *sc2 = (MOVStreamContext *)c->fc->streams[i]->priv_data;
902
 
        if(sc2 && sc2->chunk_offsets){
903
 
            int64_t first= sc2->chunk_offsets[0];
904
 
            int64_t last= sc2->chunk_offsets[sc2->chunk_count-1];
905
 
            if(first >= sc->chunk_offsets[entries-1] || last <= sc->chunk_offsets[0])
906
 
                c->ni=1;
907
 
        }
908
 
    }
909
787
    return 0;
910
788
}
911
789
 
945
823
        get_be16(pb); /* reserved */
946
824
        get_be16(pb); /* index */
947
825
 
948
 
        dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
949
 
                size,
950
 
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
951
 
                st->codec->codec_type);
 
826
        if (st->codec->codec_tag) {
 
827
            /* multiple fourcc, just skip for now */
 
828
            url_fskip(pb, size - (url_ftell(pb) - start_pos));
 
829
            continue;
 
830
        }
 
831
 
952
832
        st->codec->codec_tag = format;
953
833
        id = codec_get_id(mov_audio_tags, format);
954
834
        if (id > 0) {
955
835
            st->codec->codec_type = CODEC_TYPE_AUDIO;
956
 
        } else if (format != MKTAG('m', 'p', '4', 's')) { /* skip old asf mpeg4 tag */
 
836
        } else if (format && format != MKTAG('m', 'p', '4', 's')) { /* skip old asf mpeg4 tag */
957
837
            id = codec_get_id(mov_video_tags, format);
958
838
            if (id <= 0)
959
839
                id = codec_get_id(codec_bmp_tags, format);
961
841
                st->codec->codec_type = CODEC_TYPE_VIDEO;
962
842
        }
963
843
 
 
844
        dprintf("size=%d 4CC= %c%c%c%c codec_type=%d\n",
 
845
                size,
 
846
                (format >> 0) & 0xff, (format >> 8) & 0xff, (format >> 16) & 0xff, (format >> 24) & 0xff,
 
847
                st->codec->codec_type);
 
848
 
964
849
        if(st->codec->codec_type==CODEC_TYPE_VIDEO) {
965
850
            st->codec->codec_id = id;
966
851
            get_be16(pb); /* version */
968
853
            get_be32(pb); /* vendor */
969
854
            get_be32(pb); /* temporal quality */
970
855
            get_be32(pb); /* spacial quality */
971
 
            if(st->codec->codec_id == CODEC_ID_MPEG4){ //FIXME this is silly
972
 
                get_be16(pb);
973
 
                get_be16(pb);
974
 
            }else{
975
 
                st->codec->width = get_be16(pb); /* width */
976
 
                st->codec->height = get_be16(pb); /* height */
977
 
            }
 
856
 
 
857
            st->codec->width = get_be16(pb); /* width */
 
858
            st->codec->height = get_be16(pb); /* height */
 
859
 
978
860
            get_be32(pb); /* horiz resolution */
979
861
            get_be32(pb); /* vert resolution */
980
862
            get_be32(pb); /* data size, always 0 */
991
873
            st->codec->bits_per_sample = get_be16(pb); /* depth */
992
874
            st->codec->color_table_id = get_be16(pb); /* colortable id */
993
875
 
994
 
/*          These are set in mov_read_stts and might already be set!
995
 
            st->codec->time_base.den      = 25;
996
 
            st->codec->time_base.num = 1;
997
 
*/
998
 
 
999
876
            /* figure out the palette situation */
1000
877
            color_depth = st->codec->bits_per_sample & 0x1F;
1001
878
            color_greyscale = st->codec->bits_per_sample & 0x20;
1066
943
            } else
1067
944
                st->codec->palctrl = NULL;
1068
945
        } else if(st->codec->codec_type==CODEC_TYPE_AUDIO) {
 
946
            int bits_per_sample;
1069
947
            uint16_t version = get_be16(pb);
1070
948
 
1071
949
            st->codec->codec_id = id;
1073
951
            get_be32(pb); /* vendor */
1074
952
 
1075
953
            st->codec->channels = get_be16(pb);             /* channel count */
 
954
            dprintf("audio channels %d\n", st->codec->channels);
1076
955
            st->codec->bits_per_sample = get_be16(pb);      /* sample size */
1077
956
            /* do we need to force to 16 for AMR ? */
1078
957
 
1083
962
            st->codec->sample_rate = ((get_be32(pb) >> 16));
1084
963
 
1085
964
            switch (st->codec->codec_id) {
 
965
            case CODEC_ID_PCM_S8:
 
966
            case CODEC_ID_PCM_U8:
 
967
                if (st->codec->bits_per_sample == 16)
 
968
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
 
969
                break;
1086
970
            case CODEC_ID_PCM_S16LE:
1087
971
            case CODEC_ID_PCM_S16BE:
1088
972
                if (st->codec->bits_per_sample == 8)
1089
973
                    st->codec->codec_id = CODEC_ID_PCM_S8;
1090
 
                st->codec->bit_rate = st->codec->sample_rate * 8;
1091
 
                break;
1092
 
            case CODEC_ID_PCM_U8:
1093
 
                if (st->codec->bits_per_sample == 16)
1094
 
                    st->codec->codec_id = CODEC_ID_PCM_S16BE;
1095
 
                st->codec->bit_rate = st->codec->sample_rate * 8;
1096
974
                break;
1097
975
            case CODEC_ID_AMR_WB:
1098
976
                st->codec->sample_rate = 16000; /* should really we ? */
1106
984
                break;
1107
985
            }
1108
986
 
 
987
            bits_per_sample = av_get_bits_per_sample(st->codec->codec_id);
 
988
            if (bits_per_sample) {
 
989
                st->codec->bits_per_sample = bits_per_sample;
 
990
                sc->sample_size = (bits_per_sample >> 3) * st->codec->channels;
 
991
            }
 
992
 
1109
993
            //Read QT version 1 fields. In version 0 theese dont exist
1110
994
            dprintf("version =%d mp4=%d\n",version,c->mp4);
1111
995
            if(version==1) {
1112
 
                get_be32(pb); /* samples per packet */
 
996
                sc->sample_size_v1.den = get_be32(pb); /* samples per packet */
1113
997
                get_be32(pb); /* bytes per packet */
1114
 
                get_be32(pb); /* bytes per frame */
 
998
                sc->sample_size_v1.num = get_be32(pb); /* bytes per frame */
1115
999
                get_be32(pb); /* bytes per sample */
1116
1000
            } else if(version==2) {
1117
1001
                get_be32(pb); /* sizeof struct only */
1219
1103
{
1220
1104
    AVStream *st = c->fc->streams[c->fc->nb_streams-1];
1221
1105
    MOVStreamContext *sc = (MOVStreamContext *)st->priv_data;
1222
 
    unsigned int i, entries;
 
1106
    unsigned int i, entries, sample_size;
1223
1107
 
1224
1108
    get_byte(pb); /* version */
1225
1109
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1226
1110
 
1227
 
    sc->sample_size = get_be32(pb);
 
1111
    sample_size = get_be32(pb);
 
1112
    if (!sc->sample_size) /* do not overwrite value computed in stsd */
 
1113
        sc->sample_size = sample_size;
1228
1114
    entries = get_be32(pb);
1229
1115
    if(entries >= UINT_MAX / sizeof(long))
1230
1116
        return -1;
1231
1117
 
1232
1118
    sc->sample_count = entries;
 
1119
    if (sample_size)
 
1120
        return 0;
 
1121
 
1233
1122
#ifdef DEBUG
1234
1123
    av_log(NULL, AV_LOG_DEBUG, "sample_size = %ld sample_count = %ld\n", sc->sample_size, sc->sample_count);
1235
1124
#endif
1236
 
    if(sc->sample_size) {
1237
 
        /* override sample size for uncompressed sound */
1238
 
        switch (st->codec->codec_id) {
1239
 
        case CODEC_ID_PCM_S32BE:
1240
 
        case CODEC_ID_PCM_S32LE:
1241
 
            sc->sample_size = 4 * st->codec->channels;
1242
 
            break;
1243
 
        case CODEC_ID_PCM_S24BE:
1244
 
        case CODEC_ID_PCM_S24LE:
1245
 
            sc->sample_size = 3 * st->codec->channels;
1246
 
            break;
1247
 
        case CODEC_ID_PCM_S16BE:
1248
 
        case CODEC_ID_PCM_S16LE:
1249
 
            sc->sample_size = 2 * st->codec->channels;
1250
 
            break;
1251
 
        case CODEC_ID_PCM_MULAW:
1252
 
        case CODEC_ID_PCM_ALAW:
1253
 
        case CODEC_ID_PCM_S8:
1254
 
        case CODEC_ID_PCM_U8:
1255
 
            sc->sample_size = 1 * st->codec->channels;
1256
 
            break;
1257
 
        default:
1258
 
            break;
1259
 
        }
1260
 
        assert(sc->sample_size);
1261
 
        return 0; /* there isn't any table following */
1262
 
    }
1263
1125
    sc->sample_sizes = (long*) av_malloc(entries * sizeof(long));
1264
1126
    if (!sc->sample_sizes)
1265
1127
        return -1;
1366
1228
        return -1;
1367
1229
    }
1368
1230
 
1369
 
    sc->sample_to_chunk_index = -1;
1370
1231
    st->priv_data = sc;
1371
 
    st->codec->codec_type = CODEC_TYPE_MOV_OTHER;
 
1232
    st->codec->codec_type = CODEC_TYPE_DATA;
1372
1233
    st->start_time = 0; /* XXX: check */
1373
1234
    c->streams[c->fc->nb_streams-1] = sc;
1374
1235
 
1411
1272
    url_fskip(pb, 36); /* display matrix */
1412
1273
 
1413
1274
    /* those are fixed-point */
1414
 
    /*st->codec->width =*/ get_be32(pb) >> 16; /* track width */
1415
 
    /*st->codec->height =*/ get_be32(pb) >> 16; /* track height */
 
1275
    get_be32(pb); /* track width */
 
1276
    get_be32(pb); /* track height */
1416
1277
 
1417
1278
    return 0;
1418
1279
}
1500
1361
/* edit list atom */
1501
1362
static int mov_read_elst(MOVContext *c, ByteIOContext *pb, MOV_atom_t atom)
1502
1363
{
1503
 
  int i, edit_count;
1504
 
 
1505
 
  get_byte(pb); /* version */
1506
 
  get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
1507
 
  edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
1508
 
 
1509
 
  for(i=0; i<edit_count; i++){
1510
 
    get_be32(pb); /* Track duration */
1511
 
    get_be32(pb); /* Media time */
1512
 
    get_be32(pb); /* Media rate */
1513
 
  }
1514
 
  dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
1515
 
  return 0;
 
1364
    int i, edit_count;
 
1365
 
 
1366
    get_byte(pb); /* version */
 
1367
    get_byte(pb); get_byte(pb); get_byte(pb); /* flags */
 
1368
    edit_count= c->streams[c->fc->nb_streams-1]->edit_count = get_be32(pb);     /* entries */
 
1369
 
 
1370
    for(i=0; i<edit_count; i++){
 
1371
        get_be32(pb); /* Track duration */
 
1372
        get_be32(pb); /* Media time */
 
1373
        get_be32(pb); /* Media rate */
 
1374
    }
 
1375
    dprintf("track[%i].edit_count = %i\n", c->fc->nb_streams-1, c->streams[c->fc->nb_streams-1]->edit_count);
 
1376
    return 0;
1516
1377
}
1517
1378
 
1518
1379
static const MOVParseTableEntry mov_default_parse_table[] = {
1601
1462
static void mov_free_stream_context(MOVStreamContext *sc)
1602
1463
{
1603
1464
    if(sc) {
1604
 
        av_freep(&sc->chunk_offsets);
1605
 
        av_freep(&sc->sample_to_chunk);
1606
 
        av_freep(&sc->sample_sizes);
1607
 
        av_freep(&sc->keyframes);
1608
 
        av_freep(&sc->stts_data);
1609
1465
        av_freep(&sc->ctts_data);
1610
1466
        av_freep(&sc);
1611
1467
    }
1612
1468
}
1613
1469
 
1614
 
static inline uint32_t mov_to_tag(uint8_t *buf)
1615
 
{
1616
 
    return MKTAG(buf[0], buf[1], buf[2], buf[3]);
1617
 
}
1618
 
 
1619
 
static inline uint32_t to_be32(uint8_t *buf)
1620
 
{
1621
 
    return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
1622
 
}
1623
 
 
1624
1470
/* XXX: is it sufficient ? */
1625
1471
static int mov_probe(AVProbeData *p)
1626
1472
{
1636
1482
        /* ignore invalid offset */
1637
1483
        if ((offset + 8) > (unsigned int)p->buf_size)
1638
1484
            return score;
1639
 
        tag = mov_to_tag(p->buf + offset + 4);
 
1485
        tag = LE_32(p->buf + offset + 4);
1640
1486
        switch(tag) {
1641
1487
        /* check for obvious tags */
1642
1488
        case MKTAG( 'j', 'P', ' ', ' ' ): /* jpeg 2000 signature */
1654
1500
        case MKTAG( 'f', 't', 'y', 'p' ):
1655
1501
        case MKTAG( 's', 'k', 'i', 'p' ):
1656
1502
        case MKTAG( 'u', 'u', 'i', 'd' ):
1657
 
            offset = to_be32(p->buf+offset) + offset;
 
1503
            offset = BE_32(p->buf+offset) + offset;
1658
1504
            /* if we only find those cause probedata is too small at least rate them */
1659
1505
            score = AVPROBE_SCORE_MAX - 50;
1660
1506
            break;
1666
1512
    return score;
1667
1513
}
1668
1514
 
 
1515
static void mov_build_index(MOVContext *mov, AVStream *st)
 
1516
{
 
1517
    MOVStreamContext *sc = st->priv_data;
 
1518
    offset_t current_offset;
 
1519
    int64_t current_dts = 0;
 
1520
    int stts_index = 0;
 
1521
    int stsc_index = 0;
 
1522
    int stss_index = 0;
 
1523
    int i, j, k;
 
1524
 
 
1525
    if (sc->sample_sizes || st->codec->codec_type == CODEC_TYPE_VIDEO) {
 
1526
        int keyframe, sample_size;
 
1527
        int current_sample = 0;
 
1528
        int stts_sample = 0;
 
1529
        int distance = 0;
 
1530
 
 
1531
        st->nb_frames = sc->sample_count;
 
1532
        for (i = 0; i < sc->chunk_count; i++) {
 
1533
            current_offset = sc->chunk_offsets[i];
 
1534
            if (stsc_index + 1 < sc->sample_to_chunk_sz && i + 1 == sc->sample_to_chunk[stsc_index + 1].first)
 
1535
                stsc_index++;
 
1536
            for (j = 0; j < sc->sample_to_chunk[stsc_index].count; j++) {
 
1537
                keyframe = !sc->keyframe_count || current_sample + 1 == sc->keyframes[stss_index];
 
1538
                if (keyframe) {
 
1539
                    distance = 0;
 
1540
                    if (stss_index + 1 < sc->keyframe_count)
 
1541
                        stss_index++;
 
1542
                }
 
1543
                sample_size = sc->sample_size > 0 ? sc->sample_size : sc->sample_sizes[current_sample];
 
1544
                dprintf("AVIndex stream %d, sample %d, offset %llx, dts %lld, size %d, distance %d, keyframe %d\n",
 
1545
                        st->index, current_sample, current_offset, current_dts, sample_size, distance, keyframe);
 
1546
                av_add_index_entry(st, current_offset, current_dts, sample_size, distance, keyframe ? AVINDEX_KEYFRAME : 0);
 
1547
                current_offset += sample_size;
 
1548
                assert(sc->stts_data[stts_index].duration % sc->time_rate == 0);
 
1549
                current_dts += sc->stts_data[stts_index].duration / sc->time_rate;
 
1550
                distance++;
 
1551
                stts_sample++;
 
1552
                if (current_sample + 1 < sc->sample_count)
 
1553
                    current_sample++;
 
1554
                if (stts_index + 1 < sc->stts_count && stts_sample == sc->stts_data[stts_index].count) {
 
1555
                    stts_sample = 0;
 
1556
                    stts_index++;
 
1557
                }
 
1558
            }
 
1559
        }
 
1560
    } else { /* read whole chunk */
 
1561
        int chunk_samples, chunk_size, chunk_duration;
 
1562
 
 
1563
        for (i = 0; i < sc->chunk_count; i++) {
 
1564
            current_offset = sc->chunk_offsets[i];
 
1565
            if (stsc_index + 1 < sc->sample_to_chunk_sz && i + 1 == sc->sample_to_chunk[stsc_index + 1].first)
 
1566
                stsc_index++;
 
1567
            chunk_samples = sc->sample_to_chunk[stsc_index].count;
 
1568
            /* get chunk size */
 
1569
            if (sc->sample_size > 1 || st->codec->bits_per_sample == 8)
 
1570
                chunk_size = chunk_samples * sc->sample_size;
 
1571
            else if (sc->sample_size_v1.den > 0 && (chunk_samples * sc->sample_size_v1.num % sc->sample_size_v1.den == 0))
 
1572
                chunk_size = chunk_samples * sc->sample_size_v1.num / sc->sample_size_v1.den;
 
1573
            else { /* workaround to find nearest next chunk offset */
 
1574
                chunk_size = INT_MAX;
 
1575
                for (j = 0; j < mov->total_streams; j++) {
 
1576
                    MOVStreamContext *msc = mov->streams[j];
 
1577
 
 
1578
                    for (k = msc->next_chunk; k < msc->chunk_count; k++) {
 
1579
                        if (msc->chunk_offsets[k] > current_offset && msc->chunk_offsets[k] - current_offset < chunk_size) {
 
1580
                            chunk_size = msc->chunk_offsets[k] - current_offset;
 
1581
                            msc->next_chunk = k;
 
1582
                            break;
 
1583
                        }
 
1584
                    }
 
1585
                }
 
1586
                /* check for last chunk */
 
1587
                if (chunk_size == INT_MAX)
 
1588
                    for (j = 0; j < mov->mdat_count; j++) {
 
1589
                        dprintf("mdat %d, offset %llx, size %lld, current offset %llx\n",
 
1590
                                j, mov->mdat_list[j].offset, mov->mdat_list[j].size, current_offset);
 
1591
                        if (mov->mdat_list[j].offset <= current_offset && mov->mdat_list[j].offset + mov->mdat_list[j].size > current_offset)
 
1592
                            chunk_size = mov->mdat_list[j].offset + mov->mdat_list[j].size - current_offset;
 
1593
                    }
 
1594
                assert(chunk_size != INT_MAX);
 
1595
                for (j = 0; j < mov->total_streams; j++) {
 
1596
                    mov->streams[j]->next_chunk = 0;
 
1597
                }
 
1598
            }
 
1599
            av_add_index_entry(st, current_offset, current_dts, chunk_size, 0, AVINDEX_KEYFRAME);
 
1600
            /* get chunk duration */
 
1601
            chunk_duration = 0;
 
1602
            while (chunk_samples > 0) {
 
1603
                if (chunk_samples < sc->stts_data[stts_index].count) {
 
1604
                    chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;
 
1605
                    sc->stts_data[stts_index].count -= chunk_samples;
 
1606
                    break;
 
1607
                } else {
 
1608
                    chunk_duration += sc->stts_data[stts_index].duration * chunk_samples;
 
1609
                    chunk_samples -= sc->stts_data[stts_index].count;
 
1610
                    if (stts_index + 1 < sc->stts_count) {
 
1611
                        stts_index++;
 
1612
                    }
 
1613
                }
 
1614
            }
 
1615
            dprintf("AVIndex stream %d, chunk %d, offset %llx, dts %lld, size %d, duration %d\n",
 
1616
                    st->index, i, current_offset, current_dts, chunk_size, chunk_duration);
 
1617
            assert(chunk_duration % sc->time_rate == 0);
 
1618
            current_dts += chunk_duration / sc->time_rate;
 
1619
        }
 
1620
    }
 
1621
    /* adjust sample count to avindex entries */
 
1622
    sc->sample_count = st->nb_index_entries;
 
1623
}
 
1624
 
1669
1625
static int mov_read_header(AVFormatContext *s, AVFormatParameters *ap)
1670
1626
{
1671
1627
    MOVContext *mov = (MOVContext *) s->priv_data;
1672
1628
    ByteIOContext *pb = &s->pb;
1673
 
    int i, j, nb, err;
 
1629
    int i, err;
1674
1630
    MOV_atom_t atom = { 0, 0, 0 };
1675
1631
 
1676
1632
    mov->fc = s;
1694
1650
    if(!url_is_streamed(pb) && (url_ftell(pb) != mov->mdat_offset))
1695
1651
        url_fseek(pb, mov->mdat_offset, SEEK_SET);
1696
1652
 
1697
 
    mov->next_chunk_offset = mov->mdat_offset; /* initialise reading */
1698
 
    mov->total_streams = nb = s->nb_streams;
 
1653
    mov->total_streams = s->nb_streams;
1699
1654
 
1700
 
#if 1
1701
 
    for(i=0; i<s->nb_streams;) {
1702
 
        if(s->streams[i]->codec->codec_type == CODEC_TYPE_MOV_OTHER) {/* not audio, not video, delete */
1703
 
            av_free(s->streams[i]);
1704
 
            for(j=i+1; j<s->nb_streams; j++)
1705
 
                s->streams[j-1] = s->streams[j];
1706
 
            s->nb_streams--;
1707
 
        } else
1708
 
            i++;
1709
 
    }
1710
 
    for(i=0; i<s->nb_streams;i++) {
1711
 
        MOVStreamContext *sc = (MOVStreamContext *)s->streams[i]->priv_data;
 
1655
    for(i=0; i<mov->total_streams; i++) {
 
1656
        MOVStreamContext *sc = mov->streams[i];
1712
1657
 
1713
1658
        if(!sc->time_rate)
1714
1659
            sc->time_rate=1;
1720
1665
            assert(s->streams[i]->duration % sc->time_rate == 0);
1721
1666
            s->streams[i]->duration /= sc->time_rate;
1722
1667
        }
1723
 
 
1724
1668
        sc->ffindex = i;
1725
 
        sc->is_ff_stream = 1;
1726
 
    }
1727
 
#endif
 
1669
        mov_build_index(mov, s->streams[i]);
 
1670
    }
 
1671
 
 
1672
    for(i=0; i<mov->total_streams; i++) {
 
1673
        /* dont need those anymore */
 
1674
        av_freep(&mov->streams[i]->chunk_offsets);
 
1675
        av_freep(&mov->streams[i]->sample_to_chunk);
 
1676
        av_freep(&mov->streams[i]->sample_sizes);
 
1677
        av_freep(&mov->streams[i]->keyframes);
 
1678
        av_freep(&mov->streams[i]->stts_data);
 
1679
    }
 
1680
    av_freep(&mov->mdat_list);
1728
1681
    return 0;
1729
1682
}
1730
1683
 
1731
 
/* Yes, this is ugly... I didn't write the specs of QT :p */
1732
 
/* XXX:remove useless commented code sometime */
1733
1684
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
1734
1685
{
1735
 
    MOVContext *mov = (MOVContext *) s->priv_data;
1736
 
    MOVStreamContext *sc;
1737
 
    AVStream *st;
1738
 
    int64_t offset = INT64_MAX;
 
1686
    MOVContext *mov = s->priv_data;
 
1687
    MOVStreamContext *sc = 0;
 
1688
    AVIndexEntry *sample = 0;
1739
1689
    int64_t best_dts = INT64_MAX;
1740
 
    int i, a, b, m;
1741
 
    int next_sample= -99;
1742
 
    int size;
1743
 
    int idx;
1744
 
    size = 0x0FFFFFFF;
1745
 
 
1746
 
    if (mov->partial) {
1747
 
        sc = mov->partial;
1748
 
        idx = sc->sample_to_chunk_index;
1749
 
 
1750
 
        if (idx < 0) return 0;
1751
 
        dprintf("sc[ffid %d]->sample_size = %ld\n", sc->ffindex, sc->sample_size);
1752
 
        //size = sc->sample_sizes[sc->current_sample];
1753
 
        // that ain't working...
1754
 
        //size = (sc->sample_size)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1755
 
        size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1756
 
 
1757
 
        next_sample= sc->current_sample+1;
1758
 
 
1759
 
        sc->left_in_chunk--;
1760
 
 
1761
 
        if (sc->left_in_chunk <= 0)
1762
 
            mov->partial = 0;
1763
 
        offset = mov->next_chunk_offset;
1764
 
        /* extract the sample */
1765
 
 
1766
 
        goto readchunk;
1767
 
    }
1768
 
 
1769
 
again:
1770
 
    sc = 0;
1771
 
    if(offset == INT64_MAX)
1772
 
        best_dts= INT64_MAX;
1773
 
    for(i=0; i<mov->total_streams; i++) {
1774
 
        MOVStreamContext *msc = mov->streams[i];
1775
 
 
1776
 
        if ((msc->next_chunk < msc->chunk_count) && msc->next_chunk >= 0){
1777
 
            if (msc->sample_to_time_index < msc->stts_count && mov->ni) {
1778
 
                int64_t dts;
1779
 
                int index= msc->sample_to_time_index;
1780
 
                int sample= msc->sample_to_time_sample;
1781
 
                int time= msc->sample_to_time_time;
1782
 
                int duration = msc->stts_data[index].duration;
1783
 
                int count = msc->stts_data[index].count;
1784
 
                if (sample + count <= msc->current_sample) {
1785
 
                    sample += count;
1786
 
                    time   += count*duration;
1787
 
                    index ++;
1788
 
                    duration = msc->stts_data[index].duration;
1789
 
                }
1790
 
                dts = time + (msc->current_sample - sample) * (int64_t)duration;
1791
 
                dts = av_rescale(dts, AV_TIME_BASE, msc->time_scale);
1792
 
                dprintf("stream: %d dts: %"PRId64" best_dts: %"PRId64" offset: %"PRId64"\n", i, dts, best_dts, offset);
1793
 
                if(dts < best_dts){
1794
 
                    best_dts= dts;
1795
 
                    sc = msc;
1796
 
                    offset = msc->chunk_offsets[msc->next_chunk];
1797
 
                }
1798
 
            }else{
1799
 
                if ((msc->chunk_offsets[msc->next_chunk] < offset)) {
1800
 
                    sc = msc;
1801
 
                    offset = msc->chunk_offsets[msc->next_chunk];
1802
 
                }
1803
 
            }
1804
 
        }
1805
 
    }
1806
 
    if (!sc || offset==INT64_MAX)
1807
 
        return -1;
1808
 
 
1809
 
    sc->next_chunk++;
1810
 
 
1811
 
    if(mov->next_chunk_offset < offset) { /* some meta data */
1812
 
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1813
 
        mov->next_chunk_offset = offset;
1814
 
    }
1815
 
 
1816
 
    if(!sc->is_ff_stream || (s->streams[sc->ffindex]->discard >= AVDISCARD_ALL)) {
1817
 
        url_fskip(&s->pb, (offset - mov->next_chunk_offset));
1818
 
        mov->next_chunk_offset = offset;
1819
 
        offset = INT64_MAX;
1820
 
        goto again;
1821
 
    }
1822
 
 
1823
 
    /* now get the chunk size... */
1824
 
 
1825
 
    for(i=0; i<mov->total_streams; i++) {
1826
 
        MOVStreamContext *msc = mov->streams[i];
1827
 
        if ((msc->next_chunk < msc->chunk_count)
1828
 
            && msc->chunk_offsets[msc->next_chunk] - offset < size
1829
 
            && msc->chunk_offsets[msc->next_chunk] > offset)
1830
 
            size = msc->chunk_offsets[msc->next_chunk] - offset;
1831
 
    }
1832
 
 
1833
 
#ifdef MOV_MINOLTA_FIX
1834
 
    //Make sure that size is according to sample_size (Needed by .mov files
1835
 
    //created on a Minolta Dimage Xi where audio chunks contains waste data in the end)
1836
 
    //Maybe we should really not only check sc->sample_size, but also sc->sample_sizes
1837
 
    //but I have no such movies
1838
 
    if (sc->sample_size > 0) {
1839
 
        int foundsize=0;
1840
 
        for(i=0; i<(sc->sample_to_chunk_sz); i++) {
1841
 
            if( (sc->sample_to_chunk[i].first)<=(sc->next_chunk) )
1842
 
            {
1843
 
                foundsize=sc->sample_to_chunk[i].count*sc->sample_size;
1844
 
            }
1845
 
            dprintf("sample_to_chunk first=%ld count=%ld, id=%ld\n", sc->sample_to_chunk[i].first, sc->sample_to_chunk[i].count, sc->sample_to_chunk[i].id);
1846
 
        }
1847
 
        if( (foundsize>0) && (foundsize<size) )
1848
 
        {
1849
 
            size=foundsize;
1850
 
        }
1851
 
    }
1852
 
#endif //MOV_MINOLTA_FIX
1853
 
 
1854
 
    idx = sc->sample_to_chunk_index;
1855
 
    if (idx + 1 < sc->sample_to_chunk_sz && sc->next_chunk >= sc->sample_to_chunk[idx + 1].first)
1856
 
        idx++;
1857
 
    sc->sample_to_chunk_index = idx;
1858
 
    /* split chunks into samples */
1859
 
    if (sc->sample_size == 0 || sc->sample_size > 100) {
1860
 
        if (idx >= 0 && sc->sample_to_chunk[idx].count != 1) {
1861
 
            mov->partial = sc;
1862
 
            /* we'll have to get those samples before next chunk */
1863
 
            sc->left_in_chunk = sc->sample_to_chunk[idx].count - 1;
1864
 
            size = (sc->sample_size > 1)?sc->sample_size:sc->sample_sizes[sc->current_sample];
1865
 
        }
1866
 
 
1867
 
        next_sample= sc->current_sample+1;
1868
 
    }else if(idx < sc->sample_to_chunk_sz){
1869
 
        next_sample= sc->current_sample + sc->sample_to_chunk[idx].count;
1870
 
    }else
1871
 
        next_sample= sc->current_sample;
1872
 
 
1873
 
readchunk:
1874
 
    dprintf("chunk: %"PRId64" -> %"PRId64" (%i)\n", offset, offset + size, size);
1875
 
    if(size == 0x0FFFFFFF)
1876
 
        size = mov->mdat_size + mov->mdat_offset - offset;
1877
 
    if(size < 0)
1878
 
        return -1;
1879
 
    if(size == 0)
1880
 
        return -1;
1881
 
    url_fseek(&s->pb, offset, SEEK_SET);
1882
 
 
1883
 
    av_get_packet(&s->pb, pkt, size);
 
1690
    int i;
 
1691
 
 
1692
    for (i = 0; i < mov->total_streams; i++) {
 
1693
        MOVStreamContext *msc = mov->streams[i];
 
1694
 
 
1695
        if (s->streams[i]->discard != AVDISCARD_ALL && msc->current_sample < msc->sample_count) {
 
1696
            AVIndexEntry *current_sample = &s->streams[i]->index_entries[msc->current_sample];
 
1697
            int64_t dts = av_rescale(current_sample->timestamp * (int64_t)msc->time_rate, AV_TIME_BASE, msc->time_scale);
 
1698
 
 
1699
            dprintf("stream %d, sample %ld, dts %lld\n", i, msc->current_sample, dts);
 
1700
            if (dts < best_dts) {
 
1701
                sample = current_sample;
 
1702
                best_dts = dts;
 
1703
                sc = msc;
 
1704
            }
 
1705
        }
 
1706
    }
 
1707
    if (!sample)
 
1708
        return -1;
 
1709
    /* must be done just before reading, to avoid infinite loop on sample */
 
1710
    sc->current_sample++;
 
1711
    if (sample->pos >= url_fsize(&s->pb)) {
 
1712
        av_log(mov->fc, AV_LOG_ERROR, "stream %d, offset 0x%llx: partial file\n", sc->ffindex, sample->pos);
 
1713
        return -1;
 
1714
    }
 
1715
    url_fseek(&s->pb, sample->pos, SEEK_SET);
 
1716
    av_get_packet(&s->pb, pkt, sample->size);
1884
1717
    pkt->stream_index = sc->ffindex;
1885
 
 
1886
 
    // If the keyframes table exists, mark any samples that are in the table as key frames.
1887
 
    // If no table exists, treat very sample as a key frame.
1888
 
    if (sc->keyframes) {
1889
 
        a = 0;
1890
 
        b = sc->keyframe_count - 1;
1891
 
 
1892
 
        while (a < b) {
1893
 
            m = (a + b + 1) >> 1;
1894
 
            if (sc->keyframes[m] > sc->current_sample) {
1895
 
                b = m - 1;
1896
 
            } else {
1897
 
                a = m;
1898
 
            }
 
1718
    pkt->dts = sample->timestamp;
 
1719
    if (sc->ctts_data) {
 
1720
        assert(sc->ctts_data[sc->sample_to_ctime_index].duration % sc->time_rate == 0);
 
1721
        pkt->pts = pkt->dts + sc->ctts_data[sc->sample_to_ctime_index].duration / sc->time_rate;
 
1722
        /* update ctts context */
 
1723
        sc->sample_to_ctime_sample++;
 
1724
        if (sc->sample_to_ctime_index < sc->ctts_count && sc->ctts_data[sc->sample_to_ctime_index].count == sc->sample_to_ctime_sample) {
 
1725
            sc->sample_to_ctime_index++;
 
1726
            sc->sample_to_ctime_sample = 0;
1899
1727
        }
1900
 
 
1901
 
        if (sc->keyframes[a] == sc->current_sample)
1902
 
            pkt->flags |= PKT_FLAG_KEY;
1903
 
    }
1904
 
    else
1905
 
        pkt->flags |= PKT_FLAG_KEY;
1906
 
 
1907
 
    mov->next_chunk_offset = offset + size;
1908
 
 
1909
 
    /* find the corresponding dts */
1910
 
    if (sc && sc->sample_to_time_index < sc->stts_count && pkt) {
1911
 
      unsigned int count;
1912
 
      uint64_t dts, pts;
1913
 
      unsigned int duration = sc->stts_data[sc->sample_to_time_index].duration;
1914
 
      count = sc->stts_data[sc->sample_to_time_index].count;
1915
 
      if ((sc->sample_to_time_sample + count) <= sc->current_sample) {
1916
 
        sc->sample_to_time_sample += count;
1917
 
        sc->sample_to_time_time   += count*duration;
1918
 
        sc->sample_to_time_index ++;
1919
 
        duration = sc->stts_data[sc->sample_to_time_index].duration;
1920
 
      }
1921
 
      dts = sc->sample_to_time_time + (sc->current_sample - sc->sample_to_time_sample) * (int64_t)duration;
1922
 
        /* find the corresponding pts */
1923
 
        if (sc->sample_to_ctime_index < sc->ctts_count) {
1924
 
            int duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1925
 
            int count = sc->ctts_data[sc->sample_to_ctime_index].count;
1926
 
 
1927
 
            if ((sc->sample_to_ctime_sample + count) <= sc->current_sample) {
1928
 
                sc->sample_to_ctime_sample += count;
1929
 
                sc->sample_to_ctime_index ++;
1930
 
                duration = sc->ctts_data[sc->sample_to_ctime_index].duration;
1931
 
            }
1932
 
            pts = dts + duration;
1933
 
        }else
1934
 
            pts = dts;
1935
 
 
1936
 
        st= s->streams[ sc->ffindex ];
1937
 
        assert(pts % st->time_base.num == 0);
1938
 
        assert(dts % st->time_base.num == 0);
1939
 
 
1940
 
        pkt->pts = pts / st->time_base.num;
1941
 
        pkt->dts = dts / st->time_base.num;
1942
 
        dprintf("stream #%d smp #%ld dts = %"PRId64" pts = %"PRId64" (smp:%ld time:%"PRId64" idx:%d ent:%d count:%d dur:%d)\n"
1943
 
                , pkt->stream_index, sc->current_sample-1, pkt->dts, pkt->pts
1944
 
                , sc->sample_to_time_sample
1945
 
                , sc->sample_to_time_time
1946
 
                , sc->sample_to_time_index
1947
 
                , sc->stts_count
1948
 
                , count
1949
 
                , duration);
1950
 
    }
1951
 
 
1952
 
    assert(next_sample>=0);
1953
 
    sc->current_sample= next_sample;
1954
 
 
 
1728
    } else {
 
1729
        pkt->pts = pkt->dts;
 
1730
    }
 
1731
    pkt->flags |= sample->flags & AVINDEX_KEYFRAME ? PKT_FLAG_KEY : 0;
 
1732
    pkt->pos = sample->pos;
 
1733
    dprintf("stream %d, pts %lld, dts %lld, pos 0x%llx, duration %d\n", pkt->stream_index, pkt->pts, pkt->dts, pkt->pos, pkt->duration);
1955
1734
    return 0;
1956
1735
}
1957
1736
 
1958
 
#if defined(MOV_SEEK)
1959
 
/**
1960
 
 * Seek method based on the one described in the Appendix C of QTFileFormat.pdf
1961
 
 */
 
1737
static int mov_seek_stream(AVStream *st, int64_t timestamp, int flags)
 
1738
{
 
1739
    MOVStreamContext *sc = st->priv_data;
 
1740
    int sample, time_sample;
 
1741
    int i;
 
1742
 
 
1743
    sample = av_index_search_timestamp(st, timestamp, flags);
 
1744
    dprintf("stream %d, timestamp %lld, sample %d\n", st->index, timestamp, sample);
 
1745
    if (sample < 0) /* not sure what to do */
 
1746
        return -1;
 
1747
    sc->current_sample = sample;
 
1748
    dprintf("stream %d, found sample %ld\n", st->index, sc->current_sample);
 
1749
    /* adjust ctts index */
 
1750
    if (sc->ctts_data) {
 
1751
        time_sample = 0;
 
1752
        for (i = 0; i < sc->ctts_count; i++) {
 
1753
            time_sample += sc->ctts_data[i].count;
 
1754
            if (time_sample >= sc->current_sample) {
 
1755
                sc->sample_to_ctime_index = i;
 
1756
                sc->sample_to_ctime_sample = time_sample - sc->current_sample;
 
1757
                break;
 
1758
            }
 
1759
        }
 
1760
    }
 
1761
    return sample;
 
1762
}
 
1763
 
1962
1764
static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_time, int flags)
1963
1765
{
1964
 
    MOVContext* mov = (MOVContext *) s->priv_data;
1965
 
    MOVStreamContext* sc;
1966
 
    int32_t i, a, b, m;
1967
 
    int64_t start_time;
1968
 
    int32_t seek_sample, sample;
1969
 
    int32_t duration;
1970
 
    int32_t count;
1971
 
    int32_t chunk;
1972
 
    int32_t left_in_chunk;
1973
 
    int64_t chunk_file_offset;
1974
 
    int64_t sample_file_offset;
1975
 
    int32_t first_chunk_sample;
1976
 
    int32_t sample_to_chunk_idx;
1977
 
    int sample_to_time_index;
1978
 
    long sample_to_time_sample = 0;
1979
 
    uint64_t sample_to_time_time = 0;
1980
 
    int mov_idx;
1981
 
 
1982
 
    // Find the corresponding mov stream
1983
 
    for (mov_idx = 0; mov_idx < mov->total_streams; mov_idx++)
1984
 
        if (mov->streams[mov_idx]->ffindex == stream_index)
1985
 
            break;
1986
 
    if (mov_idx == mov->total_streams) {
1987
 
        av_log(s, AV_LOG_ERROR, "mov: requested stream was not found in mov streams (idx=%i)\n", stream_index);
1988
 
        return -1;
1989
 
    }
1990
 
    sc = mov->streams[mov_idx];
1991
 
 
1992
 
    sample_time *= s->streams[stream_index]->time_base.num;
1993
 
 
1994
 
    // Step 1. Find the edit that contains the requested time (elst)
1995
 
    if (sc->edit_count && 0) {
1996
 
        // FIXME should handle edit list
1997
 
        av_log(s, AV_LOG_ERROR, "mov: does not handle seeking in files that contain edit list (c:%d)\n", sc->edit_count);
1998
 
        return -1;
1999
 
    }
2000
 
 
2001
 
    // Step 2. Find the corresponding sample using the Time-to-sample atom (stts) */
2002
 
    dprintf("Searching for time %li in stream #%i (time_scale=%i)\n", (long)sample_time, mov_idx, sc->time_scale);
2003
 
    start_time = 0; // FIXME use elst atom
2004
 
    sample = 1; // sample are 0 based in table
2005
 
 
2006
 
    for (i = 0; i < sc->stts_count; i++) {
2007
 
        count = sc->stts_data[i].count;
2008
 
        duration = sc->stts_data[i].duration;
2009
 
        if ((start_time + count*duration) > sample_time) {
2010
 
            sample_to_time_time = start_time;
2011
 
            sample_to_time_index = i;
2012
 
            sample_to_time_sample = sample;
2013
 
            sample += (sample_time - start_time) / duration;
2014
 
            break;
2015
 
        }
2016
 
        sample += count;
2017
 
        start_time += count * duration;
2018
 
    }
2019
 
    sample_to_time_time = start_time;
2020
 
    sample_to_time_index = i;
2021
 
    /* NOTE: despite what qt doc say, the dt value (Display Time in qt vocabulary) computed with the stts atom
2022
 
       is a decoding time stamp (dts) not a presentation time stamp. And as usual dts != pts for stream with b frames */
2023
 
 
2024
 
    dprintf("Found time %li at sample #%u\n", (long)sample_time, sample);
2025
 
    if (sample > sc->sample_count) {
2026
 
        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);
2027
 
        return -1;
2028
 
    }
2029
 
 
2030
 
    // Step 3. Find the prior sync. sample using the Sync sample atom (stss)
2031
 
    if (sc->keyframes) {
2032
 
        a = 0;
2033
 
        b = sc->keyframe_count - 1;
2034
 
        while (a < b) {
2035
 
            m = (a + b + 1) >> 1;
2036
 
            if (sc->keyframes[m] > sample) {
2037
 
                b = m - 1;
2038
 
            } else {
2039
 
                a = m;
2040
 
            }
2041
 
        }
2042
 
        // for low latency prob: always use the previous keyframe, just uncomment the next line
2043
 
        // if (a) a--;
2044
 
        seek_sample = sc->keyframes[a];
2045
 
    }
2046
 
    else
2047
 
        seek_sample = sample; // else all samples are key frames
2048
 
    dprintf("Found nearest keyframe at sample #%i \n", seek_sample);
2049
 
 
2050
 
    // Step 4. Find the chunk of the sample using the Sample-to-chunk-atom (stsc)
2051
 
    for (first_chunk_sample = 1, i = 0; i < (sc->sample_to_chunk_sz - 1); i++) {
2052
 
        b = (sc->sample_to_chunk[i + 1].first - sc->sample_to_chunk[i].first) * sc->sample_to_chunk[i].count;
2053
 
        if (seek_sample >= first_chunk_sample && seek_sample < (first_chunk_sample + b))
2054
 
            break;
2055
 
        first_chunk_sample += b;
2056
 
    }
2057
 
    chunk = sc->sample_to_chunk[i].first + (seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count;
2058
 
    left_in_chunk = sc->sample_to_chunk[i].count - (seek_sample - first_chunk_sample) % sc->sample_to_chunk[i].count;
2059
 
    first_chunk_sample += ((seek_sample - first_chunk_sample) / sc->sample_to_chunk[i].count) * sc->sample_to_chunk[i].count;
2060
 
    sample_to_chunk_idx = i;
2061
 
    dprintf("Sample was found in chunk #%i at sample offset %i (idx %i)\n", chunk, seek_sample - first_chunk_sample, sample_to_chunk_idx);
2062
 
 
2063
 
    // Step 5. Find the offset of the chunk using the chunk offset atom
2064
 
    if (!sc->chunk_offsets) {
2065
 
        av_log(s, AV_LOG_ERROR, "mov: no chunk offset atom, unable to seek\n");
2066
 
        return -1;
2067
 
    }
2068
 
    if (chunk > sc->chunk_count) {
2069
 
        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);
2070
 
        return -1;
2071
 
    }
2072
 
    chunk_file_offset = sc->chunk_offsets[chunk - 1];
2073
 
    dprintf("Chunk file offset is #%"PRIu64"\n", chunk_file_offset);
2074
 
 
2075
 
    // Step 6. Find the byte offset within the chunk using the sample size atom
2076
 
    sample_file_offset = chunk_file_offset;
2077
 
    if (sc->sample_size)
2078
 
        sample_file_offset += (seek_sample - first_chunk_sample) * sc->sample_size;
2079
 
    else {
2080
 
        for (i = 0; i < (seek_sample - first_chunk_sample); i++) {
2081
 
        sample_file_offset += sc->sample_sizes[first_chunk_sample + i - 1];
2082
 
        }
2083
 
    }
2084
 
    dprintf("Sample file offset is #%"PRIu64"\n", sample_file_offset);
2085
 
 
2086
 
    // Step 6. Update the parser
2087
 
    mov->partial = sc;
2088
 
    mov->next_chunk_offset = sample_file_offset;
2089
 
    // Update current stream state
2090
 
    sc->current_sample = seek_sample - 1;  // zero based
2091
 
    sc->left_in_chunk = left_in_chunk;
2092
 
    sc->next_chunk = chunk; // +1 -1 (zero based)
2093
 
    sc->sample_to_chunk_index = sample_to_chunk_idx;
2094
 
 
2095
 
    // Update other streams
2096
 
    for (i = 0; i<mov->total_streams; i++) {
2097
 
        MOVStreamContext *msc;
2098
 
        if (i == mov_idx) continue;
2099
 
        // Find the nearest 'next' chunk
2100
 
        msc = mov->streams[i];
2101
 
        a = 0;
2102
 
        b = msc->chunk_count - 1;
2103
 
        while (a < b) {
2104
 
            m = (a + b + 1) >> 1;
2105
 
            if (msc->chunk_offsets[m] > chunk_file_offset) {
2106
 
                b = m - 1;
2107
 
            } else {
2108
 
                a = m;
2109
 
            }
2110
 
        }
2111
 
        msc->next_chunk = a;
2112
 
        if (msc->chunk_offsets[a] < chunk_file_offset && a < (msc->chunk_count-1))
2113
 
            msc->next_chunk ++;
2114
 
        dprintf("Nearest next chunk for stream #%i is #%li @%"PRId64"\n", i, msc->next_chunk+1, msc->chunk_offsets[msc->next_chunk]);
2115
 
 
2116
 
        // Compute sample count and index in the sample_to_chunk table (what a pity)
2117
 
        msc->sample_to_chunk_index = 0;
2118
 
        msc->current_sample = 0;
2119
 
        for(;  msc->sample_to_chunk_index < (msc->sample_to_chunk_sz - 1)
2120
 
            && msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first <= (1 + msc->next_chunk); msc->sample_to_chunk_index++) {
2121
 
            msc->current_sample += (msc->sample_to_chunk[msc->sample_to_chunk_index + 1].first - msc->sample_to_chunk[msc->sample_to_chunk_index].first) \
2122
 
            * msc->sample_to_chunk[msc->sample_to_chunk_index].count;
2123
 
        }
2124
 
        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;
2125
 
        msc->left_in_chunk = msc->sample_to_chunk[msc->sample_to_chunk_index].count - 1;
2126
 
        // Find corresponding position in stts (used later to compute dts)
2127
 
        sample = 0;
2128
 
        start_time = 0;
2129
 
        for (msc->sample_to_time_index = 0; msc->sample_to_time_index < msc->stts_count; msc->sample_to_time_index++) {
2130
 
            count = msc->stts_data[msc->sample_to_time_index].count;
2131
 
            duration = msc->stts_data[msc->sample_to_time_index].duration;
2132
 
            if ((sample + count - 1) > msc->current_sample) {
2133
 
                msc->sample_to_time_time = start_time;
2134
 
                msc->sample_to_time_sample = sample;
2135
 
                break;
2136
 
            }
2137
 
            sample += count;
2138
 
            start_time += count * duration;
2139
 
        }
2140
 
        sample = 0;
2141
 
        for (msc->sample_to_ctime_index = 0; msc->sample_to_ctime_index < msc->ctts_count; msc->sample_to_ctime_index++) {
2142
 
            count = msc->ctts_data[msc->sample_to_ctime_index].count;
2143
 
            duration = msc->ctts_data[msc->sample_to_ctime_index].duration;
2144
 
            if ((sample + count - 1) > msc->current_sample) {
2145
 
                msc->sample_to_ctime_sample = sample;
2146
 
                break;
2147
 
            }
2148
 
            sample += count;
2149
 
        }
2150
 
        dprintf("Next Sample for stream #%i is #%li @%li\n", i, msc->current_sample + 1, msc->sample_to_chunk_index + 1);
 
1766
    AVStream *st;
 
1767
    int64_t seek_timestamp, timestamp;
 
1768
    int sample;
 
1769
    int i;
 
1770
 
 
1771
    if (stream_index >= s->nb_streams)
 
1772
        return -1;
 
1773
 
 
1774
    st = s->streams[stream_index];
 
1775
    sample = mov_seek_stream(st, sample_time, flags);
 
1776
    if (sample < 0)
 
1777
        return -1;
 
1778
 
 
1779
    /* adjust seek timestamp to found sample timestamp */
 
1780
    seek_timestamp = st->index_entries[sample].timestamp;
 
1781
 
 
1782
    for (i = 0; i < s->nb_streams; i++) {
 
1783
        st = s->streams[i];
 
1784
        if (stream_index == i || st->discard == AVDISCARD_ALL)
 
1785
            continue;
 
1786
 
 
1787
        timestamp = av_rescale_q(seek_timestamp, s->streams[stream_index]->time_base, st->time_base);
 
1788
        mov_seek_stream(st, timestamp, flags);
2151
1789
    }
2152
1790
    return 0;
2153
1791
}
2154
 
#endif
2155
1792
 
2156
1793
static int mov_read_close(AVFormatContext *s)
2157
1794
{
2166
1803
    return 0;
2167
1804
}
2168
1805
 
2169
 
static AVInputFormat mov_iformat = {
 
1806
AVInputFormat mov_demuxer = {
2170
1807
    "mov,mp4,m4a,3gp,3g2,mj2",
2171
1808
    "QuickTime/MPEG4/Motion JPEG 2000 format",
2172
1809
    sizeof(MOVContext),
2174
1811
    mov_read_header,
2175
1812
    mov_read_packet,
2176
1813
    mov_read_close,
2177
 
#if defined(MOV_SEEK)
2178
1814
    mov_read_seek,
2179
 
#endif
2180
1815
};
2181
 
 
2182
 
int mov_init(void)
2183
 
{
2184
 
    av_register_input_format(&mov_iformat);
2185
 
    return 0;
2186
 
}