shithub: libvpx

Download patch

ref: e570b0406db127ea53047a8e76d22174e5ac0638
parent: bdd60a7be779400e597cae001448a44d21c98f2b
author: Attila Nagy <attilanagy@google.com>
date: Tue Nov 29 08:48:02 EST 2011

Reduce mem copies in encoder loopfilter level picking

Do the test filtering in the existing backup frame buffer instead of
the original. Copy the original data into extra buffer before doing
the  filtering. This way there is no need to restore the original
unfiltered  frame at the end of level picking process.

This came up in some discussions with Johann. Thanks!

Change-Id: I495f4301d983854673276c34ec0ddf9a9d622122

--- a/vp8/encoder/onyx_if.c
+++ b/vp8/encoder/onyx_if.c
@@ -355,7 +355,7 @@
 
     vp8_de_alloc_frame_buffers(&cpi->common);
 
-    vp8_yv12_de_alloc_frame_buffer(&cpi->last_frame_uf);
+    vp8_yv12_de_alloc_frame_buffer(&cpi->pick_lf_lvl_frame);
     vp8_yv12_de_alloc_frame_buffer(&cpi->scaled_source);
 #if VP8_TEMPORAL_ALT_REF
     vp8_yv12_de_alloc_frame_buffer(&cpi->alt_ref_buffer);
@@ -1365,7 +1365,7 @@
         height += 16 - (height & 0xf);
 
 
-    if (vp8_yv12_alloc_frame_buffer(&cpi->last_frame_uf,
+    if (vp8_yv12_alloc_frame_buffer(&cpi->pick_lf_lvl_frame,
                                     width, height, VP8BORDERINPIXELS))
         vpx_internal_error(&cpi->common.error, VPX_CODEC_MEM_ERROR,
                            "Failed to allocate last frame buffer");
--- a/vp8/encoder/onyx_int.h
+++ b/vp8/encoder/onyx_int.h
@@ -336,7 +336,7 @@
     int gold_is_alt;  // don't do both alt and gold search ( just do gold).
 
     //int refresh_alt_ref_frame;
-    YV12_BUFFER_CONFIG last_frame_uf;
+    YV12_BUFFER_CONFIG pick_lf_lvl_frame;
 
     TOKENEXTRA *tok;
     unsigned int tok_count;
--- a/vp8/encoder/picklpf.c
+++ b/vp8/encoder/picklpf.c
@@ -152,9 +152,10 @@
     int max_filter_level = get_max_filter_level(cpi, cm->base_qindex);
     int filt_val;
     int best_filt_val = cm->filter_level;
+    YV12_BUFFER_CONFIG * saved_frame = cm->frame_to_show;
 
-    //  Make a copy of the unfiltered / processed recon buffer
-    vp8_yv12_copy_partial_frame_ptr(cm->frame_to_show, &cpi->last_frame_uf);
+    /* Replace unfiltered frame buffer with a new one */
+    cm->frame_to_show = &cpi->pick_lf_lvl_frame;
 
     if (cm->frame_type == KEY_FRAME)
         cm->sharpness_level = 0;
@@ -177,13 +178,14 @@
     best_filt_val = filt_val;
 
     // Get the err using the previous frame's filter value.
+
+    /* Copy the unfiltered / processed recon buffer to the new buffer */
+    vp8_yv12_copy_partial_frame_ptr(saved_frame, cm->frame_to_show);
     vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);
 
-    best_err = calc_partial_ssl_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+    best_err = calc_partial_ssl_err(sd, cm->frame_to_show,
+                                    IF_RTCD(&cpi->rtcd.variance));
 
-    //  Re-instate the unfiltered frame
-    vp8_yv12_copy_partial_frame_ptr(&cpi->last_frame_uf, cm->frame_to_show);
-
     filt_val -= (1 + ((filt_val > 10) ? 1 : 0));
 
     // Search lower filter levels
@@ -190,14 +192,13 @@
     while (filt_val >= min_filter_level)
     {
         // Apply the loop filter
+        vp8_yv12_copy_partial_frame_ptr(saved_frame, cm->frame_to_show);
         vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);
 
         // Get the err for filtered frame
-        filt_err = calc_partial_ssl_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+        filt_err = calc_partial_ssl_err(sd, cm->frame_to_show,
+                                        IF_RTCD(&cpi->rtcd.variance));
 
-        //  Re-instate the unfiltered frame
-        vp8_yv12_copy_partial_frame_ptr(&cpi->last_frame_uf, cm->frame_to_show);
-
         // Update the best case record or exit loop.
         if (filt_err < best_err)
         {
@@ -222,14 +223,14 @@
         while (filt_val < max_filter_level)
         {
             // Apply the loop filter
+            vp8_yv12_copy_partial_frame_ptr(saved_frame, cm->frame_to_show);
+
             vp8_loop_filter_partial_frame(cm, &cpi->mb.e_mbd, filt_val);
 
             // Get the err for filtered frame
-            filt_err = calc_partial_ssl_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+            filt_err = calc_partial_ssl_err(sd, cm->frame_to_show,
+                                            IF_RTCD(&cpi->rtcd.variance));
 
-            //  Re-instate the unfiltered frame
-            vp8_yv12_copy_partial_frame_ptr(&cpi->last_frame_uf, cm->frame_to_show);
-
             // Update the best case record or exit loop.
             if (filt_err < best_err)
             {
@@ -253,6 +254,9 @@
 
     if (cm->filter_level > max_filter_level)
         cm->filter_level = max_filter_level;
+
+    /* restore unfiltered frame pointer */
+    cm->frame_to_show = saved_frame;
 }
 
 // Stub function for now Alt LF not used
@@ -283,11 +287,13 @@
     int filt_best;
     int filt_direction = 0;
 
-    int Bias = 0;                       // Bias against raising loop filter and in favour of lowering it
+    int Bias = 0;                       // Bias against raising loop filter and in favor of lowering it
 
-    //  Make a copy of the unfiltered / processed recon buffer
-    vp8_yv12_copy_y_ptr(cm->frame_to_show, &cpi->last_frame_uf);
+    YV12_BUFFER_CONFIG * saved_frame = cm->frame_to_show;
 
+    /* Replace unfiltered frame buffer with a new one */
+    cm->frame_to_show = &cpi->pick_lf_lvl_frame;
+
     if (cm->frame_type == KEY_FRAME)
         cm->sharpness_level = 0;
     else
@@ -305,15 +311,17 @@
     filter_step = (filt_mid < 16) ? 4 : filt_mid / 4;
 
     // Get baseline error score
+
+    /* Copy the unfiltered / processed recon buffer to the new buffer */
+    vp8_yv12_copy_y_ptr(saved_frame, cm->frame_to_show);
+
     vp8cx_set_alt_lf_level(cpi, filt_mid);
     vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_mid);
 
-    best_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+    best_err = vp8_calc_ss_err(sd, cm->frame_to_show,
+                               IF_RTCD(&cpi->rtcd.variance));
     filt_best = filt_mid;
 
-    //  Re-instate the unfiltered frame
-    vp8_yv12_copy_y_ptr(&cpi->last_frame_uf, cm->frame_to_show);
-
     while (filter_step > 0)
     {
         Bias = (best_err >> (15 - (filt_mid / 8))) * filter_step; //PGW change 12/12/06 for small images
@@ -328,14 +336,13 @@
         if ((filt_direction <= 0) && (filt_low != filt_mid))
         {
             // Get Low filter error score
+            vp8_yv12_copy_y_ptr(saved_frame, cm->frame_to_show);
             vp8cx_set_alt_lf_level(cpi, filt_low);
             vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_low);
 
-            filt_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+            filt_err = vp8_calc_ss_err(sd, cm->frame_to_show,
+                                       IF_RTCD(&cpi->rtcd.variance));
 
-            //  Re-instate the unfiltered frame
-            vp8_yv12_copy_y_ptr(&cpi->last_frame_uf, cm->frame_to_show);
-
             // If value is close to the best so far then bias towards a lower loop filter value.
             if ((filt_err - Bias) < best_err)
             {
@@ -350,14 +357,13 @@
         // Now look at filt_high
         if ((filt_direction >= 0) && (filt_high != filt_mid))
         {
+            vp8_yv12_copy_y_ptr(saved_frame, cm->frame_to_show);
             vp8cx_set_alt_lf_level(cpi, filt_high);
             vp8_loop_filter_frame_yonly(cm, &cpi->mb.e_mbd, filt_high);
 
-            filt_err = vp8_calc_ss_err(sd, cm->frame_to_show, IF_RTCD(&cpi->rtcd.variance));
+            filt_err = vp8_calc_ss_err(sd, cm->frame_to_show,
+                                       IF_RTCD(&cpi->rtcd.variance));
 
-            //  Re-instate the unfiltered frame
-            vp8_yv12_copy_y_ptr(&cpi->last_frame_uf, cm->frame_to_show);
-
             // Was it better than the previous best?
             if (filt_err < (best_err - Bias))
             {
@@ -380,4 +386,7 @@
     }
 
     cm->filter_level = filt_best;
+
+    /* restore unfiltered frame pointer */
+    cm->frame_to_show = saved_frame;
 }