shithub: libvpx

Download patch

ref: 12d946df893a5abaf762d776603de4a3f0bd9949
parent: 53c9ebe609faee5e0db5f3e15ebdaa4a04a3eb33
author: Adrian Grange <agrange@google.com>
date: Thu Mar 19 10:41:43 EDT 2015

Restore first ref frame pointer to the correct value

The joint_motion_search function alternates prediction
between two reference frames. In order to reuse existing
code, a pointer to the appropriate reference frame is
written into xd->plane[0].pre[0], that the motion
estimation code assumes points to the reference frame.

If this first reference frame was scaled then the
pointer was incorrectly being reset to point to the
unscaled reference frame rather than the scaled
version.

Change-Id: I76f73a8d8f4f15c1f3a5e7e08a35140cdb7886ab

--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -1544,8 +1544,8 @@
   const int ph = 4 * num_4x4_blocks_high_lookup[bsize];
   MACROBLOCKD *xd = &x->e_mbd;
   MB_MODE_INFO *mbmi = &xd->mi[0].src_mi->mbmi;
-  const int refs[2] = { mbmi->ref_frame[0],
-                        mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1] };
+  const int refs[2] = {mbmi->ref_frame[0],
+                       mbmi->ref_frame[1] < 0 ? 0 : mbmi->ref_frame[1]};
   int_mv ref_mv[2];
   int ite, ref;
   // Prediction buffer from second frame.
@@ -1559,7 +1559,6 @@
 
   // Do joint motion search in compound mode to get more accurate mv.
   struct buf_2d backup_yv12[2][MAX_MB_PLANE];
-  struct buf_2d scaled_first_yv12 = xd->plane[0].pre[0];
   int last_besterr[2] = {INT_MAX, INT_MAX};
   const YV12_BUFFER_CONFIG *const scaled_ref_frame[2] = {
     vp9_get_scaled_ref_frame(cpi, mbmi->ref_frame[0]),
@@ -1592,8 +1591,8 @@
     frame_mv[refs[ref]].as_int = single_newmv[refs[ref]].as_int;
   }
 
-  // Allow joint search multiple times iteratively for each ref frame
-  // and break out the search loop if it couldn't find better mv.
+  // Allow joint search multiple times iteratively for each reference frame
+  // and break out of the search loop if it couldn't find a better mv.
   for (ite = 0; ite < 4; ite++) {
     struct buf_2d ref_yv12[2];
     int bestsme = INT_MAX;
@@ -1605,13 +1604,15 @@
     int tmp_col_max = x->mv_col_max;
     int tmp_row_min = x->mv_row_min;
     int tmp_row_max = x->mv_row_max;
-    int id = ite % 2;
+    int id = ite % 2;  // Even iterations search in the first reference frame,
+                       // odd iterations search in the second. The predictor
+                       // found for the 'other' reference frame is factored in.
 
     // Initialized here because of compiler problem in Visual Studio.
     ref_yv12[0] = xd->plane[0].pre[0];
     ref_yv12[1] = xd->plane[0].pre[1];
 
-    // Get pred block from second frame.
+    // Get the prediction block from the 'other' reference frame.
 #if CONFIG_VP9_HIGHBITDEPTH
     if (xd->cur_buf->flags & YV12_FLAG_HIGHBITDEPTH) {
       vp9_highbd_build_inter_predictor(ref_yv12[!id].buf,
@@ -1644,18 +1645,18 @@
                               mi_col * MI_SIZE, mi_row * MI_SIZE);
 #endif  // CONFIG_VP9_HIGHBITDEPTH
 
-    // Compound motion search on first ref frame.
+    // Do compound motion search on the current reference frame.
     if (id)
       xd->plane[0].pre[0] = ref_yv12[id];
     vp9_set_mv_search_range(x, &ref_mv[id].as_mv);
 
-    // Use mv result from single mode as mvp.
+    // Use the mv result from the single mode as mv predictor.
     tmp_mv = frame_mv[refs[id]].as_mv;
 
     tmp_mv.col >>= 3;
     tmp_mv.row >>= 3;
 
-    // Small-range full-pixel motion search
+    // Small-range full-pixel motion search.
     bestsme = vp9_refining_search_8p_c(x, &tmp_mv, sadpb,
                                        search_range,
                                        &cpi->fn_ptr[bsize],
@@ -1685,8 +1686,9 @@
           pw, ph);
     }
 
+    // Restore the pointer to the first (possibly scaled) prediction buffer.
     if (id)
-      xd->plane[0].pre[0] = scaled_first_yv12;
+      xd->plane[0].pre[0] = ref_yv12[0];
 
     if (bestsme < last_besterr[id]) {
       frame_mv[refs[id]].as_mv = tmp_mv;
@@ -1700,7 +1702,7 @@
 
   for (ref = 0; ref < 2; ++ref) {
     if (scaled_ref_frame[ref]) {
-      // restore the predictor
+      // Restore the prediction frame pointers to their unscaled versions.
       int i;
       for (i = 0; i < MAX_MB_PLANE; i++)
         xd->plane[i].pre[ref] = backup_yv12[ref][i];