Fix a bug in motion search code(2)
authorYunqing Wang <yunqingwang@google.com>
Tue, 14 Dec 2010 22:39:25 +0000 (17:39 -0500)
committerYunqing Wang <yunqingwang@google.com>
Tue, 14 Dec 2010 22:39:25 +0000 (17:39 -0500)
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

vp8/encoder/mcomp.c
vp8/encoder/rdopt.c

index c5209ff..9b91739 100644 (file)
@@ -941,18 +941,8 @@ int vp8_diamond_search_sad
     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 @@ int vp8_diamond_search_sadx4
     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,24 +1194,10 @@ int vp8_full_search_sad(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int erro
     int ref_row = ref_mv->row >> 3;
     int ref_col = ref_mv->col >> 3;
 
-    int row_min, row_max, col_min, col_max;
-
-    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;
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
 
     // Work out the mid point for the search
     in_what = *(d->base_pre) + d->pre;
@@ -1318,24 +1284,12 @@ int vp8_full_search_sadx3(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int er
     int ref_row = ref_mv->row >> 3;
     int ref_col = ref_mv->col >> 3;
 
-    int row_min, row_max, col_min, col_max;
-    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;
-    }
+    int row_min = ref_row - distance;
+    int row_max = ref_row + distance;
+    int col_min = ref_col - distance;
+    int col_max = ref_col + distance;
 
-    row_min = ref_row - distance;
-    row_max = ref_row + distance;
-    col_min = ref_col - distance;
-    col_max = ref_col + distance;
+    unsigned int sad_array[3];
 
     // Work out the mid point for the search
     in_what = *(d->base_pre) + d->pre;
@@ -1455,25 +1409,13 @@ int vp8_full_search_sadx8(MACROBLOCK *x, BLOCK *b, BLOCKD *d, MV *ref_mv, int er
     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;
index aa17b31..91e8a54 100644 (file)
@@ -1886,11 +1886,11 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
             /* 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 vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
                 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;
@@ -2193,6 +2213,11 @@ int vp8_rd_pick_inter_mode(VP8_COMP *cpi, MACROBLOCK *x, int recon_yoffset, int
                     }
                 }
 
+                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
                     cpi->find_fractional_mv_step(x, b, d, &d->bmi.mv.as_mv, &best_ref_mv, x->errorperbit / 4, &cpi->fn_ptr[BLOCK_16X16], x->mvcost);