Merge commit '757d5e8ef98ba2ab0dd0e85a46290c4f4a7e82be'
authorMichael Niedermayer <michaelni@gmx.at>
Fri, 1 Nov 2013 14:49:58 +0000 (15:49 +0100)
committerMichael Niedermayer <michaelni@gmx.at>
Fri, 1 Nov 2013 14:49:58 +0000 (15:49 +0100)
* commit '757d5e8ef98ba2ab0dd0e85a46290c4f4a7e82be':
  vp8: stop using deprecated avcodec_set_dimensions
  vp56: stop using deprecated avcodec_set_dimensions
  vp3: stop using deprecated avcodec_set_dimensions
  txd: stop using deprecated avcodec_set_dimensions
  truemotion1: stop using deprecated avcodec_set_dimensions

Conflicts:
libavcodec/txd.c
libavcodec/vp56.c

Merged-by: Michael Niedermayer <michaelni@gmx.at>
1  2 
libavcodec/truemotion1.c
libavcodec/txd.c
libavcodec/vp3.c
libavcodec/vp5.c
libavcodec/vp56.c
libavcodec/vp6.c
libavcodec/vp8.c

diff --combined libavcodec/truemotion1.c
@@@ -2,20 -2,20 +2,20 @@@
   * Duck TrueMotion 1.0 Decoder
   * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson
   *
 - * 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
   */
  
@@@ -317,7 -317,7 +317,7 @@@ static int truemotion1_decode_header(Tr
      const uint8_t *sel_vector_table;
  
      header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f;
 -    if (s->buf[0] < 0x10)
 +    if (s->buf[0] < 0x10 || header.header_size >= s->size)
      {
          av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]);
          return AVERROR_INVALIDDATA;
          new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well
  
      s->w >>= width_shift;
-     if ((ret = av_image_check_size(s->w, s->h, 0, s->avctx)) < 0)
-         return ret;
  
      if (s->w != s->avctx->width || s->h != s->avctx->height ||
          new_pix_fmt != s->avctx->pix_fmt) {
          av_frame_unref(&s->frame);
          s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 };
          s->avctx->pix_fmt = new_pix_fmt;
-         avcodec_set_dimensions(s->avctx, s->w, s->h);
+         if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0)
+             return ret;
          av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
 +        if (!s->vert_pred)
 +            return AVERROR(ENOMEM);
      }
  
      /* There is 1 change bit per 4 pixels, so each change byte represents
@@@ -475,8 -474,6 +476,8 @@@ static av_cold int truemotion1_decode_i
      /* there is a vertical predictor for each pixel in a line; each vertical
       * predictor is 0 to start with */
      av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int));
 +    if (!s->vert_pred)
 +        return AVERROR(ENOMEM);
  
      return 0;
  }
@@@ -517,10 -514,6 +518,10 @@@ hres,vres,i,i%vres (0 < i < 4
  }
  
  #define APPLY_C_PREDICTOR() \
 +    if(index > 1023){\
 +        av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
 +        return; \
 +    }\
      predictor_pair = s->c_predictor_table[index]; \
      horiz_pred += (predictor_pair >> 1); \
      if (predictor_pair & 1) { \
          index++;
  
  #define APPLY_C_PREDICTOR_24() \
 +    if(index > 1023){\
 +        av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
 +        return; \
 +    }\
      predictor_pair = s->c_predictor_table[index]; \
      horiz_pred += (predictor_pair >> 1); \
      if (predictor_pair & 1) { \
  
  
  #define APPLY_Y_PREDICTOR() \
 +    if(index > 1023){\
 +        av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
 +        return; \
 +    }\
      predictor_pair = s->y_predictor_table[index]; \
      horiz_pred += (predictor_pair >> 1); \
      if (predictor_pair & 1) { \
          index++;
  
  #define APPLY_Y_PREDICTOR_24() \
 +    if(index > 1023){\
 +        av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \
 +        return; \
 +    }\
      predictor_pair = s->y_predictor_table[index]; \
      horiz_pred += (predictor_pair >> 1); \
      if (predictor_pair & 1) { \
@@@ -872,8 -853,10 +873,8 @@@ static int truemotion1_decode_frame(AVC
      if ((ret = truemotion1_decode_header(s)) < 0)
          return ret;
  
 -    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) {
 -        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +    if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0)
          return ret;
 -    }
  
      if (compression_types[s->compression].algorithm == ALGO_RGB24H) {
          truemotion1_decode_24bit(s);
@@@ -895,7 -878,7 +896,7 @@@ static av_cold int truemotion1_decode_e
      TrueMotion1Context *s = avctx->priv_data;
  
      av_frame_unref(&s->frame);
 -    av_free(s->vert_pred);
 +    av_freep(&s->vert_pred);
  
      return 0;
  }
diff --combined libavcodec/txd.c
@@@ -4,27 -4,27 +4,27 @@@
   *
   * See also: http://wiki.multimedia.cx/index.php?title=TXD
   *
 - * 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
   */
  
  #include "libavutil/intreadwrite.h"
  #include "libavutil/imgutils.h"
 -#include "avcodec.h"
  #include "bytestream.h"
 +#include "avcodec.h"
  #include "internal.h"
  #include "s3tc.h"
  
@@@ -63,12 -63,13 +63,11 @@@ static int txd_decode_frame(AVCodecCont
          return AVERROR_PATCHWELCOME;
      }
  
-     if ((ret = av_image_check_size(w, h, 0, avctx)) < 0)
+     if ((ret = ff_set_dimensions(avctx, w, h)) < 0)
          return ret;
-     if (w != avctx->width || h != avctx->height)
-         avcodec_set_dimensions(avctx, w, h);
 -    if ((ret = ff_get_buffer(avctx, p, 0)) < 0) {
 -        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +    if ((ret = ff_get_buffer(avctx, p, 0)) < 0)
          return ret;
 -    }
  
      p->pict_type = AV_PICTURE_TYPE_I;
  
@@@ -81,8 -82,6 +80,8 @@@
              v = bytestream2_get_be32(&gb);
              pal[y] = (v >> 8) + (v << 24);
          }
 +        if (bytestream2_get_bytes_left(&gb) < w * h)
 +            return AVERROR_INVALIDDATA;
          bytestream2_skip(&gb, 4);
          for (y=0; y<h; y++) {
              bytestream2_get_buffer(&gb, ptr, w);
              if (!(flags & 1))
                  goto unsupported;
          case FF_S3TC_DXT1:
 +            if (bytestream2_get_bytes_left(&gb) < (w/4) * (h/4) * 8)
 +                return AVERROR_INVALIDDATA;
              ff_decode_dxt1(&gb, ptr, w, h, stride);
              break;
          case FF_S3TC_DXT3:
 +            if (bytestream2_get_bytes_left(&gb) < (w/4) * (h/4) * 16)
 +                return AVERROR_INVALIDDATA;
              ff_decode_dxt3(&gb, ptr, w, h, stride);
              break;
          default:
          switch (d3d_format) {
          case 0x15:
          case 0x16:
 +            if (bytestream2_get_bytes_left(&gb) < h * w * 4)
 +                return AVERROR_INVALIDDATA;
              for (y=0; y<h; y++) {
                  bytestream2_get_buffer(&gb, ptr, w * 4);
                  ptr += stride;
diff --combined libavcodec/vp3.c
@@@ -1,20 -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
   */
  
@@@ -76,10 -76,6 +76,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] =
  {
@@@ -289,8 -285,6 +289,8 @@@ static av_cold int vp3_decode_end(AVCod
      av_freep(&s->motion_val[1]);
      av_freep(&s->edge_emu_buffer);
  
 +    s->theora_tables = 0;
 +
      /* release all frames */
      vp3_decode_flush(avctx);
      av_frame_free(&s->current_frame.f);
      return 0;
  }
  
 -/*
 +/**
   * This function sets up all of the various blocks mappings:
   * superblocks <-> fragments, macroblocks <-> fragments,
   * superblocks <-> macroblocks
@@@ -404,7 -398,7 +404,7 @@@ static void init_loop_filter(Vp3DecodeC
      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));
@@@ -1549,10 -1543,7 +1549,10 @@@ static void render_slice(Vp3DecodeConte
                              uint8_t *temp= s->edge_emu_buffer;
                              if(stride<0) temp -= 8*stride;
  
 -                            s->vdsp.emulated_edge_mc(temp, motion_source, stride, 9, 9, src_x, src_y, plane_width, plane_height);
 +                            s->vdsp.emulated_edge_mc(temp, stride,
 +                                                     motion_source, stride,
 +                                                     9, 9, src_x, src_y,
 +                                                     plane_width, plane_height);
                              motion_source= temp;
                          }
                      }
                      /* 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,
@@@ -1635,16 -1632,16 +1635,16 @@@ static av_cold int allocate_tables(AVCo
      y_fragment_count = s->fragment_width[0] * s->fragment_height[0];
      c_fragment_count = s->fragment_width[1] * s->fragment_height[1];
  
 -    s->superblock_coding = av_malloc(s->superblock_count);
 -    s->all_fragments = av_malloc(s->fragment_count * sizeof(Vp3Fragment));
 -    s->coded_fragment_list[0] = av_malloc(s->fragment_count * sizeof(int));
 -    s->dct_tokens_base = av_malloc(64*s->fragment_count * sizeof(*s->dct_tokens_base));
 -    s->motion_val[0] = av_malloc(y_fragment_count * sizeof(*s->motion_val[0]));
 -    s->motion_val[1] = av_malloc(c_fragment_count * sizeof(*s->motion_val[1]));
 +    s->superblock_coding = av_mallocz(s->superblock_count);
 +    s->all_fragments = av_mallocz(s->fragment_count * sizeof(Vp3Fragment));
 +    s->coded_fragment_list[0] = av_mallocz(s->fragment_count * sizeof(int));
 +    s->dct_tokens_base = av_mallocz(64*s->fragment_count * sizeof(*s->dct_tokens_base));
 +    s->motion_val[0] = av_mallocz(y_fragment_count * sizeof(*s->motion_val[0]));
 +    s->motion_val[1] = av_mallocz(c_fragment_count * sizeof(*s->motion_val[1]));
  
      /* work out the block mapping tables */
 -    s->superblock_fragments = av_malloc(s->superblock_count * 16 * sizeof(int));
 -    s->macroblock_coding = av_malloc(s->macroblock_count + 1);
 +    s->superblock_fragments = av_mallocz(s->superblock_count * 16 * sizeof(int));
 +    s->macroblock_coding = av_mallocz(s->macroblock_count + 1);
  
      if (!s->superblock_coding || !s->all_fragments || !s->dct_tokens_base ||
          !s->coded_fragment_list[0] || !s->superblock_fragments || !s->macroblock_coding ||
@@@ -1696,7 -1693,7 +1696,7 @@@ static av_cold int vp3_decode_init(AVCo
      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_hpeldsp_init(&s->hdsp, avctx->flags | CODEC_FLAG_BITEXACT);
      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;
@@@ -1961,44 -1959,13 +1961,44 @@@ static int vp3_decode_frame(AVCodecCont
  
      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++)
          return buf_size;
  
      s->current_frame.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
 -    if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0) {
 -        av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +    s->current_frame.f->key_frame = s->keyframe;
 +    if (ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF) < 0)
          goto error;
 -    }
  
      if (!s->edge_emu_buffer)
          s->edge_emu_buffer = av_malloc(9*FFABS(s->current_frame.f->linesize[0]));
              av_log(s->avctx, AV_LOG_WARNING, "vp3: first frame not a keyframe\n");
  
              s->golden_frame.f->pict_type = AV_PICTURE_TYPE_I;
 -            if (ff_thread_get_buffer(avctx, &s->golden_frame, AV_GET_BUFFER_FLAG_REF) < 0) {
 -                av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 +            if (ff_thread_get_buffer(avctx, &s->golden_frame, AV_GET_BUFFER_FLAG_REF) < 0)
                  goto error;
 -            }
              ff_thread_release_buffer(avctx, &s->last_frame);
              if ((ret = ff_thread_ref_frame(&s->last_frame, &s->golden_frame)) < 0)
                  goto error;
@@@ -2196,6 -2166,7 +2196,7 @@@ static int theora_decode_header(AVCodec
      Vp3DecodeContext *s = avctx->priv_data;
      int visible_width, visible_height, colorspace;
      int offset_x = 0, offset_y = 0;
+     int ret;
      AVRational fps, aspect;
  
      s->theora = get_bits_long(gb, 24);
      visible_width  = s->width  = get_bits(gb, 16) << 4;
      visible_height = s->height = get_bits(gb, 16) << 4;
  
-     if(av_image_check_size(s->width, s->height, 0, avctx)){
-         av_log(avctx, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n", s->width, s->height);
-         s->width= s->height= 0;
-         return -1;
-     }
      if (s->theora >= 0x030200) {
          visible_width  = get_bits_long(gb, 24);
          visible_height = get_bits_long(gb, 24);
      {
          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 */
      }
  
      if (   visible_width  <= s->width  && visible_width  > s->width-16
          && visible_height <= s->height && visible_height > s->height-16
          && !offset_x && (offset_y == s->height - visible_height))
-         avcodec_set_dimensions(avctx, visible_width, visible_height);
+         ret = ff_set_dimensions(avctx, visible_width, visible_height);
      else
-         avcodec_set_dimensions(avctx, s->width, s->height);
+         ret = ff_set_dimensions(avctx, s->width, s->height);
+     if (ret < 0)
+         return ret;
  
      if (colorspace == 1) {
          avctx->color_primaries = AVCOL_PRI_BT470M;
@@@ -2401,8 -2364,6 +2398,8 @@@ static av_cold int theora_decode_init(A
      int header_len[3];
      int i;
  
 +    avctx->pix_fmt = AV_PIX_FMT_YUV420P;
 +
      s->theora = 1;
  
      if (!avctx->extradata_size)
      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
diff --combined libavcodec/vp5.c
@@@ -1,20 -1,20 +1,20 @@@
  /*
   * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
   *
 - * 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
   */
  
  
  #include "avcodec.h"
  #include "get_bits.h"
+ #include "internal.h"
  
  #include "vp56.h"
  #include "vp56data.h"
  #include "vp5data.h"
  
  
 -static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
 -                            int *golden_frame)
 +static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
  {
      VP56RangeCoder *c = &s->c;
      int rows, cols;
@@@ -66,7 -68,9 +67,9 @@@
          if (!s->macroblocks || /* first frame */
              16*cols != s->avctx->coded_width ||
              16*rows != s->avctx->coded_height) {
-             avcodec_set_dimensions(s->avctx, 16*cols, 16*rows);
+             int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+             if (ret < 0)
+                 return ret;
              return VP56_SIZE_CHANGE;
          }
      } else if (!s->macroblocks)
diff --combined libavcodec/vp56.c
@@@ -1,20 -1,20 +1,20 @@@
  /*
   * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
   *
 - * 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
   */
  
@@@ -339,7 -339,7 +339,7 @@@ static void vp56_mc(VP56Context *s, in
  
      if (x<0 || x+12>=s->plane_width[plane] ||
          y<0 || y+12>=s->plane_height[plane]) {
 -        s->vdsp.emulated_edge_mc(s->edge_emu_buffer,
 +        s->vdsp.emulated_edge_mc(s->edge_emu_buffer, stride,
                              src + s->block_offset[b] + (dy-2)*stride + (dx-2),
                              stride, 12, 12, x, y,
                              s->plane_width[plane],
@@@ -452,9 -452,9 +452,9 @@@ static void vp56_decode_mb(VP56Context 
      }
  }
  
 -static int vp56_size_changed(AVCodecContext *avctx)
 +static int vp56_size_changed(VP56Context *s)
  {
 -    VP56Context *s = avctx->priv_data;
 +    AVCodecContext *avctx = s->avctx;
      int stride = s->frames[VP56_FRAME_CURRENT]->linesize[0];
      int i;
  
      s->mb_height = (avctx->coded_height+15) / 16;
  
      if (s->mb_width > 1000 || s->mb_height > 1000) {
-         avcodec_set_dimensions(avctx, 0, 0);
+         ff_set_dimensions(avctx, 0, 0);
          av_log(avctx, AV_LOG_ERROR, "picture too big\n");
          return -1;
      }
  
 -    s->above_blocks = av_realloc(s->above_blocks,
 -                                 (4*s->mb_width+6) * sizeof(*s->above_blocks));
 -    s->macroblocks = av_realloc(s->macroblocks,
 -                                s->mb_width*s->mb_height*sizeof(*s->macroblocks));
 +    av_reallocp_array(&s->above_blocks, 4*s->mb_width+6,
 +                      sizeof(*s->above_blocks));
 +    av_reallocp_array(&s->macroblocks, s->mb_width*s->mb_height,
 +                      sizeof(*s->macroblocks));
      av_free(s->edge_emu_buffer_alloc);
      s->edge_emu_buffer_alloc = av_malloc(16*stride);
      s->edge_emu_buffer = s->edge_emu_buffer_alloc;
 +    if (!s->above_blocks || !s->macroblocks || !s->edge_emu_buffer_alloc)
 +        return AVERROR(ENOMEM);
      if (s->flip < 0)
          s->edge_emu_buffer += 15 * stride;
  
 +    if (s->alpha_context)
 +        return vp56_size_changed(s->alpha_context);
 +
      return 0;
  }
  
 +static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *, int, int);
 +
  int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
                           AVPacket *avpkt)
  {
      VP56Context *s = avctx->priv_data;
      AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
      int remaining_buf_size = avpkt->size;
 -    int is_alpha, av_uninit(alpha_offset);
 -    int res;
 +    int av_uninit(alpha_offset);
 +    int i, res;
 +    int ret;
  
      if (s->has_alpha) {
          if (remaining_buf_size < 3)
              return -1;
      }
  
 -    for (is_alpha=0; is_alpha < 1+s->has_alpha; is_alpha++) {
 -        int mb_row, mb_col, mb_row_flip, mb_offset = 0;
 -        int block, y, uv;
 -        ptrdiff_t stride_y, stride_uv;
 -        int golden_frame = 0;
 +    res = s->parse_header(s, buf, remaining_buf_size);
 +    if (res < 0)
 +        return res;
  
 -        s->modelp = &s->models[is_alpha];
 +    if (res == VP56_SIZE_CHANGE) {
 +        for (i = 0; i < 4; i++) {
 +            av_frame_unref(s->frames[i]);
 +            if (s->alpha_context)
 +                av_frame_unref(s->alpha_context->frames[i]);
 +        }
 +    }
  
 -        res = s->parse_header(s, buf, remaining_buf_size, &golden_frame);
 -        if (res < 0) {
 -            int i;
 -            for (i = 0; i < 4; i++)
 -                av_frame_unref(s->frames[i]);
 -            return res;
 +    if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0)
 +        return -1;
 +
 +    if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) {
 +        av_frame_unref(s->alpha_context->frames[VP56_FRAME_CURRENT]);
 +        if ((ret = av_frame_ref(s->alpha_context->frames[VP56_FRAME_CURRENT], p)) < 0) {
 +            av_frame_unref(p);
 +            return ret;
          }
 +    }
  
 -        if (res == VP56_SIZE_CHANGE) {
 -            int i;
 -            for (i = 0; i < 4; i++)
 -                av_frame_unref(s->frames[i]);
 -            if (is_alpha) {
 -                ff_set_dimensions(avctx, 0, 0);
 -                return -1;
 -            }
 +    if (res == VP56_SIZE_CHANGE) {
 +        if (vp56_size_changed(s)) {
 +            av_frame_unref(p);
 +            return -1;
          }
 +    }
  
 -        if (!is_alpha) {
 -            if (ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF) < 0) {
 -                av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
 -                return -1;
 +    if (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) {
 +        int bak_w = avctx->width;
 +        int bak_h = avctx->height;
 +        int bak_cw = avctx->coded_width;
 +        int bak_ch = avctx->coded_height;
 +        buf += alpha_offset;
 +        remaining_buf_size -= alpha_offset;
 +
 +        res = s->alpha_context->parse_header(s->alpha_context, buf, remaining_buf_size);
 +        if (res != 0) {
 +            if(res==VP56_SIZE_CHANGE) {
 +                av_log(avctx, AV_LOG_ERROR, "Alpha reconfiguration\n");
 +                avctx->width  = bak_w;
 +                avctx->height = bak_h;
 +                avctx->coded_width  = bak_cw;
 +                avctx->coded_height = bak_ch;
              }
 -
 -            if (res == VP56_SIZE_CHANGE)
 -                if (vp56_size_changed(avctx)) {
 -                    av_frame_unref(p);
 -                    return -1;
 -                }
 +            av_frame_unref(p);
 +            return -1;
          }
 +    }
  
 -        if (p->key_frame) {
 -            p->pict_type = AV_PICTURE_TYPE_I;
 -            s->default_models_init(s);
 -            for (block=0; block<s->mb_height*s->mb_width; block++)
 -                s->macroblocks[block].type = VP56_MB_INTRA;
 -        } else {
 -            p->pict_type = AV_PICTURE_TYPE_P;
 -            vp56_parse_mb_type_models(s);
 -            s->parse_vector_models(s);
 -            s->mb_type = VP56_MB_INTER_NOVEC_PF;
 -        }
 +    avctx->execute2(avctx, ff_vp56_decode_mbs, 0, 0, (avctx->pix_fmt == AV_PIX_FMT_YUVA420P) + 1);
  
 -        if (s->parse_coeff_models(s))
 -            goto next;
 +    if ((res = av_frame_ref(data, p)) < 0)
 +        return res;
 +    *got_frame = 1;
  
 -        memset(s->prev_dc, 0, sizeof(s->prev_dc));
 -        s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
 -        s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
 +    return avpkt->size;
 +}
  
 -        for (block=0; block < 4*s->mb_width+6; block++) {
 -            s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
 -            s->above_blocks[block].dc_coeff = 0;
 -            s->above_blocks[block].not_null_dc = 0;
 -        }
 -        s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
 -        s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
 +static int ff_vp56_decode_mbs(AVCodecContext *avctx, void *data,
 +                              int jobnr, int threadnr)
 +{
 +    VP56Context *s0 = avctx->priv_data;
 +    int is_alpha = (jobnr == 1);
 +    VP56Context *s = is_alpha ? s0->alpha_context : s0;
 +    AVFrame *const p = s->frames[VP56_FRAME_CURRENT];
 +    int mb_row, mb_col, mb_row_flip, mb_offset = 0;
 +    int block, y, uv;
 +    ptrdiff_t stride_y, stride_uv;
 +    int res;
 +
 +    if (p->key_frame) {
 +        p->pict_type = AV_PICTURE_TYPE_I;
 +        s->default_models_init(s);
 +        for (block=0; block<s->mb_height*s->mb_width; block++)
 +            s->macroblocks[block].type = VP56_MB_INTRA;
 +    } else {
 +        p->pict_type = AV_PICTURE_TYPE_P;
 +        vp56_parse_mb_type_models(s);
 +        s->parse_vector_models(s);
 +        s->mb_type = VP56_MB_INTER_NOVEC_PF;
 +    }
  
 -        stride_y  = p->linesize[0];
 -        stride_uv = p->linesize[1];
 +    if (s->parse_coeff_models(s))
 +        goto next;
  
 +    memset(s->prev_dc, 0, sizeof(s->prev_dc));
 +    s->prev_dc[1][VP56_FRAME_CURRENT] = 128;
 +    s->prev_dc[2][VP56_FRAME_CURRENT] = 128;
 +
 +    for (block=0; block < 4*s->mb_width+6; block++) {
 +        s->above_blocks[block].ref_frame = VP56_FRAME_NONE;
 +        s->above_blocks[block].dc_coeff = 0;
 +        s->above_blocks[block].not_null_dc = 0;
 +    }
 +    s->above_blocks[2*s->mb_width + 2].ref_frame = VP56_FRAME_CURRENT;
 +    s->above_blocks[3*s->mb_width + 4].ref_frame = VP56_FRAME_CURRENT;
 +
 +    stride_y  = p->linesize[0];
 +    stride_uv = p->linesize[1];
 +
 +    if (s->flip < 0)
 +        mb_offset = 7;
 +
 +    /* main macroblocks loop */
 +    for (mb_row=0; mb_row<s->mb_height; mb_row++) {
          if (s->flip < 0)
 -            mb_offset = 7;
 -
 -        /* main macroblocks loop */
 -        for (mb_row=0; mb_row<s->mb_height; mb_row++) {
 -            if (s->flip < 0)
 -                mb_row_flip = s->mb_height - mb_row - 1;
 -            else
 -                mb_row_flip = mb_row;
 -
 -            for (block=0; block<4; block++) {
 -                s->left_block[block].ref_frame = VP56_FRAME_NONE;
 -                s->left_block[block].dc_coeff = 0;
 -                s->left_block[block].not_null_dc = 0;
 -            }
 -            memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
 -            memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
 -
 -            s->above_block_idx[0] = 1;
 -            s->above_block_idx[1] = 2;
 -            s->above_block_idx[2] = 1;
 -            s->above_block_idx[3] = 2;
 -            s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
 -            s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
 -
 -            s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
 -            s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
 -            s->block_offset[1] = s->block_offset[0] + 8;
 -            s->block_offset[3] = s->block_offset[2] + 8;
 -            s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
 -            s->block_offset[5] = s->block_offset[4];
 -
 -            for (mb_col=0; mb_col<s->mb_width; mb_col++) {
 -                vp56_decode_mb(s, mb_row, mb_col, is_alpha);
 -
 -                for (y=0; y<4; y++) {
 -                    s->above_block_idx[y] += 2;
 -                    s->block_offset[y] += 16;
 -                }
 +            mb_row_flip = s->mb_height - mb_row - 1;
 +        else
 +            mb_row_flip = mb_row;
  
 -                for (uv=4; uv<6; uv++) {
 -                    s->above_block_idx[uv] += 1;
 -                    s->block_offset[uv] += 8;
 -                }
 -            }
 +        for (block=0; block<4; block++) {
 +            s->left_block[block].ref_frame = VP56_FRAME_NONE;
 +            s->left_block[block].dc_coeff = 0;
 +            s->left_block[block].not_null_dc = 0;
          }
 +        memset(s->coeff_ctx, 0, sizeof(s->coeff_ctx));
 +        memset(s->coeff_ctx_last, 24, sizeof(s->coeff_ctx_last));
 +
 +        s->above_block_idx[0] = 1;
 +        s->above_block_idx[1] = 2;
 +        s->above_block_idx[2] = 1;
 +        s->above_block_idx[3] = 2;
 +        s->above_block_idx[4] = 2*s->mb_width + 2 + 1;
 +        s->above_block_idx[5] = 3*s->mb_width + 4 + 1;
 +
 +        s->block_offset[s->frbi] = (mb_row_flip*16 + mb_offset) * stride_y;
 +        s->block_offset[s->srbi] = s->block_offset[s->frbi] + 8*stride_y;
 +        s->block_offset[1] = s->block_offset[0] + 8;
 +        s->block_offset[3] = s->block_offset[2] + 8;
 +        s->block_offset[4] = (mb_row_flip*8 + mb_offset) * stride_uv;
 +        s->block_offset[5] = s->block_offset[4];
 +
 +        for (mb_col=0; mb_col<s->mb_width; mb_col++) {
 +            vp56_decode_mb(s, mb_row, mb_col, is_alpha);
 +
 +            for (y=0; y<4; y++) {
 +                s->above_block_idx[y] += 2;
 +                s->block_offset[y] += 16;
 +            }
  
 -    next:
 -        if (p->key_frame || golden_frame) {
 -            av_frame_unref(s->frames[VP56_FRAME_GOLDEN]);
 -            if ((res = av_frame_ref(s->frames[VP56_FRAME_GOLDEN], p)) < 0)
 -                return res;
 +            for (uv=4; uv<6; uv++) {
 +                s->above_block_idx[uv] += 1;
 +                s->block_offset[uv] += 8;
 +            }
          }
 +    }
  
 -        if (s->has_alpha) {
 -            FFSWAP(AVFrame *, s->frames[VP56_FRAME_GOLDEN],
 -                              s->frames[VP56_FRAME_GOLDEN2]);
 -            buf += alpha_offset;
 -            remaining_buf_size -= alpha_offset;
 -        }
 +next:
 +    if (p->key_frame || s->golden_frame) {
 +        av_frame_unref(s->frames[VP56_FRAME_GOLDEN]);
 +        if ((res = av_frame_ref(s->frames[VP56_FRAME_GOLDEN], p)) < 0)
 +            return res;
      }
  
      av_frame_unref(s->frames[VP56_FRAME_PREVIOUS]);
      FFSWAP(AVFrame *, s->frames[VP56_FRAME_CURRENT],
                        s->frames[VP56_FRAME_PREVIOUS]);
 -
 -    if ((res = av_frame_ref(data, p)) < 0)
 -        return res;
 -    *got_frame = 1;
 -
 -    return avpkt->size;
 +    return 0;
  }
  
  av_cold int ff_vp56_init(AVCodecContext *avctx, int flip, int has_alpha)
  {
      VP56Context *s = avctx->priv_data;
 +    return ff_vp56_init_context(avctx, s, flip, has_alpha);
 +}
 +
 +av_cold int ff_vp56_init_context(AVCodecContext *avctx, VP56Context *s,
 +                                  int flip, int has_alpha)
 +{
      int i;
  
      s->avctx = avctx;
      avctx->pix_fmt = has_alpha ? AV_PIX_FMT_YUVA420P : AV_PIX_FMT_YUV420P;
 +    if (avctx->skip_alpha) avctx->pix_fmt = AV_PIX_FMT_YUV420P;
  
      ff_h264chroma_init(&s->h264chroma, 8);
      ff_hpeldsp_init(&s->hdsp, avctx->flags);
      s->macroblocks = NULL;
      s->quantizer = -1;
      s->deblock_filtering = 1;
 +    s->golden_frame = 0;
  
      s->filter = NULL;
  
      s->has_alpha = has_alpha;
 +
 +    s->modelp = &s->model;
 +
      if (flip) {
          s->flip = -1;
          s->frbi = 2;
  av_cold int ff_vp56_free(AVCodecContext *avctx)
  {
      VP56Context *s = avctx->priv_data;
 +    return ff_vp56_free_context(s);
 +}
 +
 +av_cold int ff_vp56_free_context(VP56Context *s)
 +{
      int i;
  
      av_freep(&s->above_blocks);
diff --combined libavcodec/vp6.c
@@@ -1,20 -1,20 +1,20 @@@
  /*
   * Copyright (C) 2006  Aurelien Jacobs <aurel@gnuage.org>
   *
 - * 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
   */
  
@@@ -32,6 -32,7 +32,7 @@@
  #include "avcodec.h"
  #include "get_bits.h"
  #include "huffman.h"
+ #include "internal.h"
  
  #include "vp56.h"
  #include "vp56data.h"
@@@ -42,7 -43,8 +43,7 @@@
  static void vp6_parse_coeff(VP56Context *s);
  static void vp6_parse_coeff_huffman(VP56Context *s);
  
 -static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size,
 -                            int *golden_frame)
 +static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size)
  {
      VP56RangeCoder *c = &s->c;
      int parse_filter_info = 0;
                  s->avctx->coded_width  = 16 * cols;
                  s->avctx->coded_height = 16 * rows;
              } else {
-                 avcodec_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+                 int ret = ff_set_dimensions(s->avctx, 16 * cols, 16 * rows);
+                 if (ret < 0)
+                     return ret;
                  if (s->avctx->extradata_size == 1) {
                      s->avctx->width  -= s->avctx->extradata[0] >> 4;
                      s->avctx->height -= s->avctx->extradata[0] & 0x0F;
          if (sub_version < 8)
              vrt_shift = 5;
          s->sub_version = sub_version;
 +        s->golden_frame = 0;
      } else {
          if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height)
              return AVERROR_INVALIDDATA;
          }
          ff_vp56_init_range_decoder(c, buf+1, buf_size-1);
  
 -        *golden_frame = vp56_rac_get(c);
 +        s->golden_frame = vp56_rac_get(c);
          if (s->filter_header) {
              s->deblock_filtering = vp56_rac_get(c);
              if (s->deblock_filtering)
          buf_size -= coeff_offset;
          if (buf_size < 0) {
              if (s->frames[VP56_FRAME_CURRENT]->key_frame)
-                 avcodec_set_dimensions(s->avctx, 0, 0);
+                 ff_set_dimensions(s->avctx, 0, 0);
              return AVERROR_INVALIDDATA;
          }
          if (s->use_huffman) {
@@@ -248,8 -252,7 +252,8 @@@ static int vp6_build_huff_tree(VP56Cont
  
      ff_free_vlc(vlc);
      /* then build the huffman tree according to probabilities */
 -    return ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp,
 +    return ff_huff_build_tree(s->avctx, vlc, size, FF_HUFFMAN_BITS,
 +                              nodes, vp6_huff_cmp,
                                FF_HUFFMAN_FLAG_HNODE_FIRST);
  }
  
@@@ -399,11 -402,11 +403,11 @@@ static void vp6_parse_coeff_huffman(VP5
              } else {
                  if (get_bits_left(&s->gb) <= 0)
                      return;
 -                coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3);
 +                coeff = get_vlc2(&s->gb, vlc_coeff->table, FF_HUFFMAN_BITS, 3);
                  if (coeff == 0) {
                      if (coeff_idx) {
                          int pt = (coeff_idx >= 6);
 -                        run += get_vlc2(&s->gb, s->runv_vlc[pt].table, 9, 3);
 +                        run += get_vlc2(&s->gb, s->runv_vlc[pt].table, FF_HUFFMAN_BITS, 3);
                          if (run >= 9)
                              run += get_bits(&s->gb, 6);
                      } else
@@@ -600,8 -603,6 +604,8 @@@ static void vp6_filter(VP56Context *s, 
      }
  }
  
 +static av_cold void vp6_decode_init_context(VP56Context *s);
 +
  static av_cold int vp6_decode_init(AVCodecContext *avctx)
  {
      VP56Context *s = avctx->priv_data;
                              avctx->codec->id == AV_CODEC_ID_VP6A)) < 0)
          return ret;
  
 +    vp6_decode_init_context(s);
 +
 +    if (s->has_alpha) {
 +        s->alpha_context = av_mallocz(sizeof(VP56Context));
 +        ff_vp56_init_context(avctx, s->alpha_context,
 +                             s->flip == -1, s->has_alpha);
 +        vp6_decode_init_context(s->alpha_context);
 +    }
 +
 +    return 0;
 +}
 +
 +static av_cold void vp6_decode_init_context(VP56Context *s)
 +{
 +    s->deblock_filtering = 0;
      s->vp56_coord_div = vp6_coord_div;
      s->parse_vector_adjustment = vp6_parse_vector_adjustment;
      s->filter = vp6_filter;
      s->parse_vector_models = vp6_parse_vector_models;
      s->parse_coeff_models = vp6_parse_coeff_models;
      s->parse_header = vp6_parse_header;
 -
 -    return 0;
  }
  
 +static av_cold void vp6_decode_free_context(VP56Context *s);
 +
  static av_cold int vp6_decode_free(AVCodecContext *avctx)
  {
      VP56Context *s = avctx->priv_data;
 -    int pt, ct, cg;
  
      ff_vp56_free(avctx);
 +    vp6_decode_free_context(s);
 +
 +    if (s->alpha_context) {
 +        ff_vp56_free_context(s->alpha_context);
 +        vp6_decode_free_context(s->alpha_context);
 +        av_free(s->alpha_context);
 +    }
 +
 +    return 0;
 +}
 +
 +static av_cold void vp6_decode_free_context(VP56Context *s)
 +{
 +    int pt, ct, cg;
  
      for (pt=0; pt<2; pt++) {
          ff_free_vlc(&s->dccv_vlc[pt]);
              for (cg=0; cg<6; cg++)
                  ff_free_vlc(&s->ract_vlc[pt][ct][cg]);
      }
 -    return 0;
  }
  
  AVCodec ff_vp6_decoder = {
@@@ -701,5 -675,5 +705,5 @@@ AVCodec ff_vp6a_decoder = 
      .init           = vp6_decode_init,
      .close          = vp6_decode_free,
      .decode         = ff_vp56_decode_frame,
 -    .capabilities   = CODEC_CAP_DR1,
 +    .capabilities   = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
  };
diff --combined libavcodec/vp8.c
@@@ -6,20 -6,20 +6,20 @@@
   * Copyright (C) 2010 Jason Garrett-Glaser
   * Copyright (C) 2012 Daniel Kang
   *
 - * 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
   */
  
@@@ -45,6 -45,7 +45,6 @@@ static void free_buffers(VP8Context *s
              pthread_mutex_destroy(&s->thread_data[i].lock);
  #endif
              av_freep(&s->thread_data[i].filter_strength);
 -            av_freep(&s->thread_data[i].edge_emu_buffer);
          }
      av_freep(&s->thread_data);
      av_freep(&s->macroblocks_base);
@@@ -113,16 -114,15 +113,15 @@@ static void vp8_decode_flush(AVCodecCon
  static int update_dimensions(VP8Context *s, int width, int height)
  {
      AVCodecContext *avctx = s->avctx;
-     int i;
+     int i, ret;
  
 -    if (width  != s->avctx->width ||
 +    if (width  != s->avctx->width || ((width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) && s->macroblocks_base ||
          height != s->avctx->height) {
-         if (av_image_check_size(width, height, 0, s->avctx))
-             return AVERROR_INVALIDDATA;
          vp8_decode_flush_impl(s->avctx, 1);
  
-         avcodec_set_dimensions(s->avctx, width, height);
+         ret = ff_set_dimensions(s->avctx, width, height);
+         if (ret < 0)
+             return ret;
      }
  
      s->mb_width  = (s->avctx->coded_width +15) / 16;
@@@ -383,7 -383,7 +382,7 @@@ static int decode_frame_header(VP8Conte
      }
  
      if (!s->macroblocks_base || /* first frame */
 -        width != s->avctx->width || height != s->avctx->height) {
 +        width != s->avctx->width || height != s->avctx->height || (width+15)/16 != s->mb_width || (height+15)/16 != s->mb_height) {
          if ((ret = update_dimensions(s, width, height)) < 0)
              return ret;
      }
@@@ -699,10 -699,9 +698,10 @@@ void decode_mb_mode(VP8Context *s, VP8M
  {
      VP56RangeCoder *c = &s->c;
  
 -    if (s->segmentation.update_map)
 -        *segment = vp8_rac_get_tree(c, vp8_segmentid_tree, s->prob->segmentid);
 -    else if (s->segmentation.enabled)
 +    if (s->segmentation.update_map) {
 +        int bit  = vp56_rac_get_prob(c, s->prob->segmentid[0]);
 +        *segment = vp56_rac_get_prob(c, s->prob->segmentid[1+bit]) + 2*bit;
 +    } else if (s->segmentation.enabled)
          *segment = ref ? *ref : *segment;
      mb->segment = *segment;
  
@@@ -1185,7 -1184,7 +1184,7 @@@ void vp8_mc_luma(VP8Context *s, VP8Thre
      uint8_t *src = ref->f->data[0];
  
      if (AV_RN32A(mv)) {
 -
 +        int src_linesize = linesize;
          int mx = (mv->x << 1)&7, mx_idx = subpel_idx[0][mx];
          int my = (mv->y << 1)&7, my_idx = subpel_idx[0][my];
  
          src += y_off * linesize + x_off;
          if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
              y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
 -            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src - my_idx * linesize - mx_idx, linesize,
 -                                     block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
 +            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, 32,
 +                                     src - my_idx * linesize - mx_idx, linesize,
 +                                     block_w + subpel_idx[1][mx],
 +                                     block_h + subpel_idx[1][my],
                                       x_off - mx_idx, y_off - my_idx, width, height);
 -            src = td->edge_emu_buffer + mx_idx + linesize * my_idx;
 +            src = td->edge_emu_buffer + mx_idx + 32 * my_idx;
 +            src_linesize = 32;
          }
 -        mc_func[my_idx][mx_idx](dst, linesize, src, linesize, block_h, mx, my);
 +        mc_func[my_idx][mx_idx](dst, linesize, src, src_linesize, block_h, mx, my);
      } else {
          ff_thread_await_progress(ref, (3 + y_off + block_h) >> 4, 0);
          mc_func[0][0](dst, linesize, src + y_off * linesize + x_off, linesize, block_h, 0, 0);
@@@ -1250,21 -1246,17 +1249,21 @@@ void vp8_mc_chroma(VP8Context *s, VP8Th
          ff_thread_await_progress(ref, (3 + y_off + block_h + subpel_idx[2][my]) >> 3, 0);
          if (x_off < mx_idx || x_off >= width  - block_w - subpel_idx[2][mx] ||
              y_off < my_idx || y_off >= height - block_h - subpel_idx[2][my]) {
 -            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src1 - my_idx * linesize - mx_idx, linesize,
 -                                     block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
 +            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, 32,
 +                                     src1 - my_idx * linesize - mx_idx, linesize,
 +                                     block_w + subpel_idx[1][mx],
 +                                     block_h + subpel_idx[1][my],
                                       x_off - mx_idx, y_off - my_idx, width, height);
 -            src1 = td->edge_emu_buffer + mx_idx + linesize * my_idx;
 -            mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
 +            src1 = td->edge_emu_buffer + mx_idx + 32 * my_idx;
 +            mc_func[my_idx][mx_idx](dst1, linesize, src1, 32, block_h, mx, my);
  
 -            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, src2 - my_idx * linesize - mx_idx, linesize,
 -                                     block_w + subpel_idx[1][mx], block_h + subpel_idx[1][my],
 +            s->vdsp.emulated_edge_mc(td->edge_emu_buffer, 32,
 +                                     src2 - my_idx * linesize - mx_idx, linesize,
 +                                     block_w + subpel_idx[1][mx],
 +                                     block_h + subpel_idx[1][my],
                                       x_off - mx_idx, y_off - my_idx, width, height);
 -            src2 = td->edge_emu_buffer + mx_idx + linesize * my_idx;
 -            mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
 +            src2 = td->edge_emu_buffer + mx_idx + 32 * my_idx;
 +            mc_func[my_idx][mx_idx](dst2, linesize, src2, 32, block_h, mx, my);
          } else {
              mc_func[my_idx][mx_idx](dst1, linesize, src1, linesize, block_h, mx, my);
              mc_func[my_idx][mx_idx](dst2, linesize, src2, linesize, block_h, mx, my);
@@@ -1924,8 -1916,10 +1923,8 @@@ int ff_vp8_decode_frame(AVCodecContext 
  
      curframe->tf.f->key_frame = s->keyframe;
      curframe->tf.f->pict_type = s->keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P;
 -    if ((ret = vp8_alloc_frame(s, curframe, referenced))) {
 -        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed!\n");
 +    if ((ret = vp8_alloc_frame(s, curframe, referenced)) < 0)
          goto err;
 -    }
  
      // check if golden and altref are swapped
      if (s->update_altref != VP56_FRAME_NONE) {
      s->linesize   = curframe->tf.f->linesize[0];
      s->uvlinesize = curframe->tf.f->linesize[1];
  
 -    if (!s->thread_data[0].edge_emu_buffer)
 -        for (i = 0; i < MAX_THREADS; i++)
 -            s->thread_data[i].edge_emu_buffer = av_malloc(21*s->linesize);
 -
      memset(s->top_nnz, 0, s->mb_width*sizeof(*s->top_nnz));
      /* Zero macroblock structures for top/top-left prediction from outside the frame. */
      if (!s->mb_layout)
@@@ -2106,52 -2104,6 +2105,52 @@@ static int vp8_decode_update_thread_con
      return 0;
  }
  
 +static unsigned apply_padding(unsigned size) { return size + (size & 1); }
 +
 +static int webp_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
 +                             AVPacket *avpkt)
 +{
 +    const uint8_t *buf = avpkt->data;
 +    int buf_size       = avpkt->size;
 +    AVPacket pkt       = *avpkt;
 +
 +    if (buf_size >= 16
 +        && AV_RL32(buf   ) == AV_RL32("RIFF")
 +        && AV_RL32(buf+ 8) == AV_RL32("WEBP")) {
 +        unsigned riff_size = apply_padding(AV_RL32(buf+4)) + 8;
 +        buf += 12;   // Skip over main header
 +        buf_size -= 12;
 +        if (buf_size < 8 || riff_size < 8) {
 +            av_log(avctx, AV_LOG_ERROR, "Incomplete header.\n");
 +            return AVERROR_INVALIDDATA;
 +        }
 +        if (AV_RL32(buf) == AV_RL32("VP8L")) {
 +            av_log(avctx, AV_LOG_ERROR, "Unsupported WebP lossless format.\n");
 +            return AVERROR_PATCHWELCOME;
 +        }
 +        if (AV_RL32(buf) == AV_RL32("VP8X") && AV_RL32(buf+4) < (unsigned)buf_size) {
 +            unsigned size = apply_padding(AV_RL32(buf+4) + 8);
 +            buf      += size;
 +            buf_size -= size;
 +        }
 +        if (buf_size >= 8
 +            && AV_RL32(buf) == AV_RL32("ALPH") && AV_RL32(buf+4) < (unsigned)buf_size) {
 +            unsigned size = apply_padding(AV_RL32(buf+4) + 8);
 +            buf      += size;
 +            buf_size -= size;
 +            av_log(avctx, AV_LOG_WARNING, "Skipping alpha plane\n");
 +        }
 +        if (buf_size >= 8 && AV_RL32(buf) == AV_RL32("VP8 ")) {
 +            buf      += 8;
 +            buf_size -= 8;
 +        }
 +    }
 +    pkt.data = buf;
 +    pkt.size = buf_size;
 +
 +    return ff_vp8_decode_frame(avctx, data, data_size, &pkt);
 +}
 +
  AVCodec ff_vp8_decoder = {
      .name                  = "vp8",
      .long_name             = NULL_IF_CONFIG_SMALL("On2 VP8"),
      .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
      .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
  };
 +
 +// AVCodec ff_webp_decoder = {
 +//     .name                  = "webp",
 +//     .long_name             = NULL_IF_CONFIG_SMALL("WebP"),
 +//     .type                  = AVMEDIA_TYPE_VIDEO,
 +//     .id                    = AV_CODEC_ID_WEBP,
 +//     .priv_data_size        = sizeof(VP8Context),
 +//     .init                  = vp8_decode_init,
 +//     .close                 = vp8_decode_free,
 +//     .decode                = webp_decode_frame,
 +//     .capabilities          = CODEC_CAP_DR1 | CODEC_CAP_FRAME_THREADS | CODEC_CAP_SLICE_THREADS,
 +//     .flush                 = vp8_decode_flush,
 +//     .init_thread_copy      = ONLY_IF_THREADS_ENABLED(vp8_decode_init_thread_copy),
 +//     .update_thread_context = ONLY_IF_THREADS_ENABLED(vp8_decode_update_thread_context),
 +// };