diff options
author | Alex Converse <alex.converse@gmail.com> | 2009-03-16 16:14:36 +0000 |
---|---|---|
committer | Alex Converse <alex.converse@gmail.com> | 2009-03-16 16:14:36 +0000 |
commit | bd27eed6d07fc4483919aeed0e8c1f09f8e1c157 (patch) | |
tree | 4eec1c443ec8ae5bfcdb999326b197710a084081 | |
parent | 4a39ccb40350a25719b1a43d2bacbd74fbd4f703 (diff) | |
download | ffmpeg-bd27eed6d07fc4483919aeed0e8c1f09f8e1c157.tar.gz |
MOV: Support stz2 "Compact Sample Size Box"
Originally committed as revision 18016 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r-- | libavformat/mov.c | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/libavformat/mov.c b/libavformat/mov.c index e6ac071e4f..36e4bcedb9 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -33,6 +33,7 @@ #include "isom.h" #include "libavcodec/mpeg4audio.h" #include "libavcodec/mpegaudiodata.h" +#include "libavcodec/bitstream.h" #if CONFIG_ZLIB #include <zlib.h> @@ -1127,14 +1128,23 @@ static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOVAtom atom) { AVStream *st = c->fc->streams[c->fc->nb_streams-1]; MOVStreamContext *sc = st->priv_data; - unsigned int i, entries, sample_size; + unsigned int i, entries, sample_size, field_size, num_bytes; + GetBitContext gb; + unsigned char* buf; get_byte(pb); /* version */ get_be24(pb); /* flags */ + if (atom.type == MKTAG('s','t','s','z')) { sample_size = get_be32(pb); if (!sc->sample_size) /* do not overwrite value computed in stsd */ sc->sample_size = sample_size; + field_size = 32; + } else { + sample_size = 0; + get_be24(pb); /* reserved */ + field_size = get_byte(pb); + } entries = get_be32(pb); dprintf(c->fc, "sample_size = %d sample_count = %d\n", sc->sample_size, entries); @@ -1143,14 +1153,37 @@ static int mov_read_stsz(MOVContext *c, ByteIOContext *pb, MOVAtom atom) if (sample_size) return 0; + if (field_size != 4 && field_size != 8 && field_size != 16 && field_size != 32) { + av_log(c->fc, AV_LOG_ERROR, "Invalid sample field size %d\n", field_size); + return -1; + } + if(entries >= UINT_MAX / sizeof(int)) return -1; sc->sample_sizes = av_malloc(entries * sizeof(int)); if (!sc->sample_sizes) return AVERROR(ENOMEM); + num_bytes = (entries*field_size+4)>>3; + + buf = av_malloc(num_bytes); + if (!buf) { + av_freep(&sc->sample_sizes); + return AVERROR(ENOMEM); + } + + if (get_buffer(pb, buf, num_bytes) < num_bytes) { + av_freep(&sc->sample_sizes); + av_free(buf); + return -1; + } + + init_get_bits(&gb, buf, 8*num_bytes); + for(i=0; i<entries; i++) - sc->sample_sizes[i] = get_be32(pb); + sc->sample_sizes[i] = get_bits_long(&gb, field_size); + + av_free(buf); return 0; } @@ -1793,6 +1826,7 @@ static const MOVParseTableEntry mov_default_parse_table[] = { { MKTAG('s','t','s','s'), mov_read_stss }, /* sync sample */ { MKTAG('s','t','s','z'), mov_read_stsz }, /* sample size */ { MKTAG('s','t','t','s'), mov_read_stts }, +{ MKTAG('s','t','z','2'), mov_read_stsz }, /* compact sample size */ { MKTAG('t','k','h','d'), mov_read_tkhd }, /* track header */ { MKTAG('t','f','h','d'), mov_read_tfhd }, /* track fragment header */ { MKTAG('t','r','a','k'), mov_read_trak }, |