diff --git a/vp8/common/alloccommon.c b/vp8/common/alloccommon.c
index edef3609416eb0eb7ccd4f28d264ef8ee2524ebc..a1944ebdaa51361d944493608a2080829b86d0f7 100644
--- a/vp8/common/alloccommon.c
+++ b/vp8/common/alloccommon.c
@@ -65,9 +65,9 @@ int vp8_alloc_frame_buffers(VP8_COMMON *oci, int width, int height)
 
     for (i = 0; i < NUM_YV12_BUFFERS; i++)
     {
-      oci->fb_idx_ref_cnt[0] = 0;
-
-      if (vp8_yv12_alloc_frame_buffer(&oci->yv12_fb[i],  width, height, VP8BORDERINPIXELS) < 0)
+        oci->fb_idx_ref_cnt[0] = 0;
+        oci->yv12_fb[i].flags = 0;
+        if (vp8_yv12_alloc_frame_buffer(&oci->yv12_fb[i], width, height, VP8BORDERINPIXELS) < 0)
         {
             vp8_de_alloc_frame_buffers(oci);
             return 1;
diff --git a/vp8/encoder/onyx_if.c b/vp8/encoder/onyx_if.c
index 92e0cbb193017e696ddbb72cf6911b9676eef43b..46191f065d4ebcc816874971445b6b650ec7cf05 100644
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -2755,13 +2755,10 @@ static void set_quantizer(VP8_COMP *cpi, int Q)
 
 }
 
-static void update_alt_ref_frame_and_stats(VP8_COMP *cpi)
+static void update_alt_ref_frame_stats(VP8_COMP *cpi)
 {
     VP8_COMMON *cm = &cpi->common;
 
-    // Update the golden frame buffer
-    vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->alt_fb_idx]);
-
     // Select an interval before next GF or altref
     if (!cpi->auto_gold)
         cpi->frames_till_gf_update_due = cpi->goldfreq;
@@ -2794,19 +2791,13 @@ static void update_alt_ref_frame_and_stats(VP8_COMP *cpi)
 
 
 }
-static void update_golden_frame_and_stats(VP8_COMP *cpi)
+static void update_golden_frame_stats(VP8_COMP *cpi)
 {
     VP8_COMMON *cm = &cpi->common;
 
-    // Update the Golden frame reconstruction buffer if signalled and the GF usage counts.
+    // Update the Golden frame usage counts.
     if (cm->refresh_golden_frame)
     {
-        if (cm->frame_type != KEY_FRAME)
-        {
-            // Update the golden frame buffer
-            vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->gld_fb_idx]);
-        }
-
         // Select an interval before next GF
         if (!cpi->auto_gold)
             cpi->frames_till_gf_update_due = cpi->goldfreq;
@@ -3186,6 +3177,85 @@ static BOOL recode_loop_test( VP8_COMP *cpi,
     return force_recode;
 }
 
+void update_reference_frames(VP8_COMMON *cm)
+{
+    YV12_BUFFER_CONFIG *yv12_fb = cm->yv12_fb;
+
+    // At this point the new frame has been encoded.
+    // If any buffer copy / swapping is signaled it should be done here.
+
+    if (cm->frame_type == KEY_FRAME)
+    {
+        yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FLAG | VP8_ALT_FLAG ;
+
+        yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG;
+        yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG;
+
+        cm->alt_fb_idx = cm->gld_fb_idx = cm->new_fb_idx;
+    }
+    else    /* For non key frames */
+    {
+        if (cm->refresh_alt_ref_frame)
+        {
+            assert(!cm->copy_buffer_to_arf);
+
+            cm->yv12_fb[cm->new_fb_idx].flags |= VP8_ALT_FLAG;
+            cm->yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG;
+            cm->alt_fb_idx = cm->new_fb_idx;
+        }
+        else if (cm->copy_buffer_to_arf)
+        {
+            assert(!(cm->copy_buffer_to_arf & ~0x3));
+
+            if (cm->copy_buffer_to_arf == 1)
+            {
+                yv12_fb[cm->lst_fb_idx].flags |= VP8_ALT_FLAG;
+                yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG;
+                cm->alt_fb_idx = cm->lst_fb_idx;
+            }
+            else /* if (cm->copy_buffer_to_arf == 2) */
+            {
+                yv12_fb[cm->gld_fb_idx].flags |= VP8_ALT_FLAG;
+                yv12_fb[cm->alt_fb_idx].flags &= ~VP8_ALT_FLAG;
+                cm->alt_fb_idx = cm->gld_fb_idx;
+            }
+        }
+
+        if (cm->refresh_golden_frame)
+        {
+            assert(!cm->copy_buffer_to_gf);
+
+            cm->yv12_fb[cm->new_fb_idx].flags |= VP8_GOLD_FLAG;
+            cm->yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG;
+            cm->gld_fb_idx = cm->new_fb_idx;
+        }
+        else if (cm->copy_buffer_to_gf)
+        {
+            assert(!(cm->copy_buffer_to_arf & ~0x3));
+
+            if (cm->copy_buffer_to_gf == 1)
+            {
+                yv12_fb[cm->lst_fb_idx].flags |= VP8_GOLD_FLAG;
+                yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG;
+                cm->gld_fb_idx = cm->lst_fb_idx;
+            }
+            else /* if (cm->copy_buffer_to_gf == 2) */
+            {
+                yv12_fb[cm->alt_fb_idx].flags |= VP8_GOLD_FLAG;
+                yv12_fb[cm->gld_fb_idx].flags &= ~VP8_GOLD_FLAG;
+                cm->gld_fb_idx = cm->alt_fb_idx;
+            }
+        }
+    }
+
+    if (cm->refresh_last_frame)
+    {
+        cm->yv12_fb[cm->new_fb_idx].flags |= VP8_LAST_FLAG;
+        cm->yv12_fb[cm->lst_fb_idx].flags &= ~VP8_LAST_FLAG;
+        cm->lst_fb_idx = cm->new_fb_idx;
+    }
+}
+
 void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm)
 {
     if (cm->no_lpf)
@@ -3224,50 +3294,6 @@ void loopfilter_frame(VP8_COMP *cpi, VP8_COMMON *cm)
 
     vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
 
-    {
-        YV12_BUFFER_CONFIG *lst_yv12 = &cm->yv12_fb[cm->lst_fb_idx];
-        YV12_BUFFER_CONFIG *new_yv12 = &cm->yv12_fb[cm->new_fb_idx];
-        YV12_BUFFER_CONFIG *gld_yv12 = &cm->yv12_fb[cm->gld_fb_idx];
-        YV12_BUFFER_CONFIG *alt_yv12 = &cm->yv12_fb[cm->alt_fb_idx];
-        // At this point the new frame has been encoded.
-        // If any buffer copy / swapping is signaled it should be done here.
-        if (cm->frame_type == KEY_FRAME)
-        {
-            vp8_yv12_copy_frame_ptr(cm->frame_to_show, gld_yv12);
-            vp8_yv12_copy_frame_ptr(cm->frame_to_show, alt_yv12);
-        }
-        else    // For non key frames
-        {
-            // Code to copy between reference buffers
-            if (cm->copy_buffer_to_arf)
-            {
-                if (cm->copy_buffer_to_arf == 1)
-                {
-                    if (cm->refresh_last_frame)
-                        // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set.
-                        vp8_yv12_copy_frame_ptr(new_yv12, alt_yv12);
-                    else
-                        vp8_yv12_copy_frame_ptr(lst_yv12, alt_yv12);
-                }
-                else if (cm->copy_buffer_to_arf == 2)
-                    vp8_yv12_copy_frame_ptr(gld_yv12, alt_yv12);
-            }
-
-            if (cm->copy_buffer_to_gf)
-            {
-                if (cm->copy_buffer_to_gf == 1)
-                {
-                    if (cm->refresh_last_frame)
-                        // We copy new_frame here because last and new buffers will already have been swapped if cm->refresh_last_frame is set.
-                        vp8_yv12_copy_frame_ptr(new_yv12, gld_yv12);
-                    else
-                        vp8_yv12_copy_frame_ptr(lst_yv12, gld_yv12);
-                }
-                else if (cm->copy_buffer_to_gf == 2)
-                    vp8_yv12_copy_frame_ptr(alt_yv12, gld_yv12);
-            }
-        }
-    }
 }
 
 static void encode_frame_to_data_rate
@@ -4169,21 +4195,15 @@ static void encode_frame_to_data_rate
     }
 #endif
 
-    // For inter frames the current default behaviour is that when cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
-    // This is purely an encoder descision at present.
+    // For inter frames the current default behavior is that when
+    // cm->refresh_golden_frame is set we copy the old GF over to the ARF buffer
+    // This is purely an encoder decision at present.
     if (!cpi->oxcf.error_resilient_mode && cm->refresh_golden_frame)
         cm->copy_buffer_to_arf  = 2;
     else
         cm->copy_buffer_to_arf  = 0;
 
-    if (cm->refresh_last_frame)
-    {
-        vp8_swap_yv12_buffer(&cm->yv12_fb[cm->lst_fb_idx], &cm->yv12_fb[cm->new_fb_idx]);
-        cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
-    }
-    else
-        cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
-
+    cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
 
 #if CONFIG_MULTITHREAD
     if (cpi->b_multi_threaded)
@@ -4196,6 +4216,8 @@ static void encode_frame_to_data_rate
         loopfilter_frame(cpi, cm);
     }
 
+    update_reference_frames(cm);
+
     if (cpi->oxcf.error_resilient_mode == 1)
     {
         cm->refresh_entropy_probs = 0;
@@ -4220,7 +4242,7 @@ static void encode_frame_to_data_rate
 
     /* Move storing frame_type out of the above loop since it is also
      * needed in motion search besides loopfilter */
-      cm->last_frame_type = cm->frame_type;
+    cm->last_frame_type = cm->frame_type;
 
     // Update rate control heuristics
     cpi->total_byte_count += (*size);
@@ -4470,26 +4492,14 @@ static void encode_frame_to_data_rate
         cpi->ref_frame_flags &= ~VP8_ALT_FLAG;
 
 
-    if (cpi->oxcf.error_resilient_mode)
-    {
-        if (cm->frame_type != KEY_FRAME)
-        {
-            // Is this an alternate reference update
-            if (cm->refresh_alt_ref_frame)
-                vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->alt_fb_idx]);
-
-            if (cm->refresh_golden_frame)
-                vp8_yv12_copy_frame_ptr(cm->frame_to_show, &cm->yv12_fb[cm->gld_fb_idx]);
-        }
-    }
-    else
+    if (!cpi->oxcf.error_resilient_mode)
     {
         if (cpi->oxcf.play_alternate && cm->refresh_alt_ref_frame && (cm->frame_type != KEY_FRAME))
-            // Update the alternate reference frame and stats as appropriate.
-            update_alt_ref_frame_and_stats(cpi);
+            // Update the alternate reference frame stats as appropriate.
+            update_alt_ref_frame_stats(cpi);
         else
-            // Update the Golden frame and golden frame and stats as appropriate.
-            update_golden_frame_and_stats(cpi);
+            // Update the Golden frame stats as appropriate.
+            update_golden_frame_stats(cpi);
     }
 
     if (cm->frame_type == KEY_FRAME)
@@ -4833,7 +4843,20 @@ int vp8_get_compressed_data(VP8_PTR ptr, unsigned int *frame_flags, unsigned lon
     }
 
 #endif
+    /* find a free buffer for the new frame */
+    {
+        int i = 0;
+        for(; i < NUM_YV12_BUFFERS; i++)
+        {
+            if(!cm->yv12_fb[i].flags)
+            {
+                cm->new_fb_idx = i;
+                break;
+            }
+        }
 
+        assert(i < NUM_YV12_BUFFERS );
+    }
 #if !(CONFIG_REALTIME_ONLY)
 
     if (cpi->pass == 1)
diff --git a/vpx_scale/yv12config.h b/vpx_scale/yv12config.h
index e10db3468061cfb8efc447bb09407ff43f96c3c8..3cc4746f77472dbc90d9f29d899cc967be6701b6 100644
--- a/vpx_scale/yv12config.h
+++ b/vpx_scale/yv12config.h
@@ -59,6 +59,7 @@ extern "C"
         YUV_TYPE clrtype;
 
         int corrupted;
+        int flags;
     } YV12_BUFFER_CONFIG;
 
     int vp8_yv12_alloc_frame_buffer(YV12_BUFFER_CONFIG *ybf, int width, int height, int border);