diff options
Diffstat (limited to 'libavformat/oggparseogm.c')
-rw-r--r-- | libavformat/oggparseogm.c | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c index 62784650b6..f8e656dcb1 100644 --- a/libavformat/oggparseogm.c +++ b/libavformat/oggparseogm.c @@ -24,6 +24,7 @@ #include <stdlib.h> +#include "libavutil/avassert.h" #include "libavutil/intreadwrite.h" #include "libavcodec/bytestream.h" @@ -42,6 +43,7 @@ ogm_header(AVFormatContext *s, int idx) GetByteContext p; uint64_t time_unit; uint64_t spu; + uint32_t size; bytestream2_init(&p, os->buf + os->pstart, os->psize); if (!(bytestream2_peek_byte(&p) & 1)) @@ -57,6 +59,8 @@ ogm_header(AVFormatContext *s, int idx) tag = bytestream2_get_le32(&p); st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag); st->codecpar->codec_tag = tag; + if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4) + st->need_parsing = AVSTREAM_PARSE_HEADERS; } else if (bytestream2_peek_byte(&p) == 't') { st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_TEXT; @@ -70,11 +74,13 @@ ogm_header(AVFormatContext *s, int idx) acid[4] = 0; cid = strtol(acid, NULL, 16); st->codecpar->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid); - st->need_parsing = AVSTREAM_PARSE_FULL; + // our parser completely breaks AAC in Ogg + if (st->codecpar->codec_id != AV_CODEC_ID_AAC) + st->need_parsing = AVSTREAM_PARSE_FULL; } - bytestream2_skip(&p, 4); /* useless size field */ - + size = bytestream2_get_le32(&p); + size = FFMIN(size, os->psize); time_unit = bytestream2_get_le64(&p); spu = bytestream2_get_le64(&p); if (!time_unit || !spu) { @@ -95,6 +101,16 @@ ogm_header(AVFormatContext *s, int idx) st->codecpar->bit_rate = bytestream2_get_le32(&p) * 8; st->codecpar->sample_rate = spu * 10000000 / time_unit; avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); + if (size >= 56 && st->codecpar->codec_id == AV_CODEC_ID_AAC) { + bytestream2_skip(&p, 4); + size -= 4; + } + if (size > 52) { + av_assert0(AV_INPUT_BUFFER_PADDING_SIZE <= 52); + size -= 52; + ff_alloc_extradata(st->codecpar, size); + bytestream2_get_buffer(&p, st->codecpar->extradata, st->codecpar->extradata_size); + } } } else if (bytestream2_peek_byte(&p) == 3) { bytestream2_skip(&p, 7); @@ -119,15 +135,23 @@ ogm_dshow_header(AVFormatContext *s, int idx) if(*p != 1) return 1; + if (os->psize < 100) + return AVERROR_INVALIDDATA; t = AV_RL32(p + 96); if(t == 0x05589f80){ + if (os->psize < 184) + return AVERROR_INVALIDDATA; + st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags, AV_RL32(p + 68)); avpriv_set_pts_info(st, 64, AV_RL64(p + 164), 10000000); st->codecpar->width = AV_RL32(p + 176); st->codecpar->height = AV_RL32(p + 180); } else if(t == 0x05589f81){ + if (os->psize < 136) + return AVERROR_INVALIDDATA; + st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = ff_codec_get_id(ff_codec_wav_tags, AV_RL16(p + 124)); st->codecpar->channels = AV_RL16(p + 126); |