diff options
Diffstat (limited to 'libavcodec/vp3.c')
-rw-r--r-- | libavcodec/vp3.c | 77 |
1 files changed, 58 insertions, 19 deletions
diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index f46ac32..00a77e9 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -1,20 +1,20 @@ /* * Copyright (C) 2003-2004 the ffmpeg project * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * - * Libav is distributed in the hope that it will be useful, + * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -75,6 +75,10 @@ typedef struct Vp3Fragment { /* special internal mode */ #define MODE_COPY 8 +static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb); +static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb); + + /* There are 6 preset schemes, plus a free-form scheme */ static const int ModeAlphabet[6][CODING_MODE_COUNT] = { @@ -292,6 +296,8 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) av_freep(&s->motion_val[1]); av_freep(&s->edge_emu_buffer); + s->theora_tables = 0; + if (avctx->internal->is_copy) return 0; @@ -314,7 +320,7 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) return 0; } -/* +/** * This function sets up all of the various blocks mappings: * superblocks <-> fragments, macroblocks <-> fragments, * superblocks <-> macroblocks @@ -400,7 +406,7 @@ static void init_loop_filter(Vp3DecodeContext *s) int value; filter_limit = s->filter_limit_values[s->qps[0]]; - assert(filter_limit < 128); + av_assert0(filter_limit < 128U); /* set up the bounding values */ memset(s->bounding_values_array, 0, 256 * sizeof(int)); @@ -1575,19 +1581,13 @@ static void render_slice(Vp3DecodeContext *s, int slice) /* invert DCT and place (or add) in final output */ if (s->all_fragments[i].coding_method == MODE_INTRA) { - int index; - index = vp3_dequant(s, s->all_fragments + i, plane, 0, block); - if (index > 63) - continue; + vp3_dequant(s, s->all_fragments + i, plane, 0, block); s->vp3dsp.idct_put( output_plane + first_pixel, stride, block); } else { - int index = vp3_dequant(s, s->all_fragments + i, plane, 1, block); - if (index > 63) - continue; - if (index > 0) { + if (vp3_dequant(s, s->all_fragments + i, plane, 1, block)) { s->vp3dsp.idct_add( output_plane + first_pixel, stride, @@ -1673,7 +1673,7 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx) s->avctx = avctx; s->width = FFALIGN(avctx->width, 16); s->height = FFALIGN(avctx->height, 16); - if (avctx->pix_fmt == AV_PIX_FMT_NONE) + if (avctx->codec_id != AV_CODEC_ID_THEORA) avctx->pix_fmt = AV_PIX_FMT_YUV420P; avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; ff_dsputil_init(&s->dsp, avctx); @@ -1688,8 +1688,7 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx) for (i = 0; i < 3; i++) s->qps[i] = -1; - av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, - &s->chroma_y_shift); + avcodec_get_chroma_sub_sample(avctx->pix_fmt, &s->chroma_x_shift, &s->chroma_y_shift); s->y_superblock_width = (s->width + 31) / 32; s->y_superblock_height = (s->height + 31) / 32; @@ -1868,7 +1867,7 @@ static int vp3_update_thread_context(AVCodecContext *dst, const AVCodecContext * ||s->width != s1->width ||s->height!= s1->height) { if (s != s1) - copy_fields(s, s1, golden_frame, current_frame); + copy_fields(s, s1, golden_frame, keyframe); return -1; } @@ -1919,16 +1918,48 @@ static int vp3_decode_frame(AVCodecContext *avctx, Vp3DecodeContext *s = avctx->priv_data; GetBitContext gb; int i; + int ret; init_get_bits(&gb, buf, buf_size * 8); +#if CONFIG_THEORA_DECODER if (s->theora && get_bits1(&gb)) { + int type = get_bits(&gb, 7); + skip_bits_long(&gb, 6*8); /* "theora" */ + + if (s->avctx->active_thread_type&FF_THREAD_FRAME) { + av_log(avctx, AV_LOG_ERROR, "midstream reconfiguration with multithreading is unsupported, try -threads 1\n"); + return AVERROR_PATCHWELCOME; + } + if (type == 0) { + vp3_decode_end(avctx); + ret = theora_decode_header(avctx, &gb); + + if (ret < 0) { + vp3_decode_end(avctx); + } else + ret = vp3_decode_init(avctx); + return ret; + } else if (type == 2) { + ret = theora_decode_tables(avctx, &gb); + if (ret < 0) { + vp3_decode_end(avctx); + } else + ret = vp3_decode_init(avctx); + return ret; + } + av_log(avctx, AV_LOG_ERROR, "Header packet passed to frame decoder, skipping\n"); return -1; } +#endif s->keyframe = !get_bits1(&gb); + if (!s->all_fragments) { + av_log(avctx, AV_LOG_ERROR, "Data packet without prior valid headers\n"); + return -1; + } if (!s->theora) skip_bits(&gb, 1); for (i = 0; i < 3; i++) @@ -1962,6 +1993,7 @@ static int vp3_decode_frame(AVCodecContext *avctx, s->current_frame.reference = 3; s->current_frame.pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + s->current_frame.key_frame = s->keyframe; if (ff_thread_get_buffer(avctx, &s->current_frame) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); goto error; @@ -2182,6 +2214,10 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) { skip_bits(gb, 5); /* keyframe frequency force */ avctx->pix_fmt = theora_pix_fmts[get_bits(gb, 2)]; + if (avctx->pix_fmt == AV_PIX_FMT_NONE) { + av_log(avctx, AV_LOG_ERROR, "Invalid pixel format\n"); + return AVERROR_INVALIDDATA; + } skip_bits(gb, 3); /* reserved */ } @@ -2323,6 +2359,8 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) int header_len[3]; int i; + avctx->pix_fmt = AV_PIX_FMT_YUV420P; + s->theora = 1; if (!avctx->extradata_size) @@ -2356,7 +2394,8 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) switch(ptype) { case 0x80: - theora_decode_header(avctx, &gb); + if (theora_decode_header(avctx, &gb) < 0) + return -1; break; case 0x81: // FIXME: is this needed? it breaks sometimes |