shithub: libvpx

Download patch

ref: 0daadeb60c14ebb1c1657f2091dc7abc30640970
parent: 1d9e2b50031f6e43f5d696426beb97f1ae4a7ce1
author: Jingning Han <jingning@google.com>
date: Mon Aug 11 13:48:14 EDT 2014

Enable motion field based mode seach skip

This commit allows the encoder to check the above and left neighbor
blocks' reference frames and motion vectors. If they are all
consistent, skip checking the NEARMV and ZEROMV modes. This is
enabled in speed 3. The coding performance is improved:

pedestrian area 1080p at 2000 kbps,
from  74773 b/f, 41.101 dB, 198064 ms
to    74795 b/f, 41.099 dB, 193078 ms

park joy 1080p at 15000 kbps,
from 290727 b/f, 30.640 dB, 609113 ms
to   290558 b/f, 30.630 dB, 592815 ms

Overall compression performance of speed 3 is changed
derf  -0.171%
stdhd -0.168%

Change-Id: I8d47dd543a5f90d7a1c583f74035b926b6704b95

--- a/vp9/encoder/vp9_rdopt.c
+++ b/vp9/encoder/vp9_rdopt.c
@@ -2682,6 +2682,40 @@
       continue;
     second_ref_frame = vp9_mode_order[mode_index].ref_frame[1];
 
+    if (cpi->sf.motion_field_mode_search) {
+      const int mi_width  = MIN(num_8x8_blocks_wide_lookup[bsize],
+                                tile->mi_col_end - mi_col);
+      const int mi_height = MIN(num_8x8_blocks_high_lookup[bsize],
+                                tile->mi_row_end - mi_row);
+      MB_MODE_INFO *ref_mbmi;
+      int const_motion = 1;
+      int_mv ref_mv;
+      ref_mv.as_int = INVALID_MV;
+
+      if ((mi_row - 1) >= tile->mi_row_start) {
+        ref_mv = xd->mi[-xd->mi_stride]->mbmi.mv[0];
+        for (i = 0; i < mi_width; ++i) {
+          ref_mbmi = &xd->mi[-xd->mi_stride + i]->mbmi;
+          const_motion &= (ref_mv.as_int == ref_mbmi->mv[0].as_int) &&
+                          (ref_frame == ref_mbmi->ref_frame[0]);
+        }
+      }
+
+      if ((mi_col - 1) >= tile->mi_col_start) {
+        if (ref_mv.as_int == INVALID_MV)
+          ref_mv = xd->mi[-1]->mbmi.mv[0];
+        for (i = 0; i < mi_height; ++i) {
+          ref_mbmi = &xd->mi[i * xd->mi_stride - 1]->mbmi;
+          const_motion &= (ref_mv.as_int == ref_mbmi->mv[0].as_int) &&
+                          (ref_frame == ref_mbmi->ref_frame[0]);
+        }
+      }
+
+      if (const_motion)
+        if (this_mode == NEARMV || this_mode == ZEROMV)
+          continue;
+    }
+
     comp_pred = second_ref_frame > INTRA_FRAME;
     if (comp_pred) {
       if ((mode_search_skip_flags & FLAG_SKIP_COMP_BESTINTRA) &&
--- a/vp9/encoder/vp9_speed_features.c
+++ b/vp9/encoder/vp9_speed_features.c
@@ -119,6 +119,7 @@
 
     sf->adaptive_pred_interp_filter = 0;
     sf->cb_pred_filter_search = 1;
+    sf->motion_field_mode_search = frame_is_boosted(cpi) ? 0 : 1;
 
     sf->lf_motion_threshold = LOW_MOTION_THRESHOLD;
     sf->last_partitioning_redo_frequency = 3;
@@ -344,6 +345,7 @@
   sf->adaptive_pred_interp_filter = 0;
   sf->cb_pred_filter_search = 0;
   sf->cb_partition_search = 0;
+  sf->motion_field_mode_search = 0;
   sf->use_quant_fp = 0;
   sf->reference_masking = 0;
   sf->partition_search_type = SEARCH_PARTITION;
--- a/vp9/encoder/vp9_speed_features.h
+++ b/vp9/encoder/vp9_speed_features.h
@@ -288,6 +288,8 @@
 
   int cb_partition_search;
 
+  int motion_field_mode_search;
+
   // Fast quantization process path
   int use_quant_fp;