diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-05-07 06:14:09 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-05-07 06:14:09 +0400 |
commit | e5a85164b100620fe529bae0ce623956f0bab2e9 (patch) | |
tree | 4732dbaa6666e2448c33a32956b074f51105243d /libavformat/mov.c | |
parent | c60d2be5510044edf01d813363e39841db3d751a (diff) | |
parent | 45a811b512b47acf060247ad0bc7022cada5533b (diff) |
Merge remote branch 'qatar/master'
* qatar/master:
mov: fix composition timestamps on movie fragments.
wmavoice: Use proper size in memeset().
Diffstat (limited to 'libavformat/mov.c')
-rw-r--r-- | libavformat/mov.c | 40 |
1 files changed, 27 insertions, 13 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index cc120150c7..6e29ceaa00 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -2004,6 +2004,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOVFragment *frag = &c->fragment; AVStream *st = NULL; MOVStreamContext *sc; + MOVStts *ctts_data; uint64_t offset; int64_t dts; int data_offset = 0; @@ -2027,18 +2028,33 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) flags = avio_rb24(pb); entries = avio_rb32(pb); av_dlog(c->fc, "flags 0x%x entries %d\n", flags, entries); - if (flags & 0x001) data_offset = avio_rb32(pb); - if (flags & 0x004) first_sample_flags = avio_rb32(pb); - if (flags & 0x800) { - MOVStts *ctts_data; - if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data)) - return -1; - ctts_data = av_realloc(sc->ctts_data, - (entries+sc->ctts_count)*sizeof(*sc->ctts_data)); + + /* Always assume the presence of composition time offsets. + * Without this assumption, for instance, we cannot deal with a track in fragmented movies that meet the following. + * 1) in the initial movie, there are no samples. + * 2) in the first movie fragment, there is only one sample without composition time offset. + * 3) in the subsequent movie fragments, there are samples with composition time offset. */ + if (!sc->ctts_count && sc->sample_count) + { + /* Complement ctts table if moov atom doesn't have ctts atom. */ + ctts_data = av_malloc(sizeof(*sc->ctts_data)); if (!ctts_data) return AVERROR(ENOMEM); sc->ctts_data = ctts_data; + sc->ctts_data[sc->ctts_count].count = sc->sample_count; + sc->ctts_data[sc->ctts_count].duration = 0; + sc->ctts_count++; } + if ((uint64_t)entries+sc->ctts_count >= UINT_MAX/sizeof(*sc->ctts_data)) + return -1; + ctts_data = av_realloc(sc->ctts_data, + (entries+sc->ctts_count)*sizeof(*sc->ctts_data)); + if (!ctts_data) + return AVERROR(ENOMEM); + sc->ctts_data = ctts_data; + + if (flags & 0x001) data_offset = avio_rb32(pb); + if (flags & 0x004) first_sample_flags = avio_rb32(pb); dts = st->duration; offset = frag->base_data_offset + data_offset; distance = 0; @@ -2052,11 +2068,9 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (flags & 0x100) sample_duration = avio_rb32(pb); if (flags & 0x200) sample_size = avio_rb32(pb); if (flags & 0x400) sample_flags = avio_rb32(pb); - if (flags & 0x800) { - sc->ctts_data[sc->ctts_count].count = 1; - sc->ctts_data[sc->ctts_count].duration = avio_rb32(pb); - sc->ctts_count++; - } + sc->ctts_data[sc->ctts_count].count = 1; + sc->ctts_data[sc->ctts_count].duration = (flags & 0x800) ? avio_rb32(pb) : 0; + sc->ctts_count++; if ((keyframe = st->codec->codec_type == AVMEDIA_TYPE_AUDIO || (flags & 0x004 && !i && !sample_flags) || sample_flags & 0x2000000)) distance = 0; |