X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Foggparsetheora.c;h=0d74116d178822d656b63e4711bc648797ad513b;hb=005d9b57ad05acf7e8626467de8774c522182173;hp=8fb57ebd5abcee8464083b899414cde06ac55356;hpb=80fb82346e6d680d2ccff761a578fe856ed3b54c;p=ffmpeg diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c index 8fb57ebd5ab..0d74116d178 100644 --- a/libavformat/oggparsetheora.c +++ b/libavformat/oggparsetheora.c @@ -23,23 +23,24 @@ **/ #include +#include "libavutil/bswap.h" +#include "libavcodec/get_bits.h" #include "avformat.h" -#include "bitstream.h" -#include "bswap.h" -#include "ogg2.h" +#include "oggdec.h" -typedef struct theora_params { +struct theora_params { int gpshift; int gpmask; -} theora_params_t; + unsigned version; +}; static int theora_header (AVFormatContext * s, int idx) { - ogg_t *ogg = s->priv_data; - ogg_stream_t *os = ogg->streams + idx; + struct ogg *ogg = s->priv_data; + struct ogg_stream *os = ogg->streams + idx; AVStream *st = s->streams[idx]; - theora_params_t *thp = os->private; + struct theora_params *thp = os->private; int cds = st->codec->extradata_size + os->psize + 2; uint8_t *cdp; @@ -54,17 +55,16 @@ theora_header (AVFormatContext * s, int idx) if (os->buf[os->pstart] == 0x80) { GetBitContext gb; int width, height; - int version; init_get_bits(&gb, os->buf + os->pstart, os->psize*8); - skip_bits(&gb, 7*8); /* 0x80"theora" */ + skip_bits_long(&gb, 7*8); /* 0x80"theora" */ - version = get_bits_long(&gb, 24); - if (version < 0x030100) + thp->version = get_bits_long(&gb, 24); + if (thp->version < 0x030100) { av_log(s, AV_LOG_ERROR, - "Too old or unsupported Theora (%x)\n", version); + "Too old or unsupported Theora (%x)\n", thp->version); return -1; } @@ -72,27 +72,33 @@ theora_header (AVFormatContext * s, int idx) height = get_bits(&gb, 16) << 4; avcodec_set_dimensions(st->codec, width, height); - if (version >= 0x030400) + if (thp->version >= 0x030400) skip_bits(&gb, 100); - width = get_bits_long(&gb, 24); - height = get_bits_long(&gb, 24); - if ( width <= st->codec->width && width > st->codec->width-16 - && height <= st->codec->height && height > st->codec->height-16) - avcodec_set_dimensions(st->codec, width, height); + if (thp->version >= 0x030200) { + width = get_bits_long(&gb, 24); + height = get_bits_long(&gb, 24); + if ( width <= st->codec->width && width > st->codec->width-16 + && height <= st->codec->height && height > st->codec->height-16) + avcodec_set_dimensions(st->codec, width, height); - if (version >= 0x030200) skip_bits(&gb, 16); + } st->codec->time_base.den = get_bits_long(&gb, 32); st->codec->time_base.num = get_bits_long(&gb, 32); + if (!(st->codec->time_base.num > 0 && st->codec->time_base.den > 0)) { + av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n"); + st->codec->time_base.num = 1; + st->codec->time_base.den = 25; + } st->time_base = st->codec->time_base; - st->codec->sample_aspect_ratio.num = get_bits_long(&gb, 24); - st->codec->sample_aspect_ratio.den = get_bits_long(&gb, 24); + st->sample_aspect_ratio.num = get_bits_long(&gb, 24); + st->sample_aspect_ratio.den = get_bits_long(&gb, 24); - if (version >= 0x030200) - skip_bits(&gb, 38); - if (version >= 0x304000) + if (thp->version >= 0x030200) + skip_bits_long(&gb, 38); + if (thp->version >= 0x304000) skip_bits(&gb, 2); thp->gpshift = get_bits(&gb, 5); @@ -105,7 +111,8 @@ theora_header (AVFormatContext * s, int idx) vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8); } - st->codec->extradata = av_realloc (st->codec->extradata, cds); + st->codec->extradata = av_realloc (st->codec->extradata, + cds + FF_INPUT_BUFFER_PADDING_SIZE); cdp = st->codec->extradata + st->codec->extradata_size; *cdp++ = os->psize >> 8; *cdp++ = os->psize & 0xff; @@ -118,16 +125,22 @@ theora_header (AVFormatContext * s, int idx) static uint64_t theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp) { - ogg_t *ogg = ctx->priv_data; - ogg_stream_t *os = ogg->streams + idx; - theora_params_t *thp = os->private; + struct ogg *ogg = ctx->priv_data; + struct ogg_stream *os = ogg->streams + idx; + struct theora_params *thp = os->private; uint64_t iframe = gp >> thp->gpshift; uint64_t pframe = gp & thp->gpmask; + if (thp->version < 0x030201) + iframe++; + + if(!pframe) + os->pflags |= PKT_FLAG_KEY; + return iframe + pframe; } -ogg_codec_t theora_codec = { +const struct ogg_codec ff_theora_codec = { .magic = "\200theora", .magicsize = 7, .header = theora_header,