shithub: libvpx

Download patch

ref: 2a5278bdbdc908ac994edb4dd2ba71c11eec6364
parent: 6fdd4d26de9bddb2b0acd82bde72b0b3ccfb7c5a
author: Jingning Han <jingning@google.com>
date: Wed Mar 6 07:02:15 EST 2013

Extend diff MV limit from +/-256 to +/-1024

Increase the motion search range by 4x. Change MV_CLASS tree of the
entropy coding to allow two additional mv classes to cover the
extended motion vector limit. The codec determines the effective
motion search range conditioned on the actual frame dimension.

It provides coding gains:

stdhd 0.39%
yt    0.56%
hd    0.47%

Major coding performance gains are packed in several sequences with
intense motion activities, e.g., ped_1080p gains 7% at high bit-rates,
and on average 3%.

TODO: Need to further tune the rate control and motion search units.

Change-Id: Ib842540a6796fbee5a797809433ef6a477c6d78d

--- a/vp9/common/vp9_entropymv.c
+++ b/vp9/common/vp9_entropymv.c
@@ -42,7 +42,9 @@
   -MV_CLASS_2, -MV_CLASS_3,
   10, 12,
   -MV_CLASS_4, -MV_CLASS_5,
+  14, 16,
   -MV_CLASS_6, -MV_CLASS_7,
+  -MV_CLASS_8, -MV_CLASS_9,
 };
 struct vp9_token_struct vp9_mv_class_encodings[MV_CLASSES];
 
@@ -63,9 +65,9 @@
   {
     { /* vert component */
       128,                                             /* sign */
-      {224, 144, 192, 168, 192, 176, 192},             /* class */
+      {224, 144, 192, 168, 192, 176, 192, 198, 198},   /* class */
       {216},                                           /* class0 */
-      {136, 140, 148, 160, 176, 192, 224},             /* bits */
+      {136, 140, 148, 160, 176, 192, 224, 234, 234},   /* bits */
       {{128, 128, 64}, {96, 112, 64}},                 /* class0_fp */
       {64, 96, 64},                                    /* fp */
       160,                                             /* class0_hp bit */
@@ -73,9 +75,9 @@
     },
     { /* hor component */
       128,                                             /* sign */
-      {216, 128, 176, 160, 176, 176, 192},             /* class */
+      {216, 128, 176, 160, 176, 176, 192, 198, 198},   /* class */
       {208},                                           /* class0 */
-      {136, 140, 148, 160, 176, 192, 224},             /* bits */
+      {136, 140, 148, 160, 176, 192, 224, 234, 234},   /* bits */
       {{128, 128, 64}, {96, 112, 64}},                 /* class0_fp */
       {64, 96, 64},                                    /* fp */
       160,                                             /* class0_hp bit */
@@ -103,6 +105,8 @@
   else if (z < CLASS0_SIZE * 256)  c = MV_CLASS_5;
   else if (z < CLASS0_SIZE * 512)  c = MV_CLASS_6;
   else if (z < CLASS0_SIZE * 1024) c = MV_CLASS_7;
+  else if (z < CLASS0_SIZE * 2048) c = MV_CLASS_8;
+  else if (z < CLASS0_SIZE * 4096) c = MV_CLASS_9;
   else assert(0);
   if (offset)
     *offset = z - mv_class_base(c);
--- a/vp9/common/vp9_entropymv.h
+++ b/vp9/common/vp9_entropymv.h
@@ -49,7 +49,7 @@
 extern struct vp9_token_struct vp9_mv_joint_encodings [MV_JOINTS];
 
 /* Symbols for coding magnitude class of nonzero components */
-#define MV_CLASSES     8
+#define MV_CLASSES     10
 typedef enum {
   MV_CLASS_0 = 0,      /* (0, 2]     integer pel */
   MV_CLASS_1 = 1,      /* (2, 4]     integer pel */
@@ -59,6 +59,8 @@
   MV_CLASS_5 = 5,      /* (32, 64]   integer pel */
   MV_CLASS_6 = 6,      /* (64, 128]  integer pel */
   MV_CLASS_7 = 7,      /* (128, 256] integer pel */
+  MV_CLASS_8 = 8,      /* (256, 512] integer pel */
+  MV_CLASS_9 = 9,      /* (512, 1024] integer pel */
 } MV_CLASS_TYPE;
 
 extern const vp9_tree_index vp9_mv_class_tree[2 * MV_CLASSES - 2];
--- a/vp9/encoder/vp9_encodeframe.c
+++ b/vp9/encoder/vp9_encodeframe.c
@@ -1241,8 +1241,9 @@
   MACROBLOCKD *const xd = &x->e_mbd;
   int totalrate;
 
-//   fprintf(stderr, "encode_frame_internal frame %d (%d)\n",
-//          cpi->common.current_video_frame, cpi->common.show_frame);
+//   fprintf(stderr, "encode_frame_internal frame %d (%d) type %d\n",
+//            cpi->common.current_video_frame, cpi->common.show_frame,
+//            cm->frame_type);
 
   // Compute a modified set of reference frame probabilities to use when
   // prediction fails. These are based on the current general estimates for
--- a/vp9/encoder/vp9_firstpass.c
+++ b/vp9/encoder/vp9_firstpass.c
@@ -378,6 +378,19 @@
   vp9_variance_fn_ptr_t v_fn_ptr = cpi->fn_ptr[BLOCK_16X16];
   int new_mv_mode_penalty = 256;
 
+  int sr = 0;
+  int quart_frm = MIN(cpi->common.Width, cpi->common.Height);
+
+  // refine the motion search range accroding to the frame dimension
+  // for first pass test
+  while ((quart_frm << sr) < MAX_FULL_PEL_VAL)
+    sr++;
+  if (sr)
+    sr--;
+
+  step_param    += sr;
+  further_steps -= sr;
+
   // override the default variance function to use MSE
   v_fn_ptr.vf = vp9_mse16x16;
 
--- a/vp9/encoder/vp9_mbgraph.c
+++ b/vp9/encoder/vp9_mbgraph.c
@@ -420,7 +420,7 @@
       cpi->static_mb_pct = (ncnt[1] * 100) / cm->MBs;
 
     // This error case should not be reachable as this function should
-    // never be called with the common data structure unititialized.
+    // never be called with the common data structure uninitialized.
     else
       cpi->static_mb_pct = 0;
 
--- a/vp9/encoder/vp9_mcomp.c
+++ b/vp9/encoder/vp9_mcomp.c
@@ -21,9 +21,9 @@
 
 void vp9_clamp_mv_min_max(MACROBLOCK *x, int_mv *ref_mv) {
   int col_min = (ref_mv->as_mv.col >> 3) - MAX_FULL_PEL_VAL +
-      ((ref_mv->as_mv.col & 7) ? 1 : 0);
+                                 ((ref_mv->as_mv.col & 7) ? 1 : 0);
   int row_min = (ref_mv->as_mv.row >> 3) - MAX_FULL_PEL_VAL +
-      ((ref_mv->as_mv.row & 7) ? 1 : 0);
+                                 ((ref_mv->as_mv.row & 7) ? 1 : 0);
   int col_max = (ref_mv->as_mv.col >> 3) + MAX_FULL_PEL_VAL;
   int row_max = (ref_mv->as_mv.row >> 3) + MAX_FULL_PEL_VAL;
 
@@ -36,6 +36,19 @@
     x->mv_row_min = row_min;
   if (x->mv_row_max > row_max)
     x->mv_row_max = row_max;
+}
+
+int vp9_init_search_range(int width, int height) {
+  int sr = 0;
+  int frm = MIN(width, height);
+
+  while ((frm << sr) < MAX_FULL_PEL_VAL)
+    sr++;
+
+  if (sr)
+    sr--;
+
+  return sr;
 }
 
 int vp9_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvjcost, int *mvcost[2],
--- a/vp9/encoder/vp9_mcomp.h
+++ b/vp9/encoder/vp9_mcomp.h
@@ -19,12 +19,17 @@
 void print_mode_context(VP9_COMMON *pc);
 #endif
 
+// The maximum number of steps in a step search given the largest
+// allowed initial step
+#define MAX_MVSEARCH_STEPS 10
+// Max full pel mv specified in 1 pel units
+#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS)) - 1)
+// Maximum size of the first step in full pel units
+#define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS-1))
 
-#define MAX_MVSEARCH_STEPS 8                                    // The maximum number of steps in a step search given the largest allowed initial step
-#define MAX_FULL_PEL_VAL ((1 << (MAX_MVSEARCH_STEPS)) - 1)      // Max full pel mv specified in 1 pel units
-#define MAX_FIRST_STEP (1 << (MAX_MVSEARCH_STEPS-1))            // Maximum size of the first step in full pel units
-
 void vp9_clamp_mv_min_max(MACROBLOCK *x, int_mv *ref_mv);
+int vp9_init_search_range(int width, int height);
+
 int vp9_mv_bit_cost(int_mv *mv, int_mv *ref, int *mvjcost,
                            int *mvcost[2], int weight, int ishp);
 void vp9_init_dsmotion_compensation(MACROBLOCK *x, int stride);
--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -3505,6 +3505,8 @@
 
         vp9_clamp_mv_min_max(x, &ref_mv[0]);
 
+        sr = vp9_init_search_range(cpi->common.Width, cpi->common.Height);
+
         // mvp_full.as_int = ref_mv[0].as_int;
         mvp_full.as_int =
          mbmi->ref_mvs[refs[0]][x->mv_best_ref_index[refs[0]]].as_int;