shithub: libvpx

Download patch

ref: 43464e94edf3c6cb5792d5c2addb7e0ce1604d4c
parent: a9b465c5c9a35cb80e38d612bb63ba8d09c6855a
author: Attila Nagy <attilanagy@google.com>
date: Wed Apr 20 11:12:23 EDT 2011

Do not copy data between encoder reference buffers.

Golden and ALT reference buffers were refreshed by copying from
the new buffer. Replaced this by index manipulation.
Also moved all the reference frame updates to one function for
easier tracking.

Change-Id: Icd3e534e7e2c8c5567168d222e6a64a96aae24a1

--- a/vp8/common/alloccommon.c
+++ b/vp8/common/alloccommon.c
@@ -65,9 +65,9 @@
 
     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;
--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -2755,13 +2755,10 @@
 
 }
 
-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_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 @@
     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,52 +3294,8 @@
 
     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
 (
     VP8_COMP *cpi,
@@ -4169,22 +4195,16 @@
     }
 #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 @@
         loopfilter_frame(cpi, cm);
     }
 
+    update_reference_frames(cm);
+
     if (cpi->oxcf.error_resilient_mode == 1)
     {
         cm->refresh_entropy_probs = 0;
@@ -4220,7 +4242,7 @@
 
     /* 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 @@
         cpi->ref_frame_flags &= ~VP8_ALT_FLAG;
 
 
-    if (cpi->oxcf.error_resilient_mode)
+    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.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 @@
     }
 
 #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)
--- a/vpx_scale/yv12config.h
+++ b/vpx_scale/yv12config.h
@@ -59,6 +59,7 @@
         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);
--