shithub: libvpx

Download patch

ref: 08706a3ea726fe0c5d3b2c478d755818fff64291
parent: 7fb0f868634d628394a41c2195ed8ae387302c84
author: Yunqing Wang <yunqingwang@google.com>
date: Tue Dec 14 12:39:25 EST 2010

Fix a bug in motion search code(2)

This fix added MV range checks for NEWMV mode as suggested by Jim.
To reduce unnecessary MV range checks, I tried Yaowu's suggestion.
Update UMV borders in NEWMV mode to also cover MV range check.
Also, in this way, every MV that is valid gets checked in diamond
search function.

Change-Id: I95a89ce0daf6f178c454448f13d4249f19b30f3a

--- a/vp8/encoder/mcomp.c
+++ b/vp8/encoder/mcomp.c
@@ -941,18 +941,8 @@
     unsigned char *check_here;
     int thissad;
 
-    int search_range = 128>>search_param;
-
     *num00 = 0;
 
-    // Trap uncodable vectors
-    if (((abs(ref_mv->col - center_mv->col) + (search_range<<4)) > MAX_POSSIBLE_MV) || ((abs(ref_mv->row - center_mv->row) + (search_range<<4)) > MAX_POSSIBLE_MV))
-    {
-        best_mv->row = ref_row;
-        best_mv->col = ref_col;
-        return INT_MAX;
-    }
-
     // Work out the start point for the search
     in_what = (unsigned char *)(*(d->base_pre) + d->pre + (ref_row * (d->pre_stride)) + ref_col);
     best_address = in_what;
@@ -1067,18 +1057,8 @@
     unsigned char *check_here;
     unsigned int thissad;
 
-    int search_range = 128>>search_param;
-
     *num00 = 0;
 
-    // Trap uncodable vectors
-    if (((abs(ref_mv->col - center_mv->col) + (search_range<<4)) > MAX_POSSIBLE_MV) || ((abs(ref_mv->row - center_mv->row) + (search_range<<4)) > MAX_POSSIBLE_MV))
-    {
-        best_mv->row = ref_row;
-        best_mv->col = ref_col;
-        return INT_MAX;
-    }
-
     // Work out the start point for the search
     in_what = (unsigned char *)(*(d->base_pre) + d->pre + (ref_row * (d->pre_stride)) + ref_col);
     best_address = in_what;
@@ -1214,25 +1194,11 @@
     int ref_row = ref_mv->row >> 3;
     int ref_col = ref_mv->col >> 3;
 
-    int row_min, row_max, col_min, col_max;
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
 
-    int drow = abs(ref_mv->row - center_mv->row);
-    int dcol = abs(ref_mv->col - center_mv->col);
-
-    // reduce search distance and make sure MV obtained is in range.
-    if (((dcol + (distance<<3)) > MAX_POSSIBLE_MV) || (( drow + (distance<<3)) > MAX_POSSIBLE_MV))
-    {
-        if(dcol > drow)
-            distance = (MAX_POSSIBLE_MV - dcol)>>3;
-        else
-            distance = (MAX_POSSIBLE_MV - drow)>>3;
-    }
-
-    row_min = ref_row - distance;
-    row_max = ref_row + distance;
-    col_min = ref_col - distance;
-    col_max = ref_col + distance;
-
     // Work out the mid point for the search
     in_what = *(d->base_pre) + d->pre;
     bestaddress = in_what + (ref_row * d->pre_stride) + ref_col;
@@ -1318,25 +1284,13 @@
     int ref_row = ref_mv->row >> 3;
     int ref_col = ref_mv->col >> 3;
 
-    int row_min, row_max, col_min, col_max;
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
+
     unsigned int sad_array[3];
-    int drow = abs(ref_mv->row - center_mv->row);
-    int dcol = abs(ref_mv->col - center_mv->col);
 
-    // reduce search distance and make sure MV obtained is in range.
-    if (((dcol + (distance<<3)) > MAX_POSSIBLE_MV) || (( drow + (distance<<3)) > MAX_POSSIBLE_MV))
-    {
-        if(dcol > drow)
-            distance = (MAX_POSSIBLE_MV - dcol)>>3;
-        else
-            distance = (MAX_POSSIBLE_MV - drow)>>3;
-    }
-
-    row_min = ref_row - distance;
-    row_max = ref_row + distance;
-    col_min = ref_col - distance;
-    col_max = ref_col + distance;
-
     // Work out the mid point for the search
     in_what = *(d->base_pre) + d->pre;
     bestaddress = in_what + (ref_row * d->pre_stride) + ref_col;
@@ -1455,25 +1409,13 @@
     int ref_row = ref_mv->row >> 3;
     int ref_col = ref_mv->col >> 3;
 
-    int row_min, row_max, col_min, col_max;
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
+
     unsigned short sad_array8[8];
     unsigned int sad_array[3];
-    int drow = abs(ref_mv->row - center_mv->row);
-    int dcol = abs(ref_mv->col - center_mv->col);
-
-    // reduce search distance and make sure MV obtained is in range.
-    if (((dcol + (distance<<3)) > MAX_POSSIBLE_MV) || (( drow + (distance<<3)) > MAX_POSSIBLE_MV))
-    {
-        if(dcol > drow)
-            distance = (MAX_POSSIBLE_MV - dcol)>>3;
-        else
-            distance = (MAX_POSSIBLE_MV - drow)>>3;
-    }
-
-    row_min = ref_row - distance;
-    row_max = ref_row + distance;
-    col_min = ref_col - distance;
-    col_max = ref_col + distance;
 
     // Work out the mid point for the search
     in_what = *(d->base_pre) + d->pre;
--- a/vp8/encoder/rdopt.c
+++ b/vp8/encoder/rdopt.c
@@ -1886,11 +1886,11 @@
             /* adjust mvp to make sure it is within MV range */
             if(mvp.row > best_ref_mv.row + MAX_POSSIBLE_MV)
                 mvp.row = best_ref_mv.row + MAX_POSSIBLE_MV;
-            if(mvp.row < best_ref_mv.row - MAX_POSSIBLE_MV)
+            else if(mvp.row < best_ref_mv.row - MAX_POSSIBLE_MV)
                 mvp.row = best_ref_mv.row - MAX_POSSIBLE_MV;
             if(mvp.col > best_ref_mv.col + MAX_POSSIBLE_MV)
                 mvp.col = best_ref_mv.col + MAX_POSSIBLE_MV;
-            if(mvp.col < best_ref_mv.col - MAX_POSSIBLE_MV)
+            else if(mvp.col < best_ref_mv.col - MAX_POSSIBLE_MV)
                 mvp.col = best_ref_mv.col - MAX_POSSIBLE_MV;
         }
 
@@ -2081,6 +2081,26 @@
                 int further_steps;
                 int n;
 
+                int col_min = (best_ref_mv.col - MAX_POSSIBLE_MV) >>3;
+                int col_max = (best_ref_mv.col + MAX_POSSIBLE_MV) >>3;
+                int row_min = (best_ref_mv.row - MAX_POSSIBLE_MV) >>3;
+                int row_max = (best_ref_mv.row + MAX_POSSIBLE_MV) >>3;
+
+                int tmp_col_min = x->mv_col_min;
+                int tmp_col_max = x->mv_col_max;
+                int tmp_row_min = x->mv_row_min;
+                int tmp_row_max = x->mv_row_max;
+
+                // Get intersection of UMV window and valid MV window to reduce # of checks in diamond search.
+                if (x->mv_col_min < col_min )
+                    x->mv_col_min = col_min;
+                if (x->mv_col_max > col_max )
+                    x->mv_col_max = col_max;
+                if (x->mv_row_min < row_min )
+                    x->mv_row_min = row_min;
+                if (x->mv_row_max > row_max )
+                    x->mv_row_max = row_max;
+
                 //adjust search range according to sr from mv prediction
                 if(sr > step_param)
                     step_param = sr;
@@ -2192,6 +2212,11 @@
                         d->bmi.mv.as_mv.col = mode_mv[NEWMV].col;
                     }
                 }
+
+                x->mv_col_min = tmp_col_min;
+                x->mv_col_max = tmp_col_max;
+                x->mv_row_min = tmp_row_min;
+                x->mv_row_max = tmp_row_max;
 
                 if (bestsme < INT_MAX)
                     // cpi->find_fractional_mv_step(x,b,d,&d->bmi.mv.as_mv,&best_ref_mv,x->errorperbit/2,cpi->fn_ptr.svf,cpi->fn_ptr.vf,x->mvcost);  // normal mvc=11