diff --git a/test/encode_test_driver.cc b/test/encode_test_driver.cc
index b2b6e0d6d40bbda3f9cc11bf06bad51075a8636c..39d154b139b75a728918aa9820f5f747d9445bfd 100644
--- a/test/encode_test_driver.cc
+++ b/test/encode_test_driver.cc
@@ -201,6 +201,8 @@ void EncoderTest::RunLoop(VideoSource *video) {
             MismatchHook(img_enc, img_dec);
           }
         }
+        if (img_dec)
+          DecompressedFrameHook(*img_dec, video->pts());
       }
       if (!Continue())
         break;
diff --git a/test/encode_test_driver.h b/test/encode_test_driver.h
index 0944dc2c65fd473f2d94352f385e9c34b8b1810a..35082a7fdac2e42729595e0ca317eb8ecb496a7b 100644
--- a/test/encode_test_driver.h
+++ b/test/encode_test_driver.h
@@ -117,6 +117,11 @@ class Encoder {
     ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
   }
 
+  void Control(int ctrl_id, struct vpx_scaling_mode *arg) {
+    const vpx_codec_err_t res = vpx_codec_control_(&encoder_, ctrl_id, arg);
+    ASSERT_EQ(VPX_CODEC_OK, res) << EncoderError();
+  }
+
   void set_deadline(unsigned long deadline) {
     deadline_ = deadline;
   }
@@ -194,6 +199,10 @@ class EncoderTest {
   virtual void MismatchHook(const vpx_image_t *img1,
                             const vpx_image_t *img2);
 
+  // Hook to be called on every decompressed frame.
+  virtual void DecompressedFrameHook(const vpx_image_t& img,
+                                     vpx_codec_pts_t pts) {}
+
   bool                 abort_;
   vpx_codec_enc_cfg_t  cfg_;
   unsigned int         passes_;
diff --git a/test/resize_test.cc b/test/resize_test.cc
index 0ce8940a373b656ae419769ef320e15fbcb3ba4a..5e9234c38f4ff7fe4388b11e23bb0311e46c4d4b 100644
--- a/test/resize_test.cc
+++ b/test/resize_test.cc
@@ -12,6 +12,7 @@
 #include "third_party/googletest/src/include/gtest/gtest.h"
 #include "test/codec_factory.h"
 #include "test/encode_test_driver.h"
+#include "test/i420_video_source.h"
 #include "test/video_source.h"
 #include "test/util.h"
 
@@ -73,15 +74,9 @@ class ResizeTest : public ::libvpx_test::EncoderTest,
     return !HasFatalFailure() && !abort_;
   }
 
-  virtual void FramePktHook(const vpx_codec_cx_pkt_t *pkt) {
-    if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
-      const unsigned char *buf =
-          reinterpret_cast<const unsigned char *>(pkt->data.frame.buf);
-      const unsigned int w = (buf[6] | (buf[7] << 8)) & 0x3fff;
-      const unsigned int h = (buf[8] | (buf[9] << 8)) & 0x3fff;
-
-      frame_info_list_.push_back(FrameInfo(pkt->data.frame.pts, w, h));
-    }
+  virtual void DecompressedFrameHook(const vpx_image_t &img,
+                                     vpx_codec_pts_t pts) {
+    frame_info_list_.push_back(FrameInfo(pts, img.d_w, img.d_h));
   }
 
   std::vector< FrameInfo > frame_info_list_;
@@ -104,5 +99,38 @@ TEST_P(ResizeTest, TestExternalResizeWorks) {
   }
 }
 
+class ResizeInternalTest : public ResizeTest {
+ protected:
+  ResizeInternalTest() : ResizeTest() {}
+
+  virtual void PreEncodeFrameHook(libvpx_test::VideoSource *video,
+                                  libvpx_test::Encoder *encoder) {
+    if (video->frame() == 3) {
+      struct vpx_scaling_mode mode = {VP8E_FOURFIVE, VP8E_THREEFIVE};
+      encoder->Control(VP8E_SET_SCALEMODE, &mode);
+    }
+  }
+};
+
+TEST_P(ResizeInternalTest, TestInternalResizeWorks) {
+  ::libvpx_test::I420VideoSource video("hantro_collage_w352h288.yuv", 352, 288,
+                                       30, 1, 0, 5);
+  ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+
+  for (std::vector<FrameInfo>::iterator info = frame_info_list_.begin();
+       info != frame_info_list_.end(); ++info) {
+    const vpx_codec_pts_t pts = info->pts;
+    if (pts >= 3) {
+      ASSERT_EQ(282U, info->w) << "Frame " << pts << " had unexpected width";
+      ASSERT_EQ(173U, info->h) << "Frame " << pts << " had unexpected height";
+    } else {
+      EXPECT_EQ(352U, info->w) << "Frame " << pts << " had unexpected width";
+      EXPECT_EQ(288U, info->h) << "Frame " << pts << " had unexpected height";
+    }
+  }
+}
+
 VP8_INSTANTIATE_TEST_CASE(ResizeTest, ONE_PASS_TEST_MODES);
+VP9_INSTANTIATE_TEST_CASE(ResizeInternalTest,
+                          ::testing::Values(::libvpx_test::kOnePassBest));
 }  // namespace
diff --git a/vp9/decoder/vp9_decodframe.c b/vp9/decoder/vp9_decodframe.c
index 384033fbcfb5ded4ae3859cdda90f11b3009a02c..3324186efd37ea13c4b7857a4e53de88b3630d7f 100644
--- a/vp9/decoder/vp9_decodframe.c
+++ b/vp9/decoder/vp9_decodframe.c
@@ -1367,9 +1367,6 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
     vp9_setup_version(pc);
 
     if (pc->frame_type == KEY_FRAME) {
-      const int Width = pc->Width;
-      const int Height = pc->Height;
-
       /* vet via sync code */
       /* When error concealment is enabled we should only check the sync
        * code if we have enough bits available
@@ -1379,18 +1376,23 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
           vpx_internal_error(&pc->error, VPX_CODEC_UNSUP_BITSTREAM,
                              "Invalid frame sync code");
       }
+      data += 3;
+    }
+    {
+      const int Width = pc->Width;
+      const int Height = pc->Height;
 
       /* If error concealment is enabled we should only parse the new size
        * if we have enough data. Otherwise we will end up with the wrong
        * size.
        */
-      if (data + 6 < data_end) {
-        pc->Width = (data[3] | (data[4] << 8)) & 0x3fff;
-        pc->horiz_scale = data[4] >> 6;
-        pc->Height = (data[5] | (data[6] << 8)) & 0x3fff;
-        pc->vert_scale = data[6] >> 6;
+      if (data + 4 < data_end) {
+        pc->Width = (data[0] | (data[1] << 8)) & 0x3fff;
+        pc->horiz_scale = data[1] >> 6;
+        pc->Height = (data[2] | (data[3] << 8)) & 0x3fff;
+        pc->vert_scale = data[3] >> 6;
       }
-      data += 7;
+      data += 4;
 
       if (Width != pc->Width  ||  Height != pc->Height) {
         if (pc->Width <= 0) {
@@ -1423,10 +1425,8 @@ int vp9_decode_frame(VP9D_COMP *pbi, const unsigned char **p_data_end) {
                        (unsigned int)first_partition_length_in_bytes))
     vpx_internal_error(&pc->error, VPX_CODEC_MEM_ERROR,
                        "Failed to allocate bool decoder 0");
-  if (pc->frame_type == KEY_FRAME) {
-    pc->clr_type    = (YUV_TYPE)vp9_read_bit(&header_bc);
-    pc->clamp_type  = (CLAMP_TYPE)vp9_read_bit(&header_bc);
-  }
+  pc->clr_type    = (YUV_TYPE)vp9_read_bit(&header_bc);
+  pc->clamp_type  = (CLAMP_TYPE)vp9_read_bit(&header_bc);
 
   pc->error_resilient_mode = vp9_read_bit(&header_bc);
   /* Is segmentation enabled */
diff --git a/vp9/encoder/vp9_bitstream.c b/vp9/encoder/vp9_bitstream.c
index 71109f8f4d9571895603dc8dab5dfc9ce878bc85..eec83a0a8a86dc63dd042fc3c0daa2b78dc9f7c2 100644
--- a/vp9/encoder/vp9_bitstream.c
+++ b/vp9/encoder/vp9_bitstream.c
@@ -1532,33 +1532,34 @@ void vp9_pack_bitstream(VP9_COMP *cpi, unsigned char *dest,
    * and color type.
    */
   if (oh.type == KEY_FRAME) {
-    int v;
-
     // Start / synch code
     cx_data[0] = 0x9D;
     cx_data[1] = 0x01;
     cx_data[2] = 0x2a;
+    extra_bytes_packed = 3;
+    cx_data += extra_bytes_packed;
+  }
+  {
+    int v;
 
+    /* TODO(jkoleszar): support arbitrary resolutions */
     v = (pc->horiz_scale << 14) | pc->Width;
-    cx_data[3] = v;
-    cx_data[4] = v >> 8;
+    cx_data[0] = v;
+    cx_data[1] = v >> 8;
 
     v = (pc->vert_scale << 14) | pc->Height;
-    cx_data[5] = v;
-    cx_data[6] = v >> 8;
+    cx_data[2] = v;
+    cx_data[3] = v >> 8;
 
-    extra_bytes_packed = 7;
-    cx_data += extra_bytes_packed;
-
-    vp9_start_encode(&header_bc, cx_data);
+    extra_bytes_packed += 4;
+    cx_data += 4;
+  }
 
-    // signal clr type
-    vp9_write_bit(&header_bc, pc->clr_type);
-    vp9_write_bit(&header_bc, pc->clamp_type);
+  vp9_start_encode(&header_bc, cx_data);
 
-  } else {
-    vp9_start_encode(&header_bc, cx_data);
-  }
+  // TODO(jkoleszar): remove these two unused bits?
+  vp9_write_bit(&header_bc, pc->clr_type);
+  vp9_write_bit(&header_bc, pc->clamp_type);
 
   // error resilient mode
   vp9_write_bit(&header_bc, pc->error_resilient_mode);
diff --git a/vp9/encoder/vp9_onyx_if.c b/vp9/encoder/vp9_onyx_if.c
index 280a3224dcd84f74e037eebe72f98c70a283a416..3bbe9761c74f89a533ffd104afc917bb1f7320cc 100644
--- a/vp9/encoder/vp9_onyx_if.c
+++ b/vp9/encoder/vp9_onyx_if.c
@@ -1005,6 +1005,38 @@ void vp9_alloc_compressor_data(VP9_COMP *cpi) {
 }
 
 
+static void update_frame_size(VP9_COMP *cpi) {
+  VP9_COMMON *cm = &cpi->common;
+
+  /* our internal buffers are always multiples of 16 */
+  int width = (cm->Width + 15) & ~15;
+  int height = (cm->Height + 15) & ~15;
+
+  cm->mb_rows = height >> 4;
+  cm->mb_cols = width >> 4;
+  cm->MBs = cm->mb_rows * cm->mb_cols;
+  cm->mode_info_stride = cm->mb_cols + 1;
+  memset(cm->mip, 0,
+        (cm->mb_cols + 1) * (cm->mb_rows + 1) * sizeof(MODE_INFO));
+  vp9_update_mode_info_border(cm, cm->mip);
+
+  cm->mi = cm->mip + cm->mode_info_stride + 1;
+  cm->prev_mi = cm->prev_mip + cm->mode_info_stride + 1;
+  vp9_update_mode_info_in_image(cm, cm->mi);
+
+  /* Update size of buffers local to this frame */
+  if (vp8_yv12_realloc_frame_buffer(&cpi->last_frame_uf,
+                                    width, height, VP9BORDERINPIXELS))
+    vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+                       "Failed to reallocate last frame buffer");
+
+  if (vp8_yv12_realloc_frame_buffer(&cpi->scaled_source,
+                                    width, height, VP9BORDERINPIXELS))
+    vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
+                       "Failed to reallocate scaled source buffer");
+}
+
+
 // TODO perhaps change number of steps expose to outside world when setting
 // max and min limits. Also this will likely want refining for the extended Q
 // range.
@@ -1302,14 +1334,18 @@ void vp9_change_config(VP9_PTR ptr, VP9_CONFIG *oxcf) {
     cm->Height = (vs - 1 + cpi->oxcf.Height * vr) / vs;
   }
 
-  if (((cm->Width + 15) & 0xfffffff0) !=
-      cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_width ||
-      ((cm->Height + 15) & 0xfffffff0) !=
-      cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_height ||
-      cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_width == 0) {
+  // Increasing the size of the frame beyond the first seen frame, or some
+  // otherwise signalled maximum size, is not supported.
+  // TODO(jkoleszar): exit gracefully.
+  if (!cpi->initial_width) {
     alloc_raw_frame_buffers(cpi);
     vp9_alloc_compressor_data(cpi);
+    cpi->initial_width = cm->Width;
+    cpi->initial_height = cm->Height;
   }
+  assert(cm->Width <= cpi->initial_width);
+  assert(cm->Height <= cpi->initial_height);
+  update_frame_size(cpi);
 
   if (cpi->oxcf.fixed_q >= 0) {
     cpi->last_q[0] = cpi->oxcf.fixed_q;
@@ -3776,6 +3812,28 @@ int vp9_get_compressed_data(VP9_PTR ptr, unsigned int *frame_flags,
   cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
   cm->new_fb_idx = get_free_fb(cm);
 
+  /* Reset the frame pointers to the current frame size */
+  vp8_yv12_realloc_frame_buffer(&cm->yv12_fb[cm->new_fb_idx],
+                                cm->mb_cols * 16, cm->mb_rows * 16,
+                                VP9BORDERINPIXELS);
+
+  /* Disable any references that have different size */
+  if ((cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_width !=
+       cm->yv12_fb[cm->new_fb_idx].y_width) ||
+      (cm->yv12_fb[cm->active_ref_idx[cpi->lst_fb_idx]].y_height !=
+       cm->yv12_fb[cm->new_fb_idx].y_height))
+    cpi->ref_frame_flags &= ~VP9_LAST_FLAG;
+  if ((cm->yv12_fb[cm->active_ref_idx[cpi->gld_fb_idx]].y_width !=
+       cm->yv12_fb[cm->new_fb_idx].y_width) ||
+      (cm->yv12_fb[cm->active_ref_idx[cpi->gld_fb_idx]].y_height !=
+       cm->yv12_fb[cm->new_fb_idx].y_height))
+    cpi->ref_frame_flags &= ~VP9_GOLD_FLAG;
+  if ((cm->yv12_fb[cm->active_ref_idx[cpi->alt_fb_idx]].y_width !=
+       cm->yv12_fb[cm->new_fb_idx].y_width) ||
+      (cm->yv12_fb[cm->active_ref_idx[cpi->alt_fb_idx]].y_height !=
+       cm->yv12_fb[cm->new_fb_idx].y_height))
+    cpi->ref_frame_flags &= ~VP9_ALT_FLAG;
+
   vp9_setup_interp_filters(&cpi->mb.e_mbd, DEFAULT_INTERP_FILTER, cm);
   if (cpi->pass == 1) {
     Pass1Encode(cpi, size, dest, frame_flags);
@@ -4027,15 +4085,16 @@ int vp9_set_internal_size(VP9_PTR comp,
   VP9_COMP *cpi = (VP9_COMP *) comp;
 
   if (horiz_mode <= ONETWO)
-    cpi->common.horiz_scale = horiz_mode;
+    cpi->horiz_scale = horiz_mode;
   else
     return -1;
 
   if (vert_mode <= ONETWO)
-    cpi->common.vert_scale  = vert_mode;
+    cpi->vert_scale = vert_mode;
   else
     return -1;
 
+  vp9_change_config(comp, &cpi->oxcf);
   return 0;
 }
 
diff --git a/vp9/encoder/vp9_onyx_int.h b/vp9/encoder/vp9_onyx_int.h
index b7cb558d029efb36784e2b9f19e859dd545831b5..156f86f985cf7b50be25f6661f5df2455b7280b8 100644
--- a/vp9/encoder/vp9_onyx_int.h
+++ b/vp9/encoder/vp9_onyx_int.h
@@ -678,6 +678,8 @@ typedef struct VP9_COMP {
   unsigned int mb_mv_ref_count[MAX_REF_FRAMES][MAX_MV_REF_CANDIDATES];
 #endif
 
+  int initial_width;
+  int initial_height;
 } VP9_COMP;
 
 void vp9_encode_frame(VP9_COMP *cpi);
diff --git a/vp9/encoder/vp9_picklpf.c b/vp9/encoder/vp9_picklpf.c
index b443ede6fae6a121e19b3bba247a41ebdb716d89..6f93335214b3ca33b2e58fa2cf487b751daf8e24 100644
--- a/vp9/encoder/vp9_picklpf.c
+++ b/vp9/encoder/vp9_picklpf.c
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-
+#include <assert.h>
 #include "vp9/common/vp9_onyxc_int.h"
 #include "vp9/encoder/vp9_onyx_int.h"
 #include "vp9/encoder/vp9_picklpf.h"
@@ -27,6 +27,7 @@ void vp9_yv12_copy_partial_frame_c(YV12_BUFFER_CONFIG *src_ybc,
   int yoffset;
   int linestocopy;
 
+  assert(src_ybc->y_stride == dst_ybc->y_stride);
   yheight  = src_ybc->y_height;
   ystride  = src_ybc->y_stride;
 
diff --git a/vp9/encoder/vp9_rdopt.c b/vp9/encoder/vp9_rdopt.c
index c50c55ff9f304251b51ce3a93dfd75373914bdf0..370374164cfd9fccd646a5d4f475057719e2eb85 100644
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3517,6 +3517,8 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
                                int recon_yoffset, int recon_uvoffset,
                                int *returnrate, int *returndistortion,
                                int64_t *returnintra) {
+  static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
+                                    VP9_ALT_FLAG };
   VP9_COMMON *cm = &cpi->common;
   MACROBLOCKD *xd = &x->e_mbd;
   union b_mode_info best_bmodes[16];
@@ -3684,6 +3686,16 @@ static void rd_pick_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
     if (best_rd <= cpi->rd_threshes[mode_index])
       continue;
 
+    // Ensure that the references used by this mode are available.
+    if (mbmi->ref_frame &&
+        !(cpi->ref_frame_flags & flag_list[mbmi->ref_frame]))
+      continue;
+
+    if (mbmi->second_ref_frame > 0 &&
+        !(cpi->ref_frame_flags & flag_list[mbmi->second_ref_frame]))
+      continue;
+
+
     // current coding mode under rate-distortion optimization test loop
 #if CONFIG_COMP_INTERINTRA_PRED
     mbmi->interintra_mode = (MB_PREDICTION_MODE)(DC_PRED - 1);
diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c
index a6b74bc37913e09de9983d2d4d6861ab41e88352..0b8677285f7adc127c0012f2385c3215474608fd 100644
--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -80,7 +80,6 @@ struct vpx_codec_alg_priv {
   unsigned char          *pending_cx_data;
   unsigned int            pending_cx_data_sz;
   vpx_image_t             preview_img;
-  unsigned int            next_frame_flag;
   vp8_postproc_cfg_t      preview_ppcfg;
   vpx_codec_pkt_list_decl(64) pkt_list;              // changed to accomendate the maximum number of lagged frames allowed
   unsigned int                fixed_kf_cntr;
@@ -678,14 +677,11 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t  *ctx,
     if (img != NULL) {
       res = image2yuvconfig(img, &sd);
 
-      if (vp9_receive_raw_frame(ctx->cpi, ctx->next_frame_flag | lib_flags,
+      if (vp9_receive_raw_frame(ctx->cpi, lib_flags,
                                 &sd, dst_time_stamp, dst_end_time_stamp)) {
         VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
         res = update_error_state(ctx, &cpi->common.error);
       }
-
-      /* reset for next frame */
-      ctx->next_frame_flag = 0;
     }
 
     cx_data = ctx->cx_data;
@@ -987,8 +983,6 @@ static vpx_codec_err_t vp8e_set_scalemode(vpx_codec_alg_priv_t *ctx,
                                 scalemode.v_scaling_mode);
 
     if (!res) {
-      /*force next frame a key frame to effect scaling mode */
-      ctx->next_frame_flag |= FRAMEFLAGS_KEY;
       return VPX_CODEC_OK;
     } else
       return VPX_CODEC_INVALID_PARAM;
diff --git a/vpx_scale/generic/yv12config.c b/vpx_scale/generic/yv12config.c
index 4cb2a41904c87d41d99f3bc66f843fe2a0436664..267d55f40aba8e23a07ed0b12345c126591c0356 100644
--- a/vpx_scale/generic/yv12config.c
+++ b/vpx_scale/generic/yv12config.c
@@ -35,13 +35,8 @@ vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf) {
   return 0;
 }
 
-/****************************************************************************
- *
- ****************************************************************************/
-int
-vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border) {
-  /*NOTE:*/
-
+int vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
+                                  int width, int height, int border) {
   if (ybf) {
     int y_stride = ((width + 2 * border) + 31) & ~31;
     int yplane_size = (height + 2 * border) * y_stride;
@@ -51,8 +46,15 @@ vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int
       *  uv_stride == y_stride/2, so enforce this here. */
     int uv_stride = y_stride >> 1;
     int uvplane_size = (uv_height + border) * uv_stride;
+    const int frame_size = yplane_size + 2 * uvplane_size;
 
-    vp8_yv12_de_alloc_frame_buffer(ybf);
+    if (!ybf->buffer_alloc) {
+      ybf->buffer_alloc = vpx_memalign(32, frame_size);
+      ybf->buffer_alloc_sz = frame_size;
+    }
+
+    if (!ybf->buffer_alloc || ybf->buffer_alloc_sz < frame_size)
+      return -1;
 
     /** Only support allocating buffers that have a height and width that
       *  are multiples of 16, and a border that's a multiple of 32.
@@ -72,21 +74,23 @@ vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int
     ybf->uv_stride = uv_stride;
 
     ybf->border = border;
-    ybf->frame_size = yplane_size + 2 * uvplane_size;
-
-    ybf->buffer_alloc = (unsigned char *) vpx_memalign(32, ybf->frame_size);
-
-    if (ybf->buffer_alloc == NULL)
-      return -1;
+    ybf->frame_size = frame_size;
 
     ybf->y_buffer = ybf->buffer_alloc + (border * y_stride) + border;
     ybf->u_buffer = ybf->buffer_alloc + yplane_size + (border / 2  * uv_stride) + border / 2;
     ybf->v_buffer = ybf->buffer_alloc + yplane_size + uvplane_size + (border / 2  * uv_stride) + border / 2;
 
     ybf->corrupted = 0; /* assume not currupted by errors */
-  } else {
-    return -2;
+    return 0;
   }
+  return -2;
+}
 
-  return 0;
+int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
+                                int width, int height, int border) {
+  if (ybf) {
+    vp8_yv12_de_alloc_frame_buffer(ybf);
+    return vp8_yv12_realloc_frame_buffer(ybf, width, height, border);
+  }
+  return -2;
 }
diff --git a/vpx_scale/generic/yv12extend.c b/vpx_scale/generic/yv12extend.c
index 5a427356b846eaabb9ac3bb4221faa35ec919dc4..d733bd49d87b1b83e79d4a48dda1489d95c14832 100644
--- a/vpx_scale/generic/yv12extend.c
+++ b/vpx_scale/generic/yv12extend.c
@@ -8,7 +8,7 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
-
+#include <assert.h>
 #include "vpx_scale/yv12config.h"
 #include "vpx_mem/vpx_mem.h"
 #include "vpx_scale/vpx_scale.h"
@@ -216,6 +216,9 @@ vp8_yv12_copy_frame_c(YV12_BUFFER_CONFIG *src_ybc,
   int row;
   unsigned char *source, *dest;
 
+  assert(src_ybc->y_width == dst_ybc->y_width);
+  assert(src_ybc->y_height == dst_ybc->y_height);
+
   source = src_ybc->y_buffer;
   dest = dst_ybc->y_buffer;
 
diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h
index 23be8f3dd78a8d6f017a82bdaa2ee9121bcf74be..45e57f40140e1474669289b612a1699708a2106e 100644
--- a/vpx_scale/yv12config.h
+++ b/vpx_scale/yv12config.h
@@ -55,6 +55,7 @@ extern "C" {
     uint8_t *v_buffer;
 
     uint8_t *buffer_alloc;
+    int buffer_alloc_sz;
     int border;
     int frame_size;
     YUV_TYPE clrtype;
@@ -65,6 +66,8 @@ extern "C" {
 
   int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
                                   int width, int height, int border);
+  int vp8_yv12_realloc_frame_buffer(YV12_BUFFER_CONFIG *ybf,
+                                    int width, int height, int border);
   int vp8_yv12_de_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf);
 
 #ifdef __cplusplus