X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Foggparsetheora.c;h=d1559f4632da8ada7972b1a96ebedba5a26297ca;hb=ccc10acb5b941973acab49d64459bb110cc0a529;hp=b976dcb70148bb698523fb109f7ce3fc75c6d08a;hpb=e1a794b2728afc479891917171b969cfdaf5262d;p=ffmpeg diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c index b976dcb7014..d1559f4632d 100644 --- a/libavformat/oggparsetheora.c +++ b/libavformat/oggparsetheora.c @@ -23,23 +23,25 @@ **/ #include +#include "libavutil/bswap.h" +#include "libavcodec/get_bits.h" #include "avformat.h" -#include "bitstream.h" -#include "bswap.h" +#include "internal.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 +56,17 @@ theora_header (AVFormatContext * s, int idx) if (os->buf[os->pstart] == 0x80) { GetBitContext gb; int width, height; - int version; + AVRational timebase; 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,40 +74,48 @@ 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); - st->time_base = st->codec->time_base; + } + timebase.den = get_bits_long(&gb, 32); + timebase.num = get_bits_long(&gb, 32); + if (!(timebase.num > 0 && timebase.den > 0)) { + av_log(s, AV_LOG_WARNING, "Invalid time base in theora stream, assuming 25 FPS\n"); + timebase.num = 1; + timebase.den = 25; + } + avpriv_set_pts_info(st, 64, timebase.num, timebase.den); - 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); thp->gpmask = (1 << thp->gpshift) - 1; - st->codec->codec_type = CODEC_TYPE_VIDEO; + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = CODEC_ID_THEORA; + st->need_parsing = AVSTREAM_PARSE_HEADERS; } else if (os->buf[os->pstart] == 0x83) { - vorbis_comment (s, os->buf + os->pstart + 7, os->psize - 8); + ff_vorbis_comment (s, &st->metadata, 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; @@ -116,21 +126,27 @@ theora_header (AVFormatContext * s, int idx) } static uint64_t -theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp) +theora_gptopts(AVFormatContext *ctx, int idx, uint64_t gp, int64_t *dts) { - 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; + os->pflags |= AV_PKT_FLAG_KEY; + + if (dts) + *dts = iframe + pframe; return iframe + pframe; } -ogg_codec_t theora_codec = { +const struct ogg_codec ff_theora_codec = { .magic = "\200theora", .magicsize = 7, .header = theora_header,