]> granicus.if.org Git - libvpx/commitdiff
Add a new PREDICTION mode using NEARMV as ref mv
authorZoe Liu <zoeliu@google.com>
Tue, 17 Mar 2015 23:48:48 +0000 (16:48 -0700)
committerZoe Liu <zoeliu@google.com>
Thu, 2 Apr 2015 21:37:22 +0000 (14:37 -0700)
This experiment, referred as NEWMVREF, also merged with NEWMVREF_SUB8X8
and the latter one has been removed. Runborgs results show that:

(1) Turning on this experiment only, compared against the base:
derflf: Average PSNR 0.40%; Overall PSNR 0.40%; SSIM 0.35%
(2) Turning on all the experiments including this feature, compared against
that without this feature, on the highbitdepth case using 12-bit:
derflf: Average PSNR 0.33%; Overall PSNR 0.32%; SSIM 0.30%.

Now for highbitdepth using 12-bit, compared against base:
derflf: Average PSNR 11.12%; Overall PSNR 11.07%; SSIM 20.27%.

Change-Id: Ie61dbfd5a19b8652920d2c602201a25a018a87a6

15 files changed:
configure
vp9/common/vp9_blockd.h
vp9/common/vp9_entropymode.c
vp9/common/vp9_loopfilter.c
vp9/common/vp9_mvref_common.c
vp9/common/vp9_mvref_common.h
vp9/decoder/vp9_decodemv.c
vp9/encoder/vp9_bitstream.c
vp9/encoder/vp9_denoiser.c
vp9/encoder/vp9_encodemv.c
vp9/encoder/vp9_pickmode.c
vp9/encoder/vp9_rd.c
vp9/encoder/vp9_rd.h
vp9/encoder/vp9_rdopt.c
vp9/encoder/vp9_speed_features.h

index 4593d252fb6d974084b0be1b2c6b2e08507f27cc..670cf05c1564a4af3fce976d5a9b30bbcc1517a6 100755 (executable)
--- a/configure
+++ b/configure
@@ -293,8 +293,8 @@ EXPERIMENT_LIST="
     compound_modes
     global_motion
     palette
-    newmvref_sub8x8
     new_quant
+    newmvref
 "
 CONFIG_LIST="
     external_build
index 00fcb86b3c017523b610f498646ea5bffa6ac6bb..e4f3c6709cd4f31532ef60dbcca2f17fb570fbd9 100644 (file)
@@ -85,6 +85,9 @@ typedef enum {
   NEARMV,
   ZEROMV,
   NEWMV,
+#if CONFIG_NEWMVREF
+  NEAR_FORNEWMV,
+#endif  // CONFIG_NEWMVREF
 #if CONFIG_COMPOUND_MODES
   NEAREST_NEARESTMV,
   NEAREST_NEARMV,
@@ -110,7 +113,11 @@ typedef enum {
 #endif  // CONFIG_COPY_MODE
 
 static INLINE int is_inter_mode(PREDICTION_MODE mode) {
+#if CONFIG_NEWMVREF
+  return mode >= NEARESTMV && mode <= NEAR_FORNEWMV;
+#else
   return mode >= NEARESTMV && mode <= NEWMV;
+#endif  // CONFIG_NEWMVREF
 }
 
 #if CONFIG_COMPOUND_MODES
@@ -122,19 +129,31 @@ static INLINE int is_inter_compound_mode(PREDICTION_MODE mode) {
 static INLINE int have_newmv_in_inter_mode(PREDICTION_MODE mode) {
 #if CONFIG_COMPOUND_MODES
   return (mode == NEWMV ||
+#if CONFIG_NEWMVREF
+          mode == NEAR_FORNEWMV ||
+#endif  // CONFIG_NEWMVREF
           mode == NEW_NEWMV ||
           mode == NEAREST_NEWMV ||
           mode == NEW_NEARESTMV ||
           mode == NEAR_NEWMV ||
           mode == NEW_NEARMV);
+#else
+#if CONFIG_NEWMVREF
+  return (mode == NEWMV ||
+          mode == NEAR_FORNEWMV);
 #else
   return (mode == NEWMV);
+#endif  // CONFIG_NEWMVREF
 #endif  // CONFIG_COMPOUND_MODES
 }
 
 #define INTRA_MODES (TM_PRED + 1)
 
+#if CONFIG_NEWMVREF
+#define INTER_MODES (1 + NEAR_FORNEWMV - NEARESTMV)
+#else
 #define INTER_MODES (1 + NEWMV - NEARESTMV)
+#endif  // CONFIG_NEWMVREF
 
 #define INTER_OFFSET(mode) ((mode) - NEARESTMV)
 
@@ -159,9 +178,9 @@ static INLINE int have_newmv_in_inter_mode(PREDICTION_MODE mode) {
 typedef struct {
   PREDICTION_MODE as_mode;
   int_mv as_mv[2];  // first, second inter predictor motion vectors
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
   int_mv ref_mv[2];
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
 } b_mode_info;
 
 // Note that the rate-distortion optimization loop, bit-stream writer, and
index d0ecd01b94600a596d3030159d2d6bac689bdf7b..58c5482ecc8c456f434cbaa7f21c4bc757704945 100644 (file)
@@ -242,6 +242,16 @@ static const vp9_prob default_partition_probs[PARTITION_CONTEXTS]
 
 static const vp9_prob default_inter_mode_probs[INTER_MODE_CONTEXTS]
                                               [INTER_MODES - 1] = {
+#if CONFIG_NEWMVREF
+  // TODO(zoeliu): To adjust the initial default probs
+  {2,       173,   34,   192},  // 0 = both zero mv
+  {7,       145,   85,   192},  // 1 = one zero mv + one a predicted mv
+  {7,       166,   63,   192},  // 2 = two predicted mvs
+  {7,       94,    66,   192},  // 3 = one predicted/zero and one new mv
+  {8,       64,    46,   192},  // 4 = two new mvs
+  {17,      81,    31,   192},  // 5 = one intra neighbour + x
+  {25,      29,    30,   192},  // 6 = two intra neighbours
+#else
   {2,       173,   34},  // 0 = both zero mv
   {7,       145,   85},  // 1 = one zero mv + one a predicted mv
   {7,       166,   63},  // 2 = two predicted mvs
@@ -249,6 +259,7 @@ static const vp9_prob default_inter_mode_probs[INTER_MODE_CONTEXTS]
   {8,       64,    46},  // 4 = two new mvs
   {17,      81,    31},  // 5 = one intra neighbour + x
   {25,      29,    30},  // 6 = two intra neighbours
+#endif  // CONFIG_NEWMVREF
 };
 
 #if CONFIG_COMPOUND_MODES
@@ -280,7 +291,12 @@ const vp9_tree_index vp9_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = {
 const vp9_tree_index vp9_inter_mode_tree[TREE_SIZE(INTER_MODES)] = {
   -INTER_OFFSET(ZEROMV), 2,
   -INTER_OFFSET(NEARESTMV), 4,
+#if CONFIG_NEWMVREF
+  -INTER_OFFSET(NEARMV), 6,
+  -INTER_OFFSET(NEWMV), -INTER_OFFSET(NEAR_FORNEWMV)
+#else
   -INTER_OFFSET(NEARMV), -INTER_OFFSET(NEWMV)
+#endif  // CONFIG_NEWMVREF
 };
 
 #if CONFIG_COMPOUND_MODES
index ba93d99f5e0640bfa47c9f2dff9e41346bed0ffc..18fb615facf0ac674efd2f8d99e90b5b651f146f 100644 (file)
@@ -216,6 +216,9 @@ static const uint16_t above_border_uv = 0x000f;
 static const int mode_lf_lut[MB_MODE_COUNT] = {
   0, 0, 0, 0, 0, 0, 0, 0, 0, 0,  // INTRA_MODES
   1, 1, 0, 1,                    // INTER_MODES (ZEROMV == 0)
+#if CONFIG_NEWMVREF
+  1,  // NEAR_FORNEWMV mode
+#endif  // CONFIG_NEWMVREF
 #if CONFIG_COMPOUND_MODES
   1, 1, 1, 1, 1, 1, 1, 0, 1          // INTER_COMPOUND_MODES (ZERO_ZEROMV == 0)
 #endif
index c0303fcfc58faa4b5f2ba1e288eb7f6fc9b7dba1..3fed2e0e60ba3c49184303777e618844e0fb54b0 100644 (file)
@@ -26,9 +26,9 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
   const MB_MODE_INFO *const prev_mbmi = prev_mi ? &prev_mi->mbmi : NULL;
   const POSITION *const mv_ref_search = mv_ref_blocks[mi->mbmi.sb_type];
   int different_ref_found = 0;
-#if !CONFIG_NEWMVREF_SUB8X8
+#if !CONFIG_NEWMVREF
   int context_counter = 0;
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
 
   // Blank the reference vector list
   vpx_memset(mv_ref_list, 0, sizeof(*mv_ref_list) * MAX_MV_REF_CANDIDATES);
@@ -43,9 +43,9 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
                                                    xd->mi_stride].src_mi;
       const MB_MODE_INFO *const candidate = &candidate_mi->mbmi;
       // Keep counts for entropy encoding.
-#if !CONFIG_NEWMVREF_SUB8X8
+#if !CONFIG_NEWMVREF
       context_counter += mode_2_counter[candidate->mode];
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
       different_ref_found = 1;
 
       if (candidate->ref_frame[0] == ref_frame) {
@@ -103,16 +103,16 @@ static void find_mv_refs_idx(const VP9_COMMON *cm, const MACROBLOCKD *xd,
 
  Done:
 
-#if !CONFIG_NEWMVREF_SUB8X8
+#if !CONFIG_NEWMVREF
   mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter];
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
 
   // Clamp vectors
   for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i)
     clamp_mv_ref(&mv_ref_list[i].as_mv, xd);
 }
 
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
 // This function keeps a mode count for a given MB/SB
 void vp9_update_mv_context(const VP9_COMMON *cm, const MACROBLOCKD *xd,
                            const TileInfo *const tile,
@@ -150,17 +150,17 @@ void vp9_update_mv_context(const VP9_COMMON *cm, const MACROBLOCKD *xd,
 
   mi->mbmi.mode_context[ref_frame] = counter_to_context[context_counter];
 }
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
 
 void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd,
                       const TileInfo *const tile,
                       MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
                       int_mv *mv_ref_list,
                       int mi_row, int mi_col) {
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
   vp9_update_mv_context(cm, xd, tile, mi, ref_frame, mv_ref_list, -1,
                         mi_row, mi_col);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
   find_mv_refs_idx(cm, xd, tile, mi, ref_frame, mv_ref_list, -1,
                    mi_row, mi_col);
 }
@@ -182,13 +182,13 @@ void vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp,
 void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
                                    const TileInfo *const tile,
                                    int block, int ref, int mi_row, int mi_col,
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
                                    int_mv *mv_list,
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
                                    int_mv *nearest, int_mv *near) {
-#if !CONFIG_NEWMVREF_SUB8X8
+#if !CONFIG_NEWMVREF
   int_mv mv_list[MAX_MV_REF_CANDIDATES];
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
   MODE_INFO *const mi = xd->mi[0].src_mi;
   b_mode_info *bmi = mi->bmi;
   int n;
index f38423e891c5a561c78e25f7b517a8d6b7411f2a..f5d275cb2e5d28d10866fb0abf193101034b4d62 100644 (file)
@@ -59,6 +59,9 @@ static const int mode_2_counter[MB_MODE_COUNT] = {
   0,  // NEARMV
   3,  // ZEROMV
   1,  // NEWMV
+#if CONFIG_NEWMVREF
+  1,  // NEAR_FORNEWMV
+#endif  // CONFIG_NEWMVREF
 #if CONFIG_COMPOUND_MODES
   0,  // NEAREST_NEARESTMV
   0,  // NEAREST_NEARMV
@@ -215,14 +218,14 @@ static INLINE void clamp_mv2(MV *mv, const MACROBLOCKD *xd) {
                xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN);
 }
 
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
 // This function keeps a mode count for a given MB/SB
 void vp9_update_mv_context(const VP9_COMMON *cm, const MACROBLOCKD *xd,
                            const TileInfo *const tile,
                            MODE_INFO *mi, MV_REFERENCE_FRAME ref_frame,
                            int_mv *mv_ref_list,
                            int block, int mi_row, int mi_col);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
 
 void vp9_find_mv_refs(const VP9_COMMON *cm, const MACROBLOCKD *xd,
                       const TileInfo *const tile,
@@ -247,9 +250,9 @@ void vp9_find_best_ref_mvs(MACROBLOCKD *xd, int allow_hp,
 void vp9_append_sub8x8_mvs_for_idx(VP9_COMMON *cm, MACROBLOCKD *xd,
                                    const TileInfo *const tile,
                                    int block, int ref, int mi_row, int mi_col,
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
                                    int_mv *mv_list,
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
                                    int_mv *nearest, int_mv *near);
 
 #if CONFIG_COPY_MODE
index 2e9695199195dd859ff619f036fe972740d74e9f..404f682f2b5f6e89c9a0298692c7ecfe58af62b6 100644 (file)
@@ -788,6 +788,9 @@ static INLINE int assign_mv(VP9_COMMON *cm, PREDICTION_MODE mode,
   assert(is_inter_mode(mode));
 #endif
   switch (mode) {
+#if CONFIG_NEWMVREF
+    case NEAR_FORNEWMV:
+#endif  // CONFIG_NEWMVREF
     case NEWMV: {
       nmv_context_counts *const mv_counts = cm->frame_parallel_decoding_mode ?
                                             NULL : &cm->counts.mv;
@@ -1040,9 +1043,9 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
     int idx, idy;
     PREDICTION_MODE b_mode;
     int_mv nearest_sub8x8[2], near_sub8x8[2];
-#if CONFIG_NEWMVREF_SUB8X8
-    int_mv ref_mv[2];
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
+    int_mv ref_mvs[2][2];
+#endif  // CONFIG_NEWMVREF
     for (idy = 0; idy < 2; idy += num_4x4_h) {
       for (idx = 0; idx < 2; idx += num_4x4_w) {
         int_mv block[2];
@@ -1058,36 +1061,36 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
 #endif
 #if CONFIG_COMPOUND_MODES
         if (b_mode == NEARESTMV || b_mode == NEARMV ||
-#if CONFIG_NEWMVREF_SUB8X8
-            b_mode == NEWMV || b_mode == NEW_NEWMV ||
-#endif  // CONFIG_NEWMVREF_SUB8X8
-            b_mode == NEAREST_NEARESTMV || b_mode == NEAREST_NEARMV ||
-            b_mode == NEAR_NEARESTMV || b_mode == NEAREST_NEWMV ||
-            b_mode == NEW_NEARESTMV || b_mode == NEAR_NEWMV ||
-            b_mode == NEW_NEARMV)
+#if CONFIG_NEWMVREF
+            b_mode == NEWMV || b_mode == NEAR_FORNEWMV ||
+            b_mode == NEW_NEWMV ||
+#endif  // CONFIG_NEWMVREF
+            b_mode == NEAREST_NEARESTMV ||
+            b_mode == NEAREST_NEARMV || b_mode == NEAR_NEARESTMV ||
+            b_mode == NEAREST_NEWMV || b_mode == NEW_NEARESTMV ||
+            b_mode == NEAR_NEWMV || b_mode == NEW_NEARMV)
 #else
         if (b_mode == NEARESTMV || b_mode == NEARMV
-#if CONFIG_NEWMVREF_SUB8X8
-            || b_mode == NEWMV
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
+            || b_mode == NEWMV || b_mode == NEAR_FORNEWMV
+#endif  // CONFIG_NEWMVREF
             )
 #endif  // CONFIG_COMPOUND_MODES
         {
           for (ref = 0; ref < 1 + is_compound; ++ref) {
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
             int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
-            int_mv second_ref_mv;
             vp9_update_mv_context(cm, xd, tile, mi, mbmi->ref_frame[ref],
                                   mv_ref_list, j, mi_row, mi_col);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
             vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, j, ref, mi_row, mi_col,
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
                                           mv_ref_list,
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
                                           &nearest_sub8x8[ref],
                                           &near_sub8x8[ref]);
-#if CONFIG_NEWMVREF_SUB8X8
-            if (b_mode == NEWMV
+#if CONFIG_NEWMVREF
+            if (b_mode == NEWMV || b_mode == NEAR_FORNEWMV
 #if CONFIG_COMPOUND_MODES
                 || b_mode == NEW_NEWMV ||
                 b_mode == NEAREST_NEWMV ||
@@ -1099,18 +1102,18 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
               mv_ref_list[0].as_int = nearest_sub8x8[ref].as_int;
               mv_ref_list[1].as_int = near_sub8x8[ref].as_int;
               vp9_find_best_ref_mvs(xd, allow_hp, mv_ref_list,
-                                    &ref_mv[ref], &second_ref_mv);
+                                    &ref_mvs[0][ref], &ref_mvs[1][ref]);
             }
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
           }
         }
 
         if (!assign_mv(cm, b_mode, block,
-#if CONFIG_NEWMVREF_SUB8X8
-                       ref_mv,
+#if CONFIG_NEWMVREF
+                       (b_mode == NEAR_FORNEWMV) ? ref_mvs[1] : ref_mvs[0],
 #else
                        nearestmv,
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
                        nearest_sub8x8, near_sub8x8,
                        is_compound, allow_hp, r)) {
           xd->corrupted |= 1;
@@ -1132,6 +1135,12 @@ static void read_inter_block_mode_info(VP9_COMMON *const cm,
     mbmi->mv[0].as_int = mi->bmi[3].as_mv[0].as_int;
     mbmi->mv[1].as_int = mi->bmi[3].as_mv[1].as_int;
   } else {
+#if CONFIG_NEWMVREF
+    if (mbmi->mode == NEAR_FORNEWMV)
+      xd->corrupted |= !assign_mv(cm, mbmi->mode, mbmi->mv, nearmv,
+                                  nearestmv, nearmv, is_compound, allow_hp, r);
+    else
+#endif  // CONFIG_NEWMVREF
     xd->corrupted |= !assign_mv(cm, mbmi->mode, mbmi->mv, nearestmv,
                                 nearestmv, nearmv, is_compound, allow_hp, r);
   }
index 8f1ccb0b53add6274a30032f774595553fdb1396..ba9f5dab23fdc8ed75a6daa09af0b4df1c608aaf 100644 (file)
@@ -752,36 +752,44 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
 #endif  // CONFIG_COMPOUND_MODES
 
 #if CONFIG_COMPOUND_MODES
-          if (b_mode == NEWMV || b_mode == NEW_NEWMV) {
+          if (b_mode == NEWMV ||
+#if CONFIG_NEWMVREF
+              b_mode == NEAR_FORNEWMV ||
+#endif  // CONFIG_NEWMVREF
+              b_mode == NEW_NEWMV) {
+#else
+#if CONFIG_NEWMVREF
+          if (b_mode == NEWMV || b_mode == NEAR_FORNEWMV) {
 #else
           if (b_mode == NEWMV) {
+#endif  // CONFIG_NEWMVREF
 #endif  // CONFIG_COMPOUND_MODES
             for (ref = 0; ref < 1 + is_compound; ++ref) {
               vp9_encode_mv(cpi, w, &mi->bmi[j].as_mv[ref].as_mv,
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
                             &mi->bmi[j].ref_mv[ref].as_mv,
 #else
                             &mbmi->ref_mvs[mbmi->ref_frame[ref]][0].as_mv,
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
                             nmvc, allow_hp);
             }
           }
 #if CONFIG_COMPOUND_MODES
           else if (b_mode == NEAREST_NEWMV || b_mode == NEAR_NEWMV) {
             vp9_encode_mv(cpi, w, &mi->bmi[j].as_mv[1].as_mv,
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
                           &mi->bmi[j].ref_mv[1].as_mv,
 #else
                           &mbmi->ref_mvs[mbmi->ref_frame[1]][0].as_mv,
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
                           nmvc, allow_hp);
           } else if (b_mode == NEW_NEARESTMV || b_mode == NEW_NEARMV) {
             vp9_encode_mv(cpi, w, &mi->bmi[j].as_mv[0].as_mv,
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
                           &mi->bmi[j].ref_mv[0].as_mv,
 #else
                           &mbmi->ref_mvs[mbmi->ref_frame[0]][0].as_mv,
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
                           nmvc, allow_hp);
           }
 #endif  // CONFIG_COMPOUND_MODES
@@ -789,14 +797,30 @@ static void pack_inter_mode_mvs(VP9_COMP *cpi, const MODE_INFO *mi,
       }
     } else {
 #if CONFIG_COMPOUND_MODES
-      if (mode == NEWMV || mode == NEW_NEWMV) {
+      if (mode == NEWMV ||
+#if CONFIG_NEWMVREF
+          mode == NEAR_FORNEWMV ||
+#endif  // CONFIG_NEWMVREF
+          mode == NEW_NEWMV) {
+#else  // CONFIG_COMPOUND_MODES
+#if CONFIG_NEWMVREF
+      if (mode == NEWMV || mode == NEAR_FORNEWMV) {
 #else
       if (mode == NEWMV) {
+#endif  // CONFIG_NEWMVREF
 #endif  // CONFIG_COMPOUND_MODES
-        for (ref = 0; ref < 1 + is_compound; ++ref)
+        for (ref = 0; ref < 1 + is_compound; ++ref) {
+#if CONFIG_NEWMVREF
+          if (mode == NEAR_FORNEWMV)
+            vp9_encode_mv(cpi, w, &mbmi->mv[ref].as_mv,
+                          &mbmi->ref_mvs[mbmi->ref_frame[ref]][1].as_mv, nmvc,
+                          allow_hp);
+          else
+#endif  // CONFIG_NEWMVREF
           vp9_encode_mv(cpi, w, &mbmi->mv[ref].as_mv,
                         &mbmi->ref_mvs[mbmi->ref_frame[ref]][0].as_mv, nmvc,
                         allow_hp);
+        }
       }
 #if CONFIG_COMPOUND_MODES
       else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
index 6e1af8e458603c8c5ab2bd6080553046dda12424..bcbf05dd5b45d5fd3cfe153e8dd0f79d76b1d4c0 100644 (file)
@@ -426,11 +426,18 @@ void vp9_denoiser_update_frame_stats(MB_MODE_INFO *mbmi, unsigned int sse,
     ctx->best_zeromv_reference_frame = mbmi->ref_frame[0];
   }
 #if CONFIG_COMPOUND_MODES
-  if (mode == NEW_NEWMV || mode == NEWMV || mode == NEW_NEARESTMV ||
-      mode == NEAREST_NEWMV) {
+  if (mode == NEW_NEWMV || mode == NEWMV ||
+#if CONFIG_NEWMVREF
+      mode == NEAR_FORNEWMV ||
+#endif  // CONFIG_NEWMVREF
+      mode == NEW_NEARESTMV || mode == NEAREST_NEWMV) {
+#else
+#if CONFIG_NEWMVREF
+  if (mode == NEWMV || mode == NEAR_FORNEWMV) {
 #else
   if (mode == NEWMV) {
-#endif
+#endif  // CONFIG_NEWMVREF
+#endif  // CONFIG_COMPOUND_MODES
     ctx->newmv_sse = sse;
     ctx->best_sse_inter_mode = mode;
     ctx->best_sse_mv = mbmi->mv[0];
index dd6b3d688acf89ddfdfab979469ec693aedf4c07..683fb7f7bd98b4516ea2c0d241318687f86e7ef4 100644 (file)
@@ -257,8 +257,14 @@ void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd) {
   int i;
   int_mv ref_mv[2];
 
-  for (i = 0; i < 1 + has_second_ref(mbmi); ++i)
-    ref_mv[i].as_int = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_int;
+  for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
+#if CONFIG_NEWMVREF
+    if (mbmi->sb_type >= BLOCK_8X8 && mbmi->mode == NEAR_FORNEWMV)
+      ref_mv[i].as_int = mbmi->ref_mvs[mbmi->ref_frame[i]][1].as_int;
+    else
+#endif  // CONFIG_NEWMVREF
+      ref_mv[i].as_int = mbmi->ref_mvs[mbmi->ref_frame[i]][0].as_int;
+  }
 
   if (mbmi->sb_type < BLOCK_8X8) {
     const int num_4x4_w = num_4x4_blocks_wide_lookup[mbmi->sb_type];
@@ -269,11 +275,20 @@ void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd) {
       for (idx = 0; idx < 2; idx += num_4x4_w) {
         const int i = idy * 2 + idx;
 #if CONFIG_COMPOUND_MODES
-        if (mi->bmi[i].as_mode == NEWMV || mi->bmi[i].as_mode == NEW_NEWMV)
+        if (mi->bmi[i].as_mode == NEWMV ||
+#if CONFIG_NEWMVREF
+            mi->bmi[i].as_mode == NEAR_FORNEWMV ||
+#endif  // CONFIG_NEWMVREF
+            mi->bmi[i].as_mode == NEW_NEWMV)
+#else
+#if CONFIG_NEWMVREF
+        if (mi->bmi[i].as_mode == NEWMV ||
+            mi->bmi[i].as_mode == NEAR_FORNEWMV)
 #else
         if (mi->bmi[i].as_mode == NEWMV)
+#endif  // CONFIG_NEWMVREF
 #endif
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
           inc_mvs(mbmi, mi->bmi[i].as_mv,
                   mi->bmi[i].ref_mv,
                   &cm->counts.mv);
@@ -281,11 +296,11 @@ void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd) {
           inc_mvs(mbmi, mi->bmi[i].as_mv,
                   ref_mv,
                   &cm->counts.mv);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
 #if CONFIG_COMPOUND_MODES
         else if (mi->bmi[i].as_mode == NEAREST_NEWMV ||
                  mi->bmi[i].as_mode == NEAR_NEWMV)
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
           inc_compound_single_mv(1, mi->bmi[i].as_mv,
                                  mi->bmi[i].ref_mv,
                                  &cm->counts.mv);
@@ -293,10 +308,10 @@ void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd) {
           inc_compound_single_mv(1, mi->bmi[i].as_mv,
                                  ref_mv,
                                  &cm->counts.mv);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
         else if (mi->bmi[i].as_mode == NEW_NEARESTMV ||
                  mi->bmi[i].as_mode == NEW_NEARMV)
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
           inc_compound_single_mv(0, mi->bmi[i].as_mv,
                                  mi->bmi[i].ref_mv,
                                  &cm->counts.mv);
@@ -304,16 +319,24 @@ void vp9_update_mv_count(VP9_COMMON *cm, const MACROBLOCKD *xd) {
           inc_compound_single_mv(0, mi->bmi[i].as_mv,
                                  ref_mv,
                                  &cm->counts.mv);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
 #endif  // CONFIG_COMPOUND_MODES
       }
     }
   } else {
 #if CONFIG_COMPOUND_MODES
-    if (mbmi->mode == NEWMV || mbmi->mode == NEW_NEWMV)
-#else
+    if (mbmi->mode == NEWMV ||
+#if CONFIG_NEWMVREF
+        mbmi->mode == NEAR_FORNEWMV ||
+#endif  // CONFIG_NEWMVREF
+        mbmi->mode == NEW_NEWMV)
+#else  // CONFIG_COMPOUND_MODES
+#if CONFIG_NEWMVREF
+    if (mbmi->mode == NEWMV || mbmi->mode == NEAR_FORNEWMV)
+#else  // CONFIG_NEWMVREF
     if (mbmi->mode == NEWMV)
-#endif
+#endif  // CONFIG_NEWMVREF
+#endif  // CONFIG_COMPOUND_MODES
       inc_mvs(mbmi, mbmi->mv, ref_mv, &cm->counts.mv);
 #if CONFIG_COMPOUND_MODES
     else if (mbmi->mode == NEAREST_NEWMV || mbmi->mode == NEAR_NEWMV)
index a80819cdfd507c5a84eff20e37fce85248077213..daa8346934c18184c3c923e911ef126e929edb80 100644 (file)
@@ -471,9 +471,15 @@ static void estimate_block_intra(int plane, int block, BLOCK_SIZE plane_bsize,
 }
 
 static const THR_MODES mode_idx[MAX_REF_FRAMES - 1][INTER_MODES] = {
+#if CONFIG_NEWMVREF
+  {THR_NEARESTMV, THR_NEARMV, THR_ZEROMV, THR_NEWMV, THR_NEAR_FORNEWMV},
+  {THR_NEARESTG, THR_NEARG, THR_ZEROG, THR_NEWG, THR_NEAR_FORNEWG},
+  {THR_NEARESTA, THR_NEARA, THR_ZEROA, THR_NEWA, THR_NEAR_FORNEWA},
+#else
   {THR_NEARESTMV, THR_NEARMV, THR_ZEROMV, THR_NEWMV},
   {THR_NEARESTG, THR_NEARG, THR_ZEROG, THR_NEWG},
   {THR_NEARESTA, THR_NEARA, THR_ZEROA, THR_NEWA},
+#endif  // CONFIG_NEWMVREF
 };
 
 // TODO(jingning) placeholder for inter-frame non-RD mode decision.
index ad8e0e47c507fe9c8c859a66662e8a295e0cceca..3afab4e21356ab11fa80438933dbf52b09611585 100644 (file)
@@ -595,9 +595,18 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
   rd->thresh_mult[THR_NEWA] += 1000;
   rd->thresh_mult[THR_NEWG] += 1000;
 
+#if CONFIG_NEWMVREF
+  rd->thresh_mult[THR_NEAR_FORNEWMV] += 1000;
+  rd->thresh_mult[THR_NEAR_FORNEWA] += 1000;
+  rd->thresh_mult[THR_NEAR_FORNEWG] += 1000;
+#endif  // CONFIG_NEWMVREF
+
   // Adjust threshold only in real time mode, which only uses last
   // reference frame.
   rd->thresh_mult[THR_NEWMV] += sf->elevate_newmv_thresh;
+#if CONFIG_NEWMVREF
+  rd->thresh_mult[THR_NEAR_FORNEWMV] += sf->elevate_newmv_thresh;
+#endif  // CONFIG_NEWMVREF
 
   rd->thresh_mult[THR_NEARMV] += 1000;
   rd->thresh_mult[THR_NEARA] += 1000;
@@ -635,6 +644,10 @@ void vp9_set_rd_speed_thresholds(VP9_COMP *cpi) {
   rd->thresh_mult[THR_COMP_NEARGA] += 1500;
   rd->thresh_mult[THR_COMP_NEWLA] += 2000;
   rd->thresh_mult[THR_COMP_NEWGA] += 2000;
+#if CONFIG_NEWMVREF
+  rd->thresh_mult[THR_COMP_NEAR_FORNEWLA] += 2000;
+  rd->thresh_mult[THR_COMP_NEAR_FORNEWGA] += 2000;
+#endif  // CONFIG_NEWMVREF
   rd->thresh_mult[THR_COMP_ZEROLA] += 2500;
   rd->thresh_mult[THR_COMP_ZEROGA] += 2500;
 #endif  // CONFIG_COMPOUND_MODES
index b4ebb7cea34833d7e0dff41e89457575cb40f554..cbe6376dd10879f9c70054773c16555ec220d7f7 100644 (file)
@@ -36,19 +36,45 @@ extern "C" {
 #if CONFIG_COMPOUND_MODES
 
 #if CONFIG_INTERINTRA
+
+#if CONFIG_NEWMVREF
+#define MAX_MODES 55
+#define INTERINTRA_START_MODE 43
+#else
 #define MAX_MODES 52
 #define INTERINTRA_START_MODE 40
+#endif  // CONFIG_NEWMVREF
+
+#else  // CONFIG_INTERINTRA
+
+#if CONFIG_NEWMVREF
+#define MAX_MODES 43
 #else
 #define MAX_MODES 40
+#endif  // CONFIG_NEWMVREF
+
 #endif  // CONFIG_INTERINTRA
 
 #else   // CONFIG_COMPOUND_MODES
 
 #if CONFIG_INTERINTRA
+
+#if CONFIG_NEWMVREF
+#define MAX_MODES 47
+#define INTERINTRA_START_MODE 35
+#else
 #define MAX_MODES 42
 #define INTERINTRA_START_MODE 30
+#endif  // CONFIG_NEWMVREF
+
+#else  // CONFIG_INTERINTRA
+
+#if CONFIG_NEWMVREF
+#define MAX_MODES 35
 #else
 #define MAX_MODES 30
+#endif  // CONFIG_NEWMVREF
+
 #endif  // CONFIG_INTERINTRA
 
 #endif  // CONFIG_COMPOUND_MODES
@@ -68,6 +94,12 @@ typedef enum {
   THR_NEWA,
   THR_NEWG,
 
+#if CONFIG_NEWMVREF
+  THR_NEAR_FORNEWMV,
+  THR_NEAR_FORNEWA,
+  THR_NEAR_FORNEWG,
+#endif  // CONFIG_NEWMVREF
+
   THR_NEARMV,
   THR_NEARA,
   THR_NEARG,
@@ -113,6 +145,11 @@ typedef enum {
   THR_COMP_NEARGA,
   THR_COMP_NEWGA,
 
+#if CONFIG_NEWMVREF
+  THR_COMP_NEAR_FORNEWLA,
+  THR_COMP_NEAR_FORNEWGA,
+#endif  // CONFIG_NEWMVREF
+
   THR_COMP_ZEROLA,
   THR_COMP_ZEROGA,
 #endif  // CONFIG_COMPOUND_MODES
index e8b1ee960a2f1de729b3edaa043bbe3720992b9e..75abd4d0a11698a97034c7e9bf84d7ce5799d490 100644 (file)
@@ -96,6 +96,12 @@ static const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
   {NEWMV,     {ALTREF_FRAME, NONE}},
   {NEWMV,     {GOLDEN_FRAME, NONE}},
 
+#if CONFIG_NEWMVREF
+  {NEAR_FORNEWMV, {LAST_FRAME,   NONE}},
+  {NEAR_FORNEWMV, {ALTREF_FRAME, NONE}},
+  {NEAR_FORNEWMV, {GOLDEN_FRAME, NONE}},
+#endif  // CONFIG_NEWMVREF
+
   {NEARMV,    {LAST_FRAME,   NONE}},
   {NEARMV,    {ALTREF_FRAME, NONE}},
   {NEARMV,    {GOLDEN_FRAME, NONE}},
@@ -140,6 +146,11 @@ static const MODE_DEFINITION vp9_mode_order[MAX_MODES] = {
   {NEARMV,    {GOLDEN_FRAME, ALTREF_FRAME}},
   {NEWMV,     {GOLDEN_FRAME, ALTREF_FRAME}},
 
+#if CONFIG_NEWMVREF
+  {NEAR_FORNEWMV, {LAST_FRAME,   ALTREF_FRAME}},
+  {NEAR_FORNEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+#endif  // CONFIG_NEWMVREF
+
   {ZEROMV,    {LAST_FRAME,   ALTREF_FRAME}},
   {ZEROMV,    {GOLDEN_FRAME, ALTREF_FRAME}},
 #endif  // CONFIG_COMPOUND_MODES
@@ -2250,6 +2261,9 @@ static int set_and_cost_bmi_mvs(VP9_COMP *cpi, MACROBLOCKD *xd, int i,
 #endif  // CONFIG_COMPOUND_MODES
   switch (mode) {
     case NEWMV:
+#if CONFIG_NEWMVREF
+    case NEAR_FORNEWMV:
+#endif  // CONFIG_NEWMVREF
       this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
       thismvcost += vp9_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
                                     mvjcost, mvcost, MV_COST_WEIGHT_SUB);
@@ -2288,13 +2302,13 @@ static int set_and_cost_bmi_mvs(VP9_COMP *cpi, MACROBLOCKD *xd, int i,
     case NEW_NEARMV:
     case NEW_NEARESTMV:
       this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
       // Check the ref mv precision to have the final mv precision aligned
       // with that of its reference.
       if (!cpi->common.allow_high_precision_mv ||
           !vp9_use_mv_hp(&best_ref_mv[0]->as_mv))
         vp9_lower_mv_precision(&this_mv[0].as_mv, 0);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
       thismvcost += vp9_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
                                     mvjcost, mvcost, MV_COST_WEIGHT_SUB);
       this_mv[1].as_int = frame_mv[mbmi->ref_frame[1]].as_int;
@@ -2303,13 +2317,13 @@ static int set_and_cost_bmi_mvs(VP9_COMP *cpi, MACROBLOCKD *xd, int i,
     case NEAREST_NEWMV:
       this_mv[0].as_int = frame_mv[mbmi->ref_frame[0]].as_int;
       this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
       // Check the ref mv precision to have the final mv precision aligned
       // with that of its reference.
       if (!cpi->common.allow_high_precision_mv ||
           !vp9_use_mv_hp(&best_ref_mv[1]->as_mv))
         vp9_lower_mv_precision(&this_mv[1].as_mv, 0);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
       thismvcost += vp9_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
                                     mvjcost, mvcost, MV_COST_WEIGHT_SUB);
       break;
@@ -2471,9 +2485,9 @@ typedef struct {
   int64_t bsse;
   int64_t brdcost;
   int_mv mvs[2];
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
   int_mv ref_mv[2];
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
   ENTROPY_CONTEXT ta[2];
   ENTROPY_CONTEXT tl[2];
 } SEG_RDSTAT;
@@ -2632,7 +2646,7 @@ static void single_motion_search_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
   int cost_list[5];
 
   if (cpi->oxcf.mode != BEST) {
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
     mvp->as_int = ref_mv->as_int;
 #else
     // use previous block's result as next block's MV predictor.
@@ -2641,7 +2655,7 @@ static void single_motion_search_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
       if (i == 2)
         mvp->as_int = mi->bmi[i - 2].as_mv[0].as_int;
     }
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
   }
   if (i == 0)
     max_mv = x->max_mv_context[mbmi->ref_frame[0]];
@@ -2715,18 +2729,21 @@ static void single_motion_search_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
     x->pred_mv[mbmi->ref_frame[0]] = *new_mv;
 }
 
-static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
-                                        const TileInfo * const tile,
-                                        int_mv *best_ref_mv,
-                                        int_mv *second_best_ref_mv,
-                                        int64_t best_rd, int *returntotrate,
-                                        int *returnyrate,
-                                        int64_t *returndistortion,
-                                        int *skippable, int64_t *psse,
-                                        int mvthresh,
-                                        int_mv seg_mvs[4][MAX_REF_FRAMES],
-                                        BEST_SEG_INFO *bsi_buf, int filter_idx,
-                                        int mi_row, int mi_col) {
+static int64_t rd_pick_best_sub8x8_mode(
+    VP9_COMP *cpi, MACROBLOCK *x,
+    const TileInfo * const tile,
+    int64_t best_rd, int *returntotrate,
+    int *returnyrate,
+    int64_t *returndistortion,
+    int *skippable, int64_t *psse,
+    int mvthresh,
+#if CONFIG_NEWMVREF
+    int_mv seg_mvs[4][MAX_MV_REF_CANDIDATES][MAX_REF_FRAMES],
+#else
+    int_mv seg_mvs[4][MAX_REF_FRAMES],
+#endif  // CONFIG_NEWMVREF
+    BEST_SEG_INFO *bsi_buf, int filter_idx,
+    int mi_row, int mi_col) {
   int i;
   BEST_SEG_INFO *bsi = bsi_buf + filter_idx;
   MACROBLOCKD *xd = &x->e_mbd;
@@ -2753,19 +2770,37 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
 #if CONFIG_COMPOUND_MODES
   int_mv newnew_seg_mvs[4][MAX_REF_FRAMES];
 #endif
+#if CONFIG_NEWMVREF
+  int_mv ref_mvs_sub8x8[MAX_MV_REF_CANDIDATES][2];
+#else
   int_mv ref_mv_sub8x8[2];
+#endif  // CONFIG_NEWMVREF
 
   vp9_zero(*bsi);
 
   bsi->segment_rd = best_rd;
-  bsi->mvp.as_int = best_ref_mv->as_int;
+  bsi->mvp.as_int =
+      mbmi->ref_mvs[mbmi->ref_frame[0]][0].as_int;
   bsi->mvthresh = mvthresh;
 
-  ref_mv_sub8x8[0].as_int = best_ref_mv->as_int;
-  ref_mv_sub8x8[1].as_int =
-      second_best_ref_mv ? second_best_ref_mv->as_int : 0;
+#if CONFIG_NEWMVREF
+  for (i = 0; i < MAX_MV_REF_CANDIDATES; i ++) {
+    ref_mvs_sub8x8[i][0].as_int =
+        mbmi->ref_mvs[mbmi->ref_frame[0]][i].as_int;
+    ref_mvs_sub8x8[i][1].as_int = has_second_rf ?
+        mbmi->ref_mvs[mbmi->ref_frame[1]][i].as_int : 0;
+  }
+  // Initialize the segment ref mv using NEARESTMV
+  bsi->ref_mv[0] = &ref_mvs_sub8x8[0][0];
+  bsi->ref_mv[1] = &ref_mvs_sub8x8[0][1];
+#else
+  ref_mv_sub8x8[0].as_int =
+      mbmi->ref_mvs[mbmi->ref_frame[0]][0].as_int;
+  ref_mv_sub8x8[1].as_int = has_second_rf ?
+      mbmi->ref_mvs[mbmi->ref_frame[1]][0].as_int : 0;
   bsi->ref_mv[0] = &ref_mv_sub8x8[0];
   bsi->ref_mv[1] = &ref_mv_sub8x8[1];
+#endif  // CONFIG_NEWMVREF
 
   for (i = 0; i < 4; i++)
     bsi->modes[i] = ZEROMV;
@@ -2790,28 +2825,30 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
       int64_t best_rd = INT64_MAX;
       const int i = idy * 2 + idx;
       int ref;
+#if CONFIG_NEWMVREF
+      int mv_idx;
+#endif  // CONFIG_NEWMVREF
 
       for (ref = 0; ref < 1 + has_second_rf; ++ref) {
         const MV_REFERENCE_FRAME frame = mbmi->ref_frame[ref];
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
         int_mv mv_ref_list[MAX_MV_REF_CANDIDATES];
-        int_mv second_ref_mv;
         vp9_update_mv_context(cm, xd, tile, mi, frame, mv_ref_list,
                               i, mi_row, mi_col);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
         frame_mv[ZEROMV][frame].as_int = 0;
         vp9_append_sub8x8_mvs_for_idx(cm, xd, tile, i, ref, mi_row, mi_col,
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
                                       mv_ref_list,
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
                                       &frame_mv[NEARESTMV][frame],
                                       &frame_mv[NEARMV][frame]);
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
         mv_ref_list[0].as_int = frame_mv[NEARESTMV][frame].as_int;
         mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
         vp9_find_best_ref_mvs(xd, cm->allow_high_precision_mv, mv_ref_list,
-                              &ref_mv_sub8x8[ref], &second_ref_mv);
-#endif  // CONFIG_NEWMVREF_SUB8X8
+                              &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
+#endif  // CONFIG_NEWMVREF
 #if CONFIG_COMPOUND_MODES
         frame_mv[ZERO_ZEROMV][frame].as_int = 0;
         frame_mv[NEAREST_NEARESTMV][frame].as_int =
@@ -2851,15 +2888,31 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
       }
 
       // search for the best motion vector on this segment
+#if CONFIG_NEWMVREF
+#if CONFIG_COMPOUND_MODES
+      for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
+           this_mode <= (has_second_rf ? NEW_NEWMV : NEAR_FORNEWMV);
+           ++this_mode) {
+#else  // CONFIG_COMPOUND_MODES
+      for (this_mode = NEARESTMV; this_mode <= NEAR_FORNEWMV; ++this_mode) {
+#endif  // CONFIG_COMPOUND_MODES
+#else  // CONFIG_NEWMVREF
 #if CONFIG_COMPOUND_MODES
       for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
            this_mode <= (has_second_rf ? NEW_NEWMV : NEWMV); ++this_mode) {
-#else
+#else  // CONFIG_COMPOUND_MODES
       for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
-#endif
+#endif  // CONFIG_COMPOUND_MODES
+#endif  // CONFIG_NEWMVREF
         const struct buf_2d orig_src = x->plane[0].src;
         struct buf_2d orig_pre[2];
 
+#if CONFIG_NEWMVREF
+        mv_idx = (this_mode == NEAR_FORNEWMV) ? 1 : 0;
+        bsi->ref_mv[0] = &ref_mvs_sub8x8[mv_idx][0];
+        bsi->ref_mv[1] = &ref_mvs_sub8x8[mv_idx][1];
+#endif  // CONFIG_NEWMVREF
+
 #if CONFIG_COMPOUND_MODES
         if (is_inter_compound_mode(this_mode)) {
           mode_idx = INTER_COMPOUND_OFFSET(this_mode) + INTER_OFFSET(NEWMV) + 1;
@@ -2885,12 +2938,17 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
                    sizeof(bsi->rdstat[i][mode_idx].tl));
 
         // motion search for newmv (single predictor case only)
-        // Note: Need to check new mvs for every iteration as the mv ref has
-        //       changed in the NEWMVREF_SUB8X8 experiment.
-        if (!has_second_rf && this_mode == NEWMV
-#if !CONFIG_NEWMVREF_SUB8X8
+        // Note: Need to check new mvs for every iteration as the reference mv
+        //       has changed in the NEWMVREF experiment.
+        if (!has_second_rf &&
+#if CONFIG_NEWMVREF
+            (this_mode == NEWMV || this_mode == NEAR_FORNEWMV)
+#else
+            this_mode == NEWMV
+#endif  // CONFIG_NEWMVREF
+#if !CONFIG_NEWMVREF
             && seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
             ) {
           /* Is the best so far sufficiently good that we cant justify doing
            * and new motion search. */
@@ -2903,54 +2961,87 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
           single_motion_search_sub8x8(
               cpi, x, i, bsize,
               &frame_mv[this_mode][mbmi->ref_frame[0]].as_mv,
+#if CONFIG_NEWMVREF
+              &ref_mvs_sub8x8[mv_idx][0],
+#else
               &ref_mv_sub8x8[0],
+#endif  // CONFIG_NEWMVREF
               &bsi->mvp);
           // save motion search result for use in compound prediction
+#if CONFIG_NEWMVREF
+          seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int =
+              frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
+#else
           seg_mvs[i][mbmi->ref_frame[0]].as_int =
               frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
+#endif  // CONFIG_NEWMVREF
           // restore src pointers
           mi_buf_restore(x, orig_src, orig_pre);
         }
 
         if (has_second_rf) {
+#if CONFIG_NEWMVREF
+          if (seg_mvs[i][mv_idx][mbmi->ref_frame[1]].as_int == INVALID_MV ||
+              seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int == INVALID_MV)
+#else
           if (seg_mvs[i][mbmi->ref_frame[1]].as_int == INVALID_MV ||
               seg_mvs[i][mbmi->ref_frame[0]].as_int == INVALID_MV)
+#endif  // CONFIG_NEWMVREF
             continue;
         }
-        // Note: Need to check new mvs for every iteration as the mv ref has
-        //       changed in the NEWMVREF_SUB8X8 experiment.
+        // Note: Need to check new mvs for every iteration as the reference mv
+        //       has changed in the NEWMVREF experiment.
         // TODO(zoeliu): Further optimization work may be done for:
         // NEW_NEARESTMV, NEW_NEARMV, NEAREST_NEWMV, and NEAR_NEWMV, as the mv
         // ref may have changed in the compound mode as opposed to single ref.
         if (has_second_rf &&
 #if CONFIG_COMPOUND_MODES
             this_mode == NEW_NEWMV
-#else
+#else  // CONFIG_COMPOUND_MODES
+#if CONFIG_NEWMVREF
+            (this_mode == NEWMV || this_mode == NEAR_FORNEWMV)
+#else  // CONFIG_NEWMVREF
             this_mode == NEWMV
+#endif  // CONFIG_NEWMVREF
 #endif  // CONFIG_COMPOUND_MODES
-#if !CONFIG_NEWMVREF_SUB8X8
+#if !CONFIG_NEWMVREF
             && mbmi->interp_filter == EIGHTTAP
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
             ) {
           mi_buf_shift(x, i);
           if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
             int rate_mv;
+#if CONFIG_NEWMVREF
+            joint_motion_search(cpi, x, bsize,
+                                frame_mv[this_mode],
+                                ref_mvs_sub8x8[mv_idx],
+                                mi_row, mi_col, seg_mvs[i][mv_idx],
+                                &rate_mv);
+#else
             joint_motion_search(cpi, x, bsize,
                                 frame_mv[this_mode],
                                 ref_mv_sub8x8,
                                 mi_row, mi_col, seg_mvs[i],
                                 &rate_mv);
+#endif  // CONFIG_NEWMVREF
 #if CONFIG_COMPOUND_MODES
             newnew_seg_mvs[i][mbmi->ref_frame[0]].as_int =
                 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
             newnew_seg_mvs[i][mbmi->ref_frame[1]].as_int =
                 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
-#else
+#else  // CONFIG_COMPOUND_MODES
+#if CONFIG_NEWMVREF
+            seg_mvs[i][mv_idx][mbmi->ref_frame[0]].as_int =
+                frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
+            seg_mvs[i][mv_idx][mbmi->ref_frame[1]].as_int =
+                frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
+#else  // CONFIG_NEWMVREF
             seg_mvs[i][mbmi->ref_frame[0]].as_int =
                 frame_mv[this_mode][mbmi->ref_frame[0]].as_int;
             seg_mvs[i][mbmi->ref_frame[1]].as_int =
                 frame_mv[this_mode][mbmi->ref_frame[1]].as_int;
-#endif
+#endif  // CONFIG_NEWMVREF
+#endif  // CONFIG_COMPOUND_MODES
           }
           // restore src pointers
           mi_buf_restore(x, orig_src, orig_pre);
@@ -2964,10 +3055,17 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
                                  x->nmvjointcost, x->mvcost);
         } else {
 #endif
+#if CONFIG_NEWMVREF
+        bsi->rdstat[i][mode_idx].brate =
+            set_and_cost_bmi_mvs(cpi, xd, i, this_mode, mode_mv[this_mode],
+                                 frame_mv[this_mode], seg_mvs[i][mv_idx],
+                                 bsi->ref_mv, x->nmvjointcost, x->mvcost);
+#else
         bsi->rdstat[i][mode_idx].brate =
             set_and_cost_bmi_mvs(cpi, xd, i, this_mode, mode_mv[this_mode],
                                  frame_mv[this_mode], seg_mvs[i], bsi->ref_mv,
                                  x->nmvjointcost, x->mvcost);
+#endif  // CONFIG_NEWMVREF
 #if CONFIG_COMPOUND_MODES
         }
 #endif
@@ -2981,7 +3079,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
           if (num_4x4_blocks_high > 1)
             bsi->rdstat[i + 2][mode_idx].mvs[ref].as_int =
                 mode_mv[this_mode][ref].as_int;
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
           // Save the mv refs for the best mvs.
           bsi->rdstat[i][mode_idx].ref_mv[ref].as_int =
               bsi->ref_mv[ref]->as_int;
@@ -2991,7 +3089,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
           if (num_4x4_blocks_high > 1)
             bsi->rdstat[i + 2][mode_idx].ref_mv[ref].as_int =
                 bsi->ref_mv[ref]->as_int;
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
         }
 
         // Trap vectors that reach beyond the UMV borders
@@ -3007,7 +3105,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
 
           for (ref = 0; ref < 1 + has_second_rf; ++ref) {
             subpelmv |= mv_has_subpel(&mode_mv[this_mode][ref].as_mv);
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
             if (have_newmv_in_inter_mode(this_mode))
               have_ref &= (
                   (mode_mv[this_mode][ref].as_int ==
@@ -3015,7 +3113,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
                   (bsi->ref_mv[ref]->as_int ==
                    ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int) );
             else
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
             have_ref &= mode_mv[this_mode][ref].as_int ==
                 ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
           }
@@ -3024,7 +3122,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
             ref_bsi = bsi_buf + 1;
             have_ref = 1;
             for (ref = 0; ref < 1 + has_second_rf; ++ref)
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
               if (have_newmv_in_inter_mode(this_mode))
                 have_ref &= (
                     (mode_mv[this_mode][ref].as_int ==
@@ -3032,7 +3130,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
                     (bsi->ref_mv[ref]->as_int ==
                      ref_bsi->rdstat[i][mode_idx].ref_mv[ref].as_int) );
               else
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
               have_ref &= mode_mv[this_mode][ref].as_int ==
                   ref_bsi->rdstat[i][mode_idx].mvs[ref].as_int;
           }
@@ -3104,22 +3202,28 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
 #if CONFIG_COMPOUND_MODES
       }
 #endif
+#if CONFIG_NEWMVREF
+      mv_idx = (mode_selected == NEAR_FORNEWMV) ? 1 : 0;
+#endif  // CONFIG_NEWMVREF
       vpx_memcpy(t_above, bsi->rdstat[i][mode_idx].ta, sizeof(t_above));
       vpx_memcpy(t_left, bsi->rdstat[i][mode_idx].tl, sizeof(t_left));
 
 #if CONFIG_COMPOUND_MODES
-      if (mode_selected == NEW_NEWMV) {
+      if (mode_selected == NEW_NEWMV)
         set_and_cost_bmi_mvs(cpi, xd, i, mode_selected, mode_mv[mode_selected],
                              frame_mv[mode_selected], newnew_seg_mvs[i],
                              bsi->ref_mv, x->nmvjointcost, x->mvcost);
-      } else {
+      else
 #endif
+#if CONFIG_NEWMVREF
+      set_and_cost_bmi_mvs(cpi, xd, i, mode_selected, mode_mv[mode_selected],
+                           frame_mv[mode_selected], seg_mvs[i][mv_idx],
+                           bsi->ref_mv, x->nmvjointcost, x->mvcost);
+#else
       set_and_cost_bmi_mvs(cpi, xd, i, mode_selected, mode_mv[mode_selected],
                            frame_mv[mode_selected], seg_mvs[i],
                            bsi->ref_mv, x->nmvjointcost, x->mvcost);
-#if CONFIG_COMPOUND_MODES
-      }
-#endif
+#endif  // CONFIG_NEWMVREF
 
       br += bsi->rdstat[i][mode_idx].brate;
       bd += bsi->rdstat[i][mode_idx].bdist;
@@ -3149,31 +3253,28 @@ static int64_t rd_pick_best_sub8x8_mode(VP9_COMP *cpi, MACROBLOCK *x,
   bsi->sse = block_sse;
 
   // update the coding decisions
-  for (k = 0; k < 4; ++k) {
+  for (k = 0; k < 4; ++k)
     bsi->modes[k] = mi->bmi[k].as_mode;
-  }
 
   if (bsi->segment_rd > best_rd)
     return INT64_MAX;
   /* set it to the best */
   for (i = 0; i < 4; i++) {
 #if CONFIG_COMPOUND_MODES
-    if (is_inter_compound_mode(bsi->modes[i])) {
+    if (is_inter_compound_mode(bsi->modes[i]))
       mode_idx = INTER_COMPOUND_OFFSET(bsi->modes[i]) + INTER_OFFSET(NEWMV) + 1;
-    } else {
+    else
 #endif
     mode_idx = INTER_OFFSET(bsi->modes[i]);
-#if CONFIG_COMPOUND_MODES
-    }
-#endif
+
     mi->bmi[i].as_mv[0].as_int = bsi->rdstat[i][mode_idx].mvs[0].as_int;
     if (has_second_ref(mbmi))
       mi->bmi[i].as_mv[1].as_int = bsi->rdstat[i][mode_idx].mvs[1].as_int;
-#if CONFIG_NEWMVREF_SUB8X8
+#if CONFIG_NEWMVREF
     mi->bmi[i].ref_mv[0].as_int = bsi->rdstat[i][mode_idx].ref_mv[0].as_int;
     if (has_second_ref(mbmi))
       mi->bmi[i].ref_mv[1].as_int = bsi->rdstat[i][mode_idx].ref_mv[1].as_int;
-#endif  // CONFIG_NEWMVREF_SUB8X8
+#endif  // CONFIG_NEWMVREF
     x->plane[0].eobs[i] = bsi->rdstat[i][mode_idx].eobs;
     mi->bmi[i].as_mode = bsi->modes[i];
   }
@@ -3316,6 +3417,9 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
 #if CONFIG_COMPOUND_MODES
                                  int ref_idx,
 #endif
+#if CONFIG_NEWMVREF
+                                 int mv_idx,
+#endif  // CONFIG_NEWMVREF
                                  int_mv *tmp_mv, int *rate_mv) {
   MACROBLOCKD *xd = &x->e_mbd;
   const VP9_COMMON *cm = &cpi->common;
@@ -3330,8 +3434,11 @@ static void single_motion_search(VP9_COMP *cpi, MACROBLOCK *x,
 #else
   int ref = mbmi->ref_frame[0];
 #endif
-
+#if CONFIG_NEWMVREF
+  MV ref_mv = mbmi->ref_mvs[ref][mv_idx].as_mv;
+#else
   MV ref_mv = mbmi->ref_mvs[ref][0].as_mv;
+#endif  // CONFIG_NEWMVREF
 
   int tmp_col_min = x->mv_col_min;
   int tmp_col_max = x->mv_col_max;
@@ -3806,12 +3913,20 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
                                  int *disable_skip,
                                  int_mv (*mode_mv)[MAX_REF_FRAMES],
                                  int mi_row, int mi_col,
+#if CONFIG_NEWMVREF
+                                 int_mv single_newmv[2][MAX_REF_FRAMES],
+#else
                                  int_mv single_newmv[MAX_REF_FRAMES],
+#endif  // CONFIG_NEWMVREF
                                  INTERP_FILTER (*single_filter)[MAX_REF_FRAMES],
                                  int (*single_skippable)[MAX_REF_FRAMES],
 #if CONFIG_INTERINTRA
                                  int *compmode_interintra_cost,
+#if CONFIG_NEWMVREF
+                                 int single_newmv_rate[2][MAX_REF_FRAMES],
+#else
                                  int single_newmv_rate[MAX_REF_FRAMES],
+#endif  // CONFIG_NEWMVREF
 #endif
 #if CONFIG_WEDGE_PARTITION
                                  int *compmode_wedge_cost,
@@ -3891,11 +4006,19 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
       lf = xd->mi[-1].src_mi->mbmi.interp_filter;
 
 #if CONFIG_COMPOUND_MODES
-    if ((this_mode != NEWMV && this_mode != NEW_NEWMV) ||
+    if ((this_mode != NEWMV &&
+#if CONFIG_NEWMVREF
+         this_mode != NEAR_FORNEWMV &&
+#endif  // CONFIG_NEWMVREF
+         this_mode != NEW_NEWMV) || (af == lf))
+#else  // CONFIG_COMPOUND_MODES
+#if CONFIG_NEWMVREF
+    if ((this_mode != NEWMV && this_mode != NEAR_FORNEWMV) ||
         (af == lf))
-#else
+#else  // CONFIG_NEWMVREF
     if ((this_mode != NEWMV) || (af == lf))
-#endif
+#endif  // CONFIG_NEWMVREF
+#endif  // CONFIG_COMPOUND_MODES
 
       best_filter = af;
   }
@@ -3968,18 +4091,42 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
 
 #if CONFIG_COMPOUND_MODES
   if (this_mode == NEWMV || this_mode == NEW_NEWMV ||
+#if CONFIG_NEWMVREF
+      this_mode == NEAR_FORNEWMV ||
+#endif  // CONFIG_NEWMVREF
       this_mode == NEAREST_NEWMV || this_mode == NEW_NEARESTMV ||
       this_mode == NEAR_NEWMV || this_mode == NEW_NEARMV) {
+#else  // CONFIG_COMPOUND_MODES
+#if CONFIG_NEWMVREF
+  if (this_mode == NEWMV || this_mode == NEAR_FORNEWMV) {
 #else
   if (this_mode == NEWMV) {
+#endif  // CONFIG_NEWMVREF
 #endif
     int rate_mv = 0;
+#if CONFIG_NEWMVREF
+    int mv_idx = (this_mode == NEAR_FORNEWMV) ? 1 : 0;
+#endif  // CONFIG_NEWMVREF
+
     if (is_comp_pred) {
+#if CONFIG_NEWMVREF
+      for (i = 0; i < 2; ++i) {
+        // mv_idx==1: NEARMV as reference mv
+        // mv_idx==0: NEARESTMV as reference mv
+        ref_mv[i] = mbmi->ref_mvs[refs[i]][mv_idx];
+      }
+#endif  // CONFIG_NEWMVREF
+
 #if CONFIG_COMPOUND_MODES
       if (this_mode == NEW_NEWMV) {
         if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
+#if CONFIG_NEWMVREF
+          joint_motion_search(cpi, x, bsize, frame_mv, ref_mv,
+                              mi_row, mi_col, single_newmv[0], &rate_mv);
+#else
           joint_motion_search(cpi, x, bsize, frame_mv, ref_mv,
                               mi_row, mi_col, single_newmv, &rate_mv);
+#endif  // CONFIG_NEWMVREF
         } else {
           // Initialize mv using single prediction mode result.
           rate_mv  = vp9_mv_bit_cost(&frame_mv[refs[0]].as_mv,
@@ -4003,8 +4150,13 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
 #else
       // Initialize mv using single prediction mode result.
       if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
+#if CONFIG_NEWMVREF
+        joint_motion_search(cpi, x, bsize, frame_mv, ref_mv,
+                            mi_row, mi_col, single_newmv[mv_idx], &rate_mv);
+#else
         joint_motion_search(cpi, x, bsize, frame_mv, ref_mv,
                             mi_row, mi_col, single_newmv, &rate_mv);
+#endif  // CONFIG_NEWMVREF
       } else {
         rate_mv  = vp9_mv_bit_cost(&frame_mv[refs[0]].as_mv,
                                    &mbmi->ref_mvs[refs[0]][0].as_mv,
@@ -4019,27 +4171,44 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
 #endif
     } else {
       int_mv tmp_mv;
+
 #if CONFIG_INTERINTRA
       if (!is_comp_interintra_pred) {
         single_motion_search(cpi, x, bsize, mi_row, mi_col,
 #if CONFIG_COMPOUND_MODES
                              0,
 #endif
+#if CONFIG_NEWMVREF
+                             mv_idx,
+#endif  // CONFIG_NEWMVREF
                              &tmp_mv, &rate_mv);
         if (tmp_mv.as_int == INVALID_MV)
           return INT64_MAX;
         frame_mv[refs[0]].as_int = tmp_mv.as_int;
+#if CONFIG_NEWMVREF
+        single_newmv[mv_idx][refs[0]].as_int = tmp_mv.as_int;
+        single_newmv_rate[mv_idx][refs[0]] = rate_mv;
+#else
         single_newmv[refs[0]].as_int = tmp_mv.as_int;
         single_newmv_rate[refs[0]] = rate_mv;
+#endif  // CONFIG_NEWMVREF
       } else {
+#if CONFIG_NEWMVREF
+        frame_mv[refs[0]].as_int = single_newmv[mv_idx][refs[0]].as_int;
+        rate_mv = single_newmv_rate[mv_idx][refs[0]];
+#else
         frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
         rate_mv = single_newmv_rate[refs[0]];
+#endif  // CONFIG_NEWMVREF
       }
-#else
+#else  // CONFIG_INTERINTRA
       single_motion_search(cpi, x, bsize, mi_row, mi_col,
 #if CONFIG_COMPOUND_MODES
                            0,
 #endif
+#if CONFIG_NEWMVREF
+                           mv_idx,
+#endif  // CONFIG_NEWMVREF
                            &tmp_mv, &rate_mv);
       if (tmp_mv.as_int == INVALID_MV)
         return INT64_MAX;
@@ -4047,7 +4216,11 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
       *rate2 += rate_mv;
 #endif
       frame_mv[refs[0]].as_int = tmp_mv.as_int;
+#if CONFIG_NEWMVREF
+      single_newmv[mv_idx][refs[0]].as_int = tmp_mv.as_int;
+#else
       single_newmv[refs[0]].as_int = tmp_mv.as_int;
+#endif  // CONFIG_NEWMVREF
 #endif  // CONFIG_INTERINTRA
     }
 #if CONFIG_WEDGE_PARTITION || CONFIG_INTERINTRA
@@ -4060,11 +4233,18 @@ static int64_t handle_inter_mode(VP9_COMP *cpi, MACROBLOCK *x,
     // Clip "next_nearest" so that it does not extend to far out of image
 #if CONFIG_COMPOUND_MODES
     if (this_mode != NEWMV && this_mode != NEW_NEWMV
+#if CONFIG_NEWMVREF
+        && this_mode != NEAR_FORNEWMV
+#endif  // CONFIG_NEWMVREF
         && !((this_mode == NEAR_NEWMV || this_mode == NEAREST_NEWMV) && i == 1)
         && !((this_mode == NEW_NEARMV || this_mode == NEW_NEARESTMV) && i == 0))
+#else
+#if CONFIG_NEWMVREF
+    if (this_mode != NEWMV && this_mode != NEAR_FORNEWMV)
 #else
     if (this_mode != NEWMV)
-#endif
+#endif  // CONFIG_NEWMVREF
+#endif  // CONFIG_COMPOUND_MODES
       clamp_mv2(&cur_mv[i].as_mv, xd);
 
     if (mv_check_bounds(x, &cur_mv[i].as_mv))
@@ -5117,7 +5297,11 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   int comp_pred, i, k;
   int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES];
   struct buf_2d yv12_mb[4][MAX_MB_PLANE];
+#if CONFIG_NEWMVREF
+  int_mv single_newmv[2][MAX_REF_FRAMES] = { { { 0 } }, { { 0 } } };
+#else
   int_mv single_newmv[MAX_REF_FRAMES] = { { 0 } };
+#endif  // CONFIG_NEWMVREF
   INTERP_FILTER single_inter_filter[MB_MODE_COUNT][MAX_REF_FRAMES];
   int single_skippable[MB_MODE_COUNT][MAX_REF_FRAMES];
   static const int flag_list[4] = { 0, VP9_LAST_FLAG, VP9_GOLD_FLAG,
@@ -5145,7 +5329,11 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   int fbit_uv[TX_SIZES];
 #endif  // CONFIG_FILTERINTRA
 #if CONFIG_INTERINTRA
+#if CONFIG_NEWMVREF
+  int single_newmv_rate[2][MAX_REF_FRAMES] = { { 0 }, { 0 } };
+#else
   int single_newmv_rate[MAX_REF_FRAMES] = { 0 };
+#endif  // CONFIG_NEWMVREF
 #endif  // CONFIG_INTERINTRA
   const int intra_cost_penalty = vp9_get_intra_cost_penalty(
       cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
@@ -5226,6 +5414,9 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
                          frame_mv[NEARESTMV], frame_mv[NEARMV], yv12_mb);
     }
     frame_mv[NEWMV][ref_frame].as_int = INVALID_MV;
+#if CONFIG_NEWMVREF
+    frame_mv[NEAR_FORNEWMV][ref_frame].as_int = INVALID_MV;
+#endif  // CONFIG_NEWMVREF
     frame_mv[ZEROMV][ref_frame].as_int = 0;
 #if CONFIG_COMPOUND_MODES
     frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
@@ -5484,13 +5675,20 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
 
 #if CONFIG_COMPOUND_MODES
       if (skip_ref_frame && this_mode != NEARESTMV && this_mode != NEWMV &&
+#if CONFIG_NEWMVREF
+          this_mode != NEAR_FORNEWMV &&
+#endif  // CONFIG_NEWMVREF
           this_mode != NEAREST_NEARESTMV && this_mode != NEW_NEWMV &&
           this_mode != NEAREST_NEWMV &&
           this_mode != NEW_NEARESTMV &&
           this_mode != NEAR_NEWMV &&
           this_mode != NEW_NEARMV)
 #else
-      if (skip_ref_frame && this_mode != NEARESTMV && this_mode != NEWMV)
+      if (skip_ref_frame && this_mode != NEARESTMV &&
+#if CONFIG_NEWMVREF
+          this_mode != NEAR_FORNEWMV &&
+#endif  // CONFIG_NEWMVREF
+          this_mode != NEWMV)
 #endif  // CONFIG_COMPOUND_MODES
         if (rf > INTRA_FRAME)
           if (ref_frame != rf)
@@ -5761,6 +5959,7 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
 #if CONFIG_EXT_TX
       mbmi->ext_txfrm = NORM;
 #endif
+
       this_rd = handle_inter_mode(cpi, x, bsize,
                                   tx_cache,
                                   &rate2, &distortion2, &skippable,
@@ -5994,7 +6193,11 @@ void vp9_rd_pick_inter_mode_sb(VP9_COMP *cpi, MACROBLOCK *x,
   // Therefore, sometimes, NEWMV is chosen instead of NEARESTMV, NEARMV, and
   // ZEROMV. Here, checks are added for those cases, and the mode decisions
   // are corrected.
-  if (best_mbmode.mode == NEWMV) {
+  if (best_mbmode.mode == NEWMV
+#if CONFIG_NEWMVREF
+      || best_mbmode.mode == NEAR_FORNEWMV
+#endif  // CONFIG_NEWMVREF
+      ) {
     const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
         best_mbmode.ref_frame[1]};
     int comp_pred_mode = refs[1] > INTRA_FRAME;
@@ -6713,7 +6916,11 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
 #endif
   const int intra_cost_penalty = vp9_get_intra_cost_penalty(
       cm->base_qindex, cm->y_dc_delta_q, cm->bit_depth);
+#if CONFIG_NEWMVREF
+  int_mv seg_mvs[4][MAX_MV_REF_CANDIDATES][MAX_REF_FRAMES];
+#else
   int_mv seg_mvs[4][MAX_REF_FRAMES];
+#endif  // CONFIG_NEWMVREF
   b_mode_info best_bmodes[4];
   int best_skip2 = 0;
   int ref_frame_skip_mask[2] = { 0 };
@@ -6744,8 +6951,15 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
 
   for (i = 0; i < 4; i++) {
     int j;
+#if CONFIG_NEWMVREF
+    int k;
+    for (k = 0; k < MAX_MV_REF_CANDIDATES; k++)
+      for (j = 0; j < MAX_REF_FRAMES; j++)
+        seg_mvs[i][k][j].as_int = INVALID_MV;
+#else
     for (j = 0; j < MAX_REF_FRAMES; j++)
       seg_mvs[i][j].as_int = INVALID_MV;
+#endif  // CONFIG_NEWMVREF
   }
 
   estimate_ref_frame_costs(cm, xd, segment_id, ref_costs_single, ref_costs_comp,
@@ -6982,8 +7196,6 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
       int64_t tmp_best_distortion = INT_MAX, tmp_best_sse;
       int tmp_best_skippable = 0;
       int switchable_filter_index;
-      int_mv *second_ref = comp_pred ?
-                             &mbmi->ref_mvs[second_ref_frame][0] : NULL;
       b_mode_info tmp_best_bmodes[16];
       MB_MODE_INFO tmp_best_mbmode;
       BEST_SEG_INFO bsi[SWITCHABLE_FILTERS];
@@ -7017,8 +7229,7 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
             int64_t rs_rd;
             mbmi->interp_filter = switchable_filter_index;
             tmp_rd = rd_pick_best_sub8x8_mode(cpi, x, tile,
-                                              &mbmi->ref_mvs[ref_frame][0],
-                                              second_ref, best_yrd, &rate,
+                                              best_yrd, &rate,
                                               &rate_y, &distortion,
                                               &skippable, &total_sse,
                                               (int) this_rd_thresh, seg_mvs,
@@ -7083,8 +7294,7 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
         // Handles the special case when a filter that is not in the
         // switchable list (bilinear, 6-tap) is indicated at the frame level
         tmp_rd = rd_pick_best_sub8x8_mode(cpi, x, tile,
-                                          &mbmi->ref_mvs[ref_frame][0],
-                                          second_ref, best_yrd, &rate, &rate_y,
+                                          best_yrd, &rate, &rate_y,
                                           &distortion, &skippable, &total_sse,
                                           (int) this_rd_thresh, seg_mvs, bsi, 0,
                                           mi_row, mi_col);
@@ -7374,3 +7584,5 @@ void vp9_rd_pick_inter_mode_sub8x8(VP9_COMP *cpi, MACROBLOCK *x,
                        best_pred_diff, best_tx_diff, best_filter_diff, 0);
 }
 
+
+
index e9ee421ae5575a1aafbadcba471bdcb3b8f99563..380277c33efa6d75a9145bfaac887facd6cc9f27 100644 (file)
@@ -35,6 +35,9 @@ enum {
 enum {
   INTER_ALL =
       (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) | (1 << NEWMV) |
+#if CONFIG_NEWMVREF
+      (1 << NEAR_FORNEWMV) |
+#endif  // CONFIG_NEWMVREF
       (1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) | (1 << NEAREST_NEARMV) |
       (1 << NEAR_NEARESTMV) | (1 << NEW_NEWMV) | (1 << NEAREST_NEWMV) |
       (1 << NEAR_NEWMV) | (1 << NEW_NEARMV) | (1 << NEW_NEARESTMV),
@@ -71,7 +74,12 @@ enum {
 };
 #else
 enum {
-  INTER_ALL = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) | (1 << NEWMV),
+  INTER_ALL = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) |
+#if CONFIG_NEWMVREF
+      (1 << NEWMV) | (1 << NEAR_FORNEWMV),
+#else
+      (1 << NEWMV),
+#endif  // CONFIG_NEWMVREF
   INTER_NEAREST = (1 << NEARESTMV),
   INTER_NEAREST_NEW = (1 << NEARESTMV) | (1 << NEWMV),
   INTER_NEAREST_ZERO = (1 << NEARESTMV) | (1 << ZEROMV),
@@ -79,7 +87,7 @@ enum {
   INTER_NEAREST_NEAR_NEW = (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV),
   INTER_NEAREST_NEAR_ZERO = (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV),
 };
-#endif
+#endif  // CONFIG_COMPOUND_MODES
 
 enum {
   DISABLE_ALL_INTER_SPLIT   = (1 << THR_COMP_GA) |