]> granicus.if.org Git - libvpx/commitdiff
Skip mode search based on reference frame consistency
authorJingning Han <jingning@google.com>
Tue, 12 Aug 2014 01:02:18 +0000 (18:02 -0700)
committerJingning Han <jingning@google.com>
Wed, 13 Aug 2014 21:16:18 +0000 (14:16 -0700)
This commit enables the encoder to skip NEARMV and ZEROMV if the
above and left blocks have identical reference frame, and the
current reference is different from that. It reduces the runtime
of speed 3 for test sequences:
bus cif at 1000 kbps 10064 ms -> 9823 ms
pedestrian 1080p at 2000 kbps 193078 ms -> 189559 ms

The compression performance is changed by
derf  -0.085%
stdhd -0.103%

Change-Id: If304f26d42e6412152a84c3dd7b02635c38444f4

vp9/encoder/vp9_rdopt.c

index 3850548d6ffde0dc2d073c48b3bcdd47fca82c69..e368037a6271caf5f8ba61a650b98af5920e6d93 100644 (file)
@@ -2687,30 +2687,45 @@ int64_t vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
                                 tile->mi_col_end - mi_col);
       const int mi_height = MIN(num_8x8_blocks_high_lookup[bsize],
                                 tile->mi_row_end - mi_row);
+      const int bsl = mi_width_log2(bsize);
+      int cb_partition_search_ctrl = (((mi_row + mi_col) >> bsl)
+          + get_chessboard_index(cm->current_video_frame)) & 0x1;
       MB_MODE_INFO *ref_mbmi;
       int const_motion = 1;
+      int skip_ref_frame = !cb_partition_search_ctrl;
+      MV_REFERENCE_FRAME rf = NONE;
       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];
+        rf = xd->mi[-xd->mi_stride]->mbmi.ref_frame[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]);
+          skip_ref_frame &= (rf == 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];
+        if (rf == NONE)
+          rf = xd->mi[-1]->mbmi.ref_frame[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]);
+          skip_ref_frame &= (rf == ref_mbmi->ref_frame[0]);
         }
       }
 
+      if (skip_ref_frame && this_mode != NEARESTMV && this_mode != NEWMV)
+        if (rf > INTRA_FRAME)
+          if (ref_frame != rf)
+            continue;
+
       if (const_motion)
         if (this_mode == NEARMV || this_mode == ZEROMV)
           continue;