]> granicus.if.org Git - libvpx/commitdiff
Adding new compound modes to EXT_INTER experiment
authorYue Chen <yuec@google.com>
Wed, 20 Jan 2016 00:45:45 +0000 (16:45 -0800)
committerYue Chen <yuec@google.com>
Fri, 22 Jan 2016 21:52:16 +0000 (13:52 -0800)
Combinations of different mv modes for two reference frames
are allowed in compound inter modes. 9 options are enabled,
including NEAREST_NEARESTMV, NEAREST_NEARMV, NEAR_NEARESTMV,
NEAREST_NEWMV, NEW_NEARESTMV, NEAR_NEWMV, NEW_NEARMV, ZERO_ZEROMV,
and NEW_NEWMV.
This experiment is mostly deported from the nextgen branch.
It is made compatible with other experiments

Coding gain of EXT_INTER(derflr/hevcmr/hevchd): 0.533%/0.728%/0.639%

Change-Id: Id47e97284e6481b186870afbad33204b7a33dbb0

21 files changed:
vp10/common/blockd.h
vp10/common/entropymode.c
vp10/common/entropymode.h
vp10/common/enums.h
vp10/common/loopfilter.c
vp10/common/mvref_common.c
vp10/common/mvref_common.h
vp10/common/thread_common.c
vp10/decoder/decodeframe.c
vp10/decoder/decodemv.c
vp10/encoder/bitstream.c
vp10/encoder/block.h
vp10/encoder/denoiser.c
vp10/encoder/encodeframe.c
vp10/encoder/encodemv.c
vp10/encoder/encoder.h
vp10/encoder/mbgraph.c
vp10/encoder/rd.c
vp10/encoder/rd.h
vp10/encoder/rdopt.c
vp10/encoder/speed_features.h

index 8c75c97afbdc6693765c3583cfb70185f04c1655..8011456a390ee0f8b0ebaf355942b9188d1924d1 100644 (file)
@@ -49,15 +49,26 @@ typedef enum {
 
 static INLINE int is_inter_mode(PREDICTION_MODE mode) {
 #if CONFIG_EXT_INTER
-  return mode >= NEARESTMV && mode <= NEWFROMNEARMV;
+  return mode >= NEARESTMV && mode <= NEW_NEWMV;
 #else
   return mode >= NEARESTMV && mode <= NEWMV;
 #endif  // CONFIG_EXT_INTER
 }
 
 #if CONFIG_EXT_INTER
+static INLINE int is_inter_singleref_mode(PREDICTION_MODE mode) {
+  return mode >= NEARESTMV && mode <= NEWFROMNEARMV;
+}
+
+static INLINE int is_inter_compound_mode(PREDICTION_MODE mode) {
+  return mode >= NEAREST_NEARESTMV && mode <= NEW_NEWMV;
+}
+
 static INLINE int have_newmv_in_inter_mode(PREDICTION_MODE mode) {
-  return (mode == NEWMV || mode == NEWFROMNEARMV);
+  return (mode == NEWMV || mode == NEWFROMNEARMV ||
+          mode == NEW_NEWMV ||
+          mode == NEAREST_NEWMV || mode == NEW_NEARESTMV ||
+          mode == NEAR_NEWMV || mode == NEW_NEARMV);
 }
 #endif  // CONFIG_EXT_INTER
 
index 579745101cdca324fd41753706085d1f32fd2f2c..44c10990a6547e9e59dc447a733d406fc5db545d 100644 (file)
@@ -211,6 +211,19 @@ static const vpx_prob default_inter_mode_probs[INTER_MODE_CONTEXTS]
 #endif  // CONFIG_EXT_INTER
 };
 
+#if CONFIG_EXT_INTER
+static const vpx_prob default_inter_compound_mode_probs
+                      [INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES - 1] = {
+  { 2, 173,  68, 192, 192, 128, 180, 180},   // 0 = both zero mv
+  { 7, 145, 160, 192, 192, 128, 180, 180},   // 1 = 1 zero + 1 predicted
+  { 7, 166, 126, 192, 192, 128, 180, 180},   // 2 = two predicted mvs
+  { 7,  94, 132, 192, 192, 128, 180, 180},   // 3 = 1 pred/zero, 1 new
+  { 8,  64,  64, 192, 192, 128, 180, 180},   // 4 = two new mvs
+  {17,  81,  52, 192, 192, 128, 180, 180},   // 5 = one intra neighbour
+  {25,  29,  50, 192, 192, 128, 180, 180},   // 6 = two intra neighbours
+};
+#endif  // CONFIG_EXT_INTER
+
 /* Array indices are identical to previously-existing INTRAMODECONTEXTNODES. */
 const vpx_tree_index vp10_intra_mode_tree[TREE_SIZE(INTRA_MODES)] = {
   -DC_PRED, 2,                      /* 0 = DC_NODE */
@@ -235,6 +248,21 @@ const vpx_tree_index vp10_inter_mode_tree[TREE_SIZE(INTER_MODES)] = {
 #endif  // CONFIG_EXT_INTER
 };
 
+#if CONFIG_EXT_INTER
+const vpx_tree_index vp10_inter_compound_mode_tree
+      [TREE_SIZE(INTER_COMPOUND_MODES)] = {
+  -INTER_COMPOUND_OFFSET(ZERO_ZEROMV), 2,
+  -INTER_COMPOUND_OFFSET(NEAREST_NEARESTMV), 4,
+  6, -INTER_COMPOUND_OFFSET(NEW_NEWMV),
+  8, 10,
+  -INTER_COMPOUND_OFFSET(NEAREST_NEARMV),
+  -INTER_COMPOUND_OFFSET(NEAR_NEARESTMV),
+  12, 14,
+  -INTER_COMPOUND_OFFSET(NEAREST_NEWMV), -INTER_COMPOUND_OFFSET(NEW_NEARESTMV),
+  -INTER_COMPOUND_OFFSET(NEAR_NEWMV), -INTER_COMPOUND_OFFSET(NEW_NEARMV)
+};
+#endif  // CONFIG_EXT_INTER
+
 const vpx_tree_index vp10_partition_tree[TREE_SIZE(PARTITION_TYPES)] = {
   -PARTITION_NONE, 2,
   -PARTITION_HORZ, 4,
@@ -1257,6 +1285,9 @@ static void init_mode_probs(FRAME_CONTEXT *fc) {
 #endif  // CONFIG_EXT_INTER
 #endif  // CONFIG_REF_MV
   vp10_copy(fc->inter_mode_probs, default_inter_mode_probs);
+#if CONFIG_EXT_INTER
+  vp10_copy(fc->inter_compound_mode_probs, default_inter_compound_mode_probs);
+#endif  // CONFIG_EXT_INTER
 #if CONFIG_SUPERTX
   vp10_copy(fc->supertx_prob, default_supertx_prob);
 #endif  // CONFIG_SUPERTX
@@ -1336,6 +1367,14 @@ void vp10_adapt_inter_frame_probs(VP10_COMMON *cm) {
   }
 #endif  // CONFIG_SUPERTX
 
+#if CONFIG_EXT_INTER
+  for (i = 0; i < INTER_MODE_CONTEXTS; i++)
+    vpx_tree_merge_probs(vp10_inter_compound_mode_tree,
+                         pre_fc->inter_compound_mode_probs[i],
+                         counts->inter_compound_mode[i],
+                         fc->inter_compound_mode_probs[i]);
+#endif  // CONFIG_EXT_INTER
+
   for (i = 0; i < BLOCK_SIZE_GROUPS; i++)
     vpx_tree_merge_probs(vp10_intra_mode_tree, pre_fc->y_mode_prob[i],
                 counts->y_mode[i], fc->y_mode_prob[i]);
index ffaa3dfa37c1e2ab97d3a39ee2100cb723d9a9b1..01dcd5266081e6701fd99c9394a3e8df6b4215e6 100644 (file)
@@ -26,6 +26,9 @@ extern "C" {
 #define TX_SIZE_CONTEXTS 2
 
 #define INTER_OFFSET(mode) ((mode) - NEARESTMV)
+#if CONFIG_EXT_INTER
+#define INTER_COMPOUND_OFFSET(mode) ((mode) - NEAREST_NEARESTMV)
+#endif  // CONFIG_EXT_INTER
 
 #define PALETTE_COLOR_CONTEXTS 16
 #define PALETTE_MAX_SIZE 8
@@ -71,6 +74,10 @@ typedef struct frame_contexts {
 #endif
 
   vpx_prob inter_mode_probs[INTER_MODE_CONTEXTS][INTER_MODES - 1];
+#if CONFIG_EXT_INTER
+  vpx_prob inter_compound_mode_probs[INTER_MODE_CONTEXTS]
+                                    [INTER_COMPOUND_MODES - 1];
+#endif  // CONFIG_EXT_INTER
   vpx_prob intra_inter_prob[INTRA_INTER_CONTEXTS];
   vpx_prob comp_inter_prob[COMP_INTER_CONTEXTS];
   vpx_prob single_ref_prob[REF_CONTEXTS][SINGLE_REFS-1];
@@ -119,6 +126,9 @@ typedef struct FRAME_COUNTS {
 #endif
 
   unsigned int inter_mode[INTER_MODE_CONTEXTS][INTER_MODES];
+#if CONFIG_EXT_INTER
+  unsigned int inter_compound_mode[INTER_MODE_CONTEXTS][INTER_COMPOUND_MODES];
+#endif  // CONFIG_EXT_INTER
   unsigned int intra_inter[INTRA_INTER_CONTEXTS][2];
   unsigned int comp_inter[COMP_INTER_CONTEXTS][2];
   unsigned int single_ref[REF_CONTEXTS][SINGLE_REFS-1][2];
@@ -162,6 +172,10 @@ extern const vpx_prob vp10_default_palette_uv_color_prob
 
 extern const vpx_tree_index vp10_intra_mode_tree[TREE_SIZE(INTRA_MODES)];
 extern const vpx_tree_index vp10_inter_mode_tree[TREE_SIZE(INTER_MODES)];
+#if CONFIG_EXT_INTER
+extern const vpx_tree_index vp10_inter_compound_mode_tree
+                            [TREE_SIZE(INTER_COMPOUND_MODES)];
+#endif  // CONFIG_EXT_INTER
 extern const vpx_tree_index vp10_partition_tree[TREE_SIZE(PARTITION_TYPES)];
 extern const vpx_tree_index vp10_switchable_interp_tree
                                 [TREE_SIZE(SWITCHABLE_FILTERS)];
index 5b4d1c5ecd15ab205b23d45be6a30c446e56af63..fdcde99e6b07dfc702650d0a518c2d92f74fbcb3 100644 (file)
@@ -179,7 +179,16 @@ typedef enum {
 #define NEWMV     13
 #if CONFIG_EXT_INTER
 #define NEWFROMNEARMV     14
-#define MB_MODE_COUNT     15
+#define NEAREST_NEARESTMV 15
+#define NEAREST_NEARMV    16
+#define NEAR_NEARESTMV    17
+#define NEAREST_NEWMV     18
+#define NEW_NEARESTMV     19
+#define NEAR_NEWMV        20
+#define NEW_NEARMV        21
+#define ZERO_ZEROMV       22
+#define NEW_NEWMV         23
+#define MB_MODE_COUNT     24
 #else
 #define MB_MODE_COUNT 14
 #endif  // CONFIG_EXT_INTER
@@ -212,6 +221,10 @@ typedef enum {
 #define INTER_MODES (1 + NEWMV - NEARESTMV)
 #endif  // CONFIG_EXT_INTER
 
+#if CONFIG_EXT_INTER
+#define INTER_COMPOUND_MODES (1 + NEW_NEWMV - NEAREST_NEARESTMV)
+#endif  // CONFIG_EXT_INTER
+
 #define SKIP_CONTEXTS 3
 
 #if CONFIG_REF_MV
index 380312e6c5d139b0a851cf64cb00ad2f537f9f3d..a4845339d714e9bb7da2d0d9c93fae2e8deba7fd 100644 (file)
@@ -210,7 +210,8 @@ 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_EXT_INTER
-  , 1                            // NEWFROMNEARMV mode
+  , 1,                           // NEWFROMNEARMV mode
+  1, 1, 1, 1, 1, 1, 1, 0, 1      // INTER_COMPOUND_MODES (ZERO_ZEROMV == 0)
 #endif  // CONFIG_EXT_INTER
 };
 
index 89cd8bbb89008f21104143f9d84fc5928146b0b1..53394e94d0f054e0f34b40a2e5a4aae31878b8b2 100644 (file)
@@ -41,7 +41,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
           ref_mv_stack[index].weight = 2 * weight;
           ++(*refmv_count);
 
+#if CONFIG_EXT_INTER
+          if (candidate->mode == NEWMV || candidate->mode == NEWFROMNEARMV)
+#else
           if (candidate->mode == NEWMV)
+#endif  // CONFIG_EXT_INTER
             ++newmv_count;
         }
 
@@ -62,7 +66,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
             ref_mv_stack[index].weight = weight;
             ++(*refmv_count);
 
+#if CONFIG_EXT_INTER
+          if (candidate->mode == NEWMV || candidate->mode == NEWFROMNEARMV)
+#else
             if (candidate->mode == NEWMV)
+#endif  // CONFIG_EXT_INTER
               ++newmv_count;
           }
         }
@@ -92,7 +100,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
         ref_mv_stack[index].weight = 2 * weight;
         ++(*refmv_count);
 
+#if CONFIG_EXT_INTER
+        if (candidate->mode == NEW_NEWMV)
+#else
         if (candidate->mode == NEWMV)
+#endif  // CONFIG_EXT_INTER
           ++newmv_count;
       }
 
@@ -116,7 +128,11 @@ static uint8_t add_ref_mv_candidate(const MODE_INFO *const candidate_mi,
           ref_mv_stack[index].weight = weight;
           ++(*refmv_count);
 
+#if CONFIG_EXT_INTER
+          if (candidate->mode == NEW_NEWMV)
+#else
           if (candidate->mode == NEWMV)
+#endif  // CONFIG_EXT_INTER
             ++newmv_count;
         }
       }
@@ -664,6 +680,9 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
 #if CONFIG_REF_MV
                       uint8_t *ref_mv_count,
                       CANDIDATE_MV *ref_mv_stack,
+#if CONFIG_EXT_INTER
+                      int16_t *compound_mode_context,
+#endif  // CONFIG_EXT_INTER
 #endif
                       int_mv *mv_ref_list,
                       int mi_row, int mi_col,
@@ -674,7 +693,12 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
 #endif
 #if CONFIG_EXT_INTER
   vp10_update_mv_context(cm, xd, mi, ref_frame, mv_ref_list, -1,
-                         mi_row, mi_col, mode_context);
+                         mi_row, mi_col,
+#if CONFIG_REF_MV
+                         compound_mode_context);
+#else
+                         mode_context);
+#endif  // CONFIG_REF_MV
   find_mv_refs_idx(cm, xd, mi, ref_frame, mv_ref_list, -1,
                    mi_row, mi_col, sync, data, NULL);
 #else
index c1ddc959bfec6f6f99094aa08374d8cc5e3c9c3a..4187247e7d74ecccf9e7ceef1be96371e0c4410a 100644 (file)
@@ -57,6 +57,15 @@ static const int mode_2_counter[MB_MODE_COUNT] = {
   1,  // NEWMV
 #if CONFIG_EXT_INTER
   1,  // NEWFROMNEARMV
+  0,  // NEAREST_NEARESTMV
+  0,  // NEAREST_NEARMV
+  0,  // NEAR_NEARESTMV
+  1,  // NEAREST_NEWMV
+  1,  // NEW_NEARESTMV
+  1,  // NEAR_NEWMV
+  1,  // NEW_NEARMV
+  3,  // ZERO_ZEROMV
+  1,  // NEW_NEWMV
 #endif  // CONFIG_EXT_INTER
 };
 
@@ -255,6 +264,9 @@ void vp10_find_mv_refs(const VP10_COMMON *cm, const MACROBLOCKD *xd,
 #if CONFIG_REF_MV
                        uint8_t *ref_mv_count,
                        CANDIDATE_MV *ref_mv_stack,
+#if CONFIG_EXT_INTER
+                       int16_t *compound_mode_context,
+#endif  // CONFIG_EXT_INTER
 #endif
                        int_mv *mv_ref_list, int mi_row, int mi_col,
                        find_mv_refs_sync sync, void *const data,
index c9cc343462da0b916cc865d049e9299ae4eaf68d..be8b9d1ea744dc2844397836dacd9bc70cb04f65 100644 (file)
@@ -389,6 +389,13 @@ void vp10_accumulate_frame_counts(VP10_COMMON *cm, FRAME_COUNTS *counts,
     for (j = 0; j < INTER_MODES; j++)
       cm->counts.inter_mode[i][j] += counts->inter_mode[i][j];
 
+#if CONFIG_EXT_INTER
+  for (i = 0; i < INTER_MODE_CONTEXTS; i++)
+    for (j = 0; j < INTER_COMPOUND_MODES; j++)
+      cm->counts.inter_compound_mode[i][j] +=
+          counts->inter_compound_mode[i][j];
+#endif  // CONFIG_EXT_INTER
+
   for (i = 0; i < INTRA_INTER_CONTEXTS; i++)
     for (j = 0; j < 2; j++)
       cm->counts.intra_inter[i][j] += counts->intra_inter[i][j];
index 33e8332eaf09984c0f3b8c3a10fd96e33d636f72..0ed16f12fca628e7ffc800c7630556626eca3b03 100644 (file)
@@ -143,6 +143,19 @@ static void read_inter_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
 #endif
 }
 
+#if CONFIG_EXT_INTER
+static void read_inter_compound_mode_probs(FRAME_CONTEXT *fc, vpx_reader *r) {
+  int i, j;
+  if (vpx_read(r, GROUP_DIFF_UPDATE_PROB)) {
+    for (j = 0; j < INTER_MODE_CONTEXTS; ++j) {
+      for (i = 0; i < INTER_COMPOUND_MODES - 1; ++i) {
+        vp10_diff_update_prob(r, &fc->inter_compound_mode_probs[j][i]);
+      }
+    }
+  }
+}
+#endif  // CONFIG_EXT_INTER
+
 static REFERENCE_MODE read_frame_reference_mode(const VP10_COMMON *cm,
     struct vpx_read_bit_buffer *rb) {
   if (is_compound_reference_allowed(cm)) {
@@ -3259,6 +3272,10 @@ static int read_compressed_header(VP10Decoder *pbi, const uint8_t *data,
 
     read_inter_mode_probs(fc, &r);
 
+#if CONFIG_EXT_INTER
+    read_inter_compound_mode_probs(fc, &r);
+#endif  // CONFIG_EXT_INTER
+
     if (cm->interp_filter == SWITCHABLE)
       read_switchable_interp_probs(fc, &r);
 
@@ -3308,6 +3325,11 @@ static void debug_check_frame_counts(const VP10_COMMON *const cm) {
                  sizeof(cm->counts.switchable_interp)));
   assert(!memcmp(cm->counts.inter_mode, zero_counts.inter_mode,
                  sizeof(cm->counts.inter_mode)));
+#if CONFIG_EXT_INTER
+  assert(!memcmp(cm->counts.inter_compound_mode,
+                 zero_counts.inter_compound_mode,
+                 sizeof(cm->counts.inter_compound_mode)));
+#endif  // CONFIG_EXT_INTER
   assert(!memcmp(cm->counts.intra_inter, zero_counts.intra_inter,
                  sizeof(cm->counts.intra_inter)));
   assert(!memcmp(cm->counts.comp_inter, zero_counts.comp_inter,
index d7c3faf0ec8fb2a53ed586d48ab00f09884990d7..8f6d51080b84e7eb28a223e8f6d4980284ef8af7 100644 (file)
@@ -147,6 +147,22 @@ static PREDICTION_MODE read_inter_mode(VP10_COMMON *cm, MACROBLOCKD *xd,
 #endif
 }
 
+#if CONFIG_EXT_INTER
+static PREDICTION_MODE read_inter_compound_mode(VP10_COMMON *cm,
+                                                MACROBLOCKD *xd,
+                                                vpx_reader *r, int16_t ctx) {
+  const int mode = vpx_read_tree(r, vp10_inter_compound_mode_tree,
+                                 cm->fc->inter_compound_mode_probs[ctx]);
+  FRAME_COUNTS *counts = xd->counts;
+
+  if (counts)
+    ++counts->inter_compound_mode[ctx][mode];
+
+  assert(is_inter_compound_mode(NEAREST_NEARESTMV + mode));
+  return NEAREST_NEARESTMV + mode;
+}
+#endif  // CONFIG_EXT_INTER
+
 static int read_segment_id(vpx_reader *r,
     const struct segmentation_probs *segp) {
   return vpx_read_tree(r, vp10_segment_tree, segp->tree_probs);
@@ -826,6 +842,83 @@ static INLINE int assign_mv(VP10_COMMON *cm, MACROBLOCKD *xd,
         mv[1].as_int = 0;
       break;
     }
+#if CONFIG_EXT_INTER
+    case NEW_NEWMV: {
+      FRAME_COUNTS *counts = xd->counts;
+      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
+      assert(is_compound);
+      for (i = 0; i < 2; ++i) {
+        read_mv(r, &mv[i].as_mv, &ref_mv[i].as_mv, &cm->fc->nmvc, mv_counts,
+                allow_hp);
+        ret = ret && is_mv_valid(&mv[i].as_mv);
+      }
+      break;
+    }
+    case NEAREST_NEARESTMV: {
+      assert(is_compound);
+      mv[0].as_int = nearest_mv[0].as_int;
+      mv[1].as_int = nearest_mv[1].as_int;
+      break;
+    }
+    case NEAREST_NEARMV: {
+      assert(is_compound);
+      mv[0].as_int = nearest_mv[0].as_int;
+      mv[1].as_int = near_mv[1].as_int;
+      break;
+    }
+    case NEAR_NEARESTMV: {
+      assert(is_compound);
+      mv[0].as_int = near_mv[0].as_int;
+      mv[1].as_int = nearest_mv[1].as_int;
+      break;
+    }
+    case NEW_NEARESTMV: {
+      FRAME_COUNTS *counts = xd->counts;
+      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
+      assert(is_compound);
+      read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv, &cm->fc->nmvc, mv_counts,
+              allow_hp);
+      ret = ret && is_mv_valid(&mv[0].as_mv);
+      mv[1].as_int = nearest_mv[1].as_int;
+      break;
+    }
+    case NEAREST_NEWMV: {
+      FRAME_COUNTS *counts = xd->counts;
+      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
+      assert(is_compound);
+      mv[0].as_int = nearest_mv[0].as_int;
+      read_mv(r, &mv[1].as_mv, &ref_mv[1].as_mv, &cm->fc->nmvc, mv_counts,
+              allow_hp);
+      ret = ret && is_mv_valid(&mv[1].as_mv);
+      break;
+    }
+    case NEAR_NEWMV: {
+      FRAME_COUNTS *counts = xd->counts;
+      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
+      assert(is_compound);
+      mv[0].as_int = near_mv[0].as_int;
+      read_mv(r, &mv[1].as_mv, &ref_mv[1].as_mv, &cm->fc->nmvc, mv_counts,
+              allow_hp);
+      ret = ret && is_mv_valid(&mv[1].as_mv);
+      break;
+    }
+    case NEW_NEARMV: {
+      FRAME_COUNTS *counts = xd->counts;
+      nmv_context_counts *const mv_counts = counts ? &counts->mv : NULL;
+      assert(is_compound);
+      read_mv(r, &mv[0].as_mv, &ref_mv[0].as_mv, &cm->fc->nmvc, mv_counts,
+              allow_hp);
+      ret = ret && is_mv_valid(&mv[0].as_mv);
+      mv[1].as_int = near_mv[1].as_int;
+      break;
+    }
+    case ZERO_ZEROMV: {
+      assert(is_compound);
+      mv[0].as_int = 0;
+      mv[1].as_int = 0;
+      break;
+    }
+#endif  // CONFIG_EXT_INTER
     default: {
       return 0;
     }
@@ -868,6 +961,9 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
 #endif  // CONFIG_EXT_INTER
   int ref, is_compound;
   int16_t inter_mode_ctx[MODE_CTX_REF_FRAMES];
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+  int16_t compound_inter_mode_ctx[MODE_CTX_REF_FRAMES];
+#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
   int16_t mode_ctx = 0;
   MV_REFERENCE_FRAME ref_frame;
 
@@ -891,12 +987,20 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
 #if CONFIG_REF_MV
                       &xd->ref_mv_count[ref_frame],
                       xd->ref_mv_stack[ref_frame],
+#if CONFIG_EXT_INTER
+                      compound_inter_mode_ctx,
+#endif  // CONFIG_EXT_INTER
 #endif
                       ref_mvs[ref_frame],
                       mi_row, mi_col, fpm_sync, (void *)pbi, inter_mode_ctx);
   }
 
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+  if (is_compound)
+    mode_ctx = compound_inter_mode_ctx[mbmi->ref_frame[0]];
+  else
+#endif  // CONFIG_EXT_INTER
   mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx,
                                         mbmi->ref_frame, bsize, -1);
 #else
@@ -912,14 +1016,28 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
     }
   } else {
     if (bsize >= BLOCK_8X8)
+#if CONFIG_EXT_INTER
+    {
+      if (is_compound)
+        mbmi->mode = read_inter_compound_mode(cm, xd, r, mode_ctx);
+      else
+#endif  // CONFIG_EXT_INTER
       mbmi->mode = read_inter_mode(cm, xd,
 #if CONFIG_REF_MV && CONFIG_EXT_INTER
                                    mbmi,
 #endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
                                    r, mode_ctx);
+#if CONFIG_EXT_INTER
+    }
+#endif  // CONFIG_EXT_INTER
   }
 
+#if CONFIG_EXT_INTER
+  if (bsize < BLOCK_8X8 ||
+      (mbmi->mode != ZEROMV && mbmi->mode != ZERO_ZEROMV)) {
+#else
   if (bsize < BLOCK_8X8 || mbmi->mode != ZEROMV) {
+#endif  // CONFIG_EXT_INTER
     for (ref = 0; ref < 1 + is_compound; ++ref) {
       vp10_find_best_ref_mvs(allow_hp, ref_mvs[mbmi->ref_frame[ref]],
                              &nearestmv[ref], &nearmv[ref]);
@@ -927,19 +1045,52 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
   }
 
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+  if (is_compound && bsize >= BLOCK_8X8 && mbmi->mode != ZERO_ZEROMV) {
+#else
   if (is_compound && bsize >= BLOCK_8X8 && mbmi->mode != NEWMV &&
       mbmi->mode != ZEROMV) {
+#endif  // CONFIG_EXT_INTER
     uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
 
+#if CONFIG_EXT_INTER
+    if (xd->ref_mv_count[ref_frame_type] > 0) {
+#else
     if (xd->ref_mv_count[ref_frame_type] == 1 && mbmi->mode == NEARESTMV) {
+#endif  // CONFIG_EXT_INTER
       int i;
+#if CONFIG_EXT_INTER
+      if (mbmi->mode == NEAREST_NEARESTMV) {
+#endif  // CONFIG_EXT_INTER
       nearestmv[0] = xd->ref_mv_stack[ref_frame_type][0].this_mv;
       nearestmv[1] = xd->ref_mv_stack[ref_frame_type][0].comp_mv;
 
       for (i = 0; i < MAX_MV_REF_CANDIDATES; ++i)
         lower_mv_precision(&nearestmv[i].as_mv, allow_hp);
+#if CONFIG_EXT_INTER
+      } else if (mbmi->mode == NEAREST_NEWMV || mbmi->mode == NEAREST_NEARMV) {
+        nearestmv[0] = xd->ref_mv_stack[ref_frame_type][0].this_mv;
+        lower_mv_precision(&nearestmv[0].as_mv, allow_hp);
+      } else if (mbmi->mode == NEW_NEARESTMV || mbmi->mode == NEAR_NEARESTMV) {
+        nearestmv[1] = xd->ref_mv_stack[ref_frame_type][0].comp_mv;
+        lower_mv_precision(&nearestmv[1].as_mv, allow_hp);
+      }
+#endif  // CONFIG_EXT_INTER
     }
 
+#if CONFIG_EXT_INTER
+    if (xd->ref_mv_count[ref_frame_type] > 1) {
+      if (mbmi->mode == NEAR_NEWMV || mbmi->mode == NEAR_NEARESTMV) {
+        nearmv[0] = xd->ref_mv_stack[ref_frame_type][1].this_mv;
+        lower_mv_precision(&nearmv[0].as_mv, allow_hp);
+      }
+
+      if (mbmi->mode == NEW_NEARMV || mbmi->mode == NEAREST_NEARMV) {
+        nearmv[1] = xd->ref_mv_stack[ref_frame_type][1].comp_mv;
+        lower_mv_precision(&nearmv[1].as_mv, allow_hp);
+      }
+    }
+#else
     if (xd->ref_mv_count[ref_frame_type] > 1) {
       int i;
       nearestmv[0] = xd->ref_mv_stack[ref_frame_type][0].this_mv;
@@ -952,6 +1103,7 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
         lower_mv_precision(&nearmv[i].as_mv, allow_hp);
       }
     }
+#endif  // CONFIG_EXT_INTER
   }
 #endif
 
@@ -975,9 +1127,17 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
         int_mv block[2];
         const int j = idy * 2 + idx;
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+        if (!is_compound)
+#endif  // CONFIG_EXT_INTER
         mode_ctx = vp10_mode_context_analyzer(inter_mode_ctx,  mbmi->ref_frame,
                                               bsize, j);
 #endif
+#if CONFIG_EXT_INTER
+        if (is_compound)
+          b_mode = read_inter_compound_mode(cm, xd, r, mode_ctx);
+        else
+#endif  // CONFIG_EXT_INTER
         b_mode = read_inter_mode(cm, xd,
 #if CONFIG_REF_MV && CONFIG_EXT_INTER
                                  mbmi,
@@ -987,7 +1147,7 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
 #if CONFIG_EXT_INTER
         mv_idx = (b_mode == NEWFROMNEARMV) ? 1 : 0;
 
-        if (b_mode != ZEROMV) {
+        if (b_mode != ZEROMV && b_mode != ZERO_ZEROMV) {
 #else
         if (b_mode == NEARESTMV || b_mode == NEARMV) {
 #endif  // CONFIG_EXT_INTER
@@ -1000,7 +1160,7 @@ static void read_inter_block_mode_info(VP10Decoder *const pbi,
 #endif  // CONFIG_EXT_INTER
             vp10_append_sub8x8_mvs_for_idx(cm, xd, j, ref, mi_row, mi_col,
 #if CONFIG_EXT_INTER
-                                          mv_ref_list,
+                                           mv_ref_list,
 #endif  // CONFIG_EXT_INTER
                                           &nearest_sub8x8[ref],
                                           &near_sub8x8[ref]);
index 098c86a50c8496b71fbda18f4e89534a02c6d758..48c256496d334194e73e9ed745ac4a34b305a8b1 100644 (file)
@@ -55,6 +55,13 @@ static const struct vp10_token inter_mode_encodings[INTER_MODES] =
   {{2, 2}, {6, 3}, {0, 1}, {7, 3}};
 #endif  // CONFIG_EXT_INTER
 #endif
+#if CONFIG_EXT_INTER
+static const struct vp10_token inter_compound_mode_encodings
+                               [INTER_COMPOUND_MODES] = {
+  {2, 2}, {24, 5}, {25, 5}, {52, 6}, {53, 6},
+  {54, 6}, {55, 6}, {0, 1}, {7, 3}
+};
+#endif  // CONFIG_EXT_INTER
 static const struct vp10_token palette_size_encodings[] = {
     {0, 1}, {2, 2}, {6, 3}, {14, 4}, {30, 5}, {62, 6}, {63, 6},
 };
@@ -173,6 +180,19 @@ static void write_inter_mode(VP10_COMMON *cm,
 #endif
 }
 
+#if CONFIG_EXT_INTER
+static void write_inter_compound_mode(VP10_COMMON *cm, vpx_writer *w,
+                                      PREDICTION_MODE mode,
+                                      const int16_t mode_ctx) {
+  const vpx_prob *const inter_compound_probs =
+                        cm->fc->inter_compound_mode_probs[mode_ctx];
+
+  assert(is_inter_compound_mode(mode));
+  vp10_write_token(w, vp10_inter_compound_mode_tree, inter_compound_probs,
+                  &inter_compound_mode_encodings[INTER_COMPOUND_OFFSET(mode)]);
+}
+#endif  // CONFIG_EXT_INTER
+
 static void encode_unsigned_max(struct vpx_write_bit_buffer *wb,
                                 int data, int max) {
   vpx_wb_write_literal(wb, data, get_unsigned_bits(max));
@@ -302,6 +322,32 @@ static void update_inter_mode_probs(VP10_COMMON *cm, vpx_writer *w,
 }
 #endif
 
+#if CONFIG_EXT_INTER
+static void update_inter_compound_mode_probs(VP10_COMMON *cm, vpx_writer *w) {
+  const int savings_thresh = vp10_cost_one(GROUP_DIFF_UPDATE_PROB) -
+                             vp10_cost_zero(GROUP_DIFF_UPDATE_PROB);
+  int i;
+  int savings = 0;
+  int do_update = 0;
+  for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
+    savings += prob_diff_update_savings(vp10_inter_compound_mode_tree,
+                                        cm->fc->inter_compound_mode_probs[i],
+                                        cm->counts.inter_compound_mode[i],
+                                        INTER_COMPOUND_MODES);
+  }
+  do_update = savings > savings_thresh;
+  vpx_write(w, do_update, GROUP_DIFF_UPDATE_PROB);
+  if (do_update) {
+    for (i = 0; i < INTER_MODE_CONTEXTS; ++i) {
+      prob_diff_update(vp10_inter_compound_mode_tree,
+                       cm->fc->inter_compound_mode_probs[i],
+                       cm->counts.inter_compound_mode[i],
+                       INTER_COMPOUND_MODES, w);
+    }
+  }
+}
+#endif  // CONFIG_EXT_INTER
+
 static int write_skip(const VP10_COMMON *cm, const MACROBLOCKD *xd,
                       int segment_id, const MODE_INFO *mi, vpx_writer *w) {
   if (segfeature_active(&cm->seg, segment_id, SEG_LVL_SKIP)) {
@@ -793,8 +839,6 @@ static void write_switchable_interp_filter(VP10_COMP *cpi,
     const int ctx = vp10_get_pred_context_switchable_interp(xd);
 #if CONFIG_EXT_INTERP
     if (!vp10_is_interp_needed(xd)) {
-      // if (mbmi->interp_filter != EIGHTTAP)
-      //   printf("Error [%d]\n", mbmi->sb_type);
       assert(mbmi->interp_filter == EIGHTTAP);
       return;
     }
@@ -919,6 +963,11 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
     write_ref_frames(cm, xd, w);
 
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+    if (is_compound)
+      mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
+    else
+#endif  // CONFIG_EXT_INTER
     mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
                                           mbmi->ref_frame, bsize, -1);
 #endif
@@ -926,6 +975,11 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
     // If segment skip is not enabled code the mode.
     if (!segfeature_active(seg, segment_id, SEG_LVL_SKIP)) {
       if (bsize >= BLOCK_8X8) {
+#if CONFIG_EXT_INTER
+        if (is_inter_compound_mode(mode))
+          write_inter_compound_mode(cm, w, mode, mode_ctx);
+        else if (is_inter_singleref_mode(mode))
+#endif  // CONFIG_EXT_INTER
         write_inter_mode(cm, w, mode,
 #if CONFIG_REF_MV && CONFIG_EXT_INTER
                          has_second_ref(mbmi),
@@ -947,9 +1001,17 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
           const int j = idy * 2 + idx;
           const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+          if (!is_compound)
+#endif  // CONFIG_EXT_INTER
           mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
                                                 mbmi->ref_frame, bsize, j);
 #endif
+#if CONFIG_EXT_INTER
+          if (is_inter_compound_mode(b_mode))
+            write_inter_compound_mode(cm, w, b_mode, mode_ctx);
+          else if (is_inter_singleref_mode(b_mode))
+#endif  // CONFIG_EXT_INTER
           write_inter_mode(cm, w, b_mode,
 #if CONFIG_REF_MV && CONFIG_EXT_INTER
                            has_second_ref(mbmi),
@@ -957,7 +1019,8 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
                            mode_ctx);
 
 #if CONFIG_EXT_INTER
-          if (b_mode == NEWMV || b_mode == NEWFROMNEARMV) {
+          if (b_mode == NEWMV || b_mode == NEWFROMNEARMV ||
+              b_mode == NEW_NEWMV) {
 #else
           if (b_mode == NEWMV) {
 #endif  // CONFIG_EXT_INTER
@@ -970,11 +1033,20 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
 #endif  // CONFIG_EXT_INTER
                             nmvc, allow_hp);
           }
+#if CONFIG_EXT_INTER
+          else if (b_mode == NEAREST_NEWMV || b_mode == NEAR_NEWMV) {
+            vp10_encode_mv(cpi, w, &mi->bmi[j].as_mv[1].as_mv,
+                           &mi->bmi[j].ref_mv[1].as_mv, nmvc, allow_hp);
+          } else if (b_mode == NEW_NEARESTMV || b_mode == NEW_NEARMV) {
+            vp10_encode_mv(cpi, w, &mi->bmi[j].as_mv[0].as_mv,
+                           &mi->bmi[j].ref_mv[0].as_mv, nmvc, allow_hp);
+          }
+#endif  // CONFIG_EXT_INTER
         }
       }
     } else {
 #if CONFIG_EXT_INTER
-      if (mode == NEWMV || mode == NEWFROMNEARMV) {
+      if (mode == NEWMV || mode == NEWFROMNEARMV || mode == NEW_NEWMV) {
 #else
       if (mode == NEWMV) {
 #endif  // CONFIG_EXT_INTER
@@ -992,6 +1064,14 @@ static void pack_inter_mode_mvs(VP10_COMP *cpi, const MODE_INFO *mi,
                         allow_hp);
 #if CONFIG_EXT_INTER
         }
+      } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
+        vp10_encode_mv(cpi, w, &mbmi->mv[1].as_mv,
+                       &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv, nmvc,
+                       allow_hp);
+      } else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) {
+        vp10_encode_mv(cpi, w, &mbmi->mv[0].as_mv,
+                       &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv, nmvc,
+                       allow_hp);
 #endif  // CONFIG_EXT_INTER
       }
     }
@@ -2212,6 +2292,10 @@ static size_t write_compressed_header(VP10_COMP *cpi, uint8_t *data) {
                        counts->inter_mode[i], INTER_MODES, &header_bc);
 #endif
 
+#if CONFIG_EXT_INTER
+    update_inter_compound_mode_probs(cm, &header_bc);
+#endif  // CONFIG_EXT_INTER
+
     if (cm->interp_filter == SWITCHABLE)
       update_switchable_interp_probs(cm, &header_bc, counts);
 
index 597f0d7d68ef98cb06d750d4705d9d1813b5f1ef..3e322decdeee9017067a238cb29efb6efb32bcd8 100644 (file)
@@ -56,6 +56,9 @@ typedef struct {
 #if CONFIG_REF_MV
   uint8_t ref_mv_count[MODE_CTX_REF_FRAMES];
   CANDIDATE_MV ref_mv_stack[MODE_CTX_REF_FRAMES][MAX_REF_MV_STACK_SIZE];
+#if CONFIG_EXT_INTER
+  int16_t compound_mode_context[MODE_CTX_REF_FRAMES];
+#endif  // CONFIG_EXT_INTER
 #endif
 } MB_MODE_INFO_EXT;
 
index 43647b0f4d530e23bd6980c08d4f8219063ce762..e876676533d13933dc5b0f9b9ca2b07570ec0b3d 100644 (file)
@@ -230,9 +230,19 @@ static VP9_DENOISER_DECISION perform_motion_compensation(VP9_DENOISER *denoiser,
     frame = ctx->best_zeromv_reference_frame;
 
     mbmi->ref_frame[0] = ctx->best_zeromv_reference_frame;
+#if CONFIG_EXT_INTER
+    if (has_second_ref(mbmi))
+      mbmi->mode = ZERO_ZEROMV;
+    else
+#endif  // CONFIG_EXT_INTER
     mbmi->mode = ZEROMV;
     mbmi->mv[0].as_int = 0;
 
+#if CONFIG_EXT_INTER
+    if (has_second_ref(mbmi))
+      ctx->best_sse_inter_mode = ZERO_ZEROMV;
+    else
+#endif  // CONFIG_EXT_INTER
     ctx->best_sse_inter_mode = ZEROMV;
     ctx->best_sse_mv.as_int = 0;
     ctx->newmv_sse = ctx->zeromv_sse;
index 52926e35eb9762ef45b2866884ac7f37e861566c..8c75287f408d77870d836fef5eddbbbea94cd7c4 100644 (file)
@@ -1796,6 +1796,12 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
       if (bsize >= BLOCK_8X8) {
         const PREDICTION_MODE mode = mbmi->mode;
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+        if (has_second_ref(mbmi)) {
+          mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
+          ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
+        } else {
+#endif  // CONFIG_EXT_INTER
         mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
                                               mbmi->ref_frame, bsize, -1);
         update_inter_mode_stats(counts, mode,
@@ -1803,8 +1809,15 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
                                 has_second_ref(mbmi),
 #endif  // CONFIG_EXT_INTER
                                 mode_ctx);
-
+#if CONFIG_EXT_INTER
+        }
+#endif  // CONFIG_EXT_INTER
 #else
+#if CONFIG_EXT_INTER
+        if (is_inter_compound_mode(mode))
+          ++counts->inter_compound_mode[mode_ctx][INTER_COMPOUND_OFFSET(mode)];
+        else
+#endif  // CONFIG_EXT_INTER
         ++counts->inter_mode[mode_ctx][INTER_OFFSET(mode)];
 #endif
       } else {
@@ -1816,6 +1829,13 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
             const int j = idy * 2 + idx;
             const PREDICTION_MODE b_mode = mi->bmi[j].as_mode;
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+          if (has_second_ref(mbmi)) {
+            mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
+            ++counts->inter_compound_mode[mode_ctx]
+                                         [INTER_COMPOUND_OFFSET(b_mode)];
+          } else {
+#endif  // CONFIG_EXT_INTER
             mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
                                                   mbmi->ref_frame, bsize, j);
             update_inter_mode_stats(counts, b_mode,
@@ -1823,7 +1843,16 @@ static void update_stats(VP10_COMMON *cm, ThreadData *td
                                     has_second_ref(mbmi),
 #endif  // CONFIG_EXT_INTER
                                     mode_ctx);
+#if CONFIG_EXT_INTER
+            }
+#endif  // CONFIG_EXT_INTER
 #else
+#if CONFIG_EXT_INTER
+            if (is_inter_compound_mode(b_mode))
+              ++counts->inter_compound_mode[mode_ctx]
+                                           [INTER_COMPOUND_OFFSET(b_mode)];
+            else
+#endif  // CONFIG_EXT_INTER
             ++counts->inter_mode[mode_ctx][INTER_OFFSET(b_mode)];
 #endif
           }
index 0184bae9de0343d9b5b8db104cf7e747e84b5078..4124c4ac28c2c83e64318e0af6bf71b756d0d6f1 100644 (file)
@@ -232,13 +232,23 @@ static void inc_mvs(const MB_MODE_INFO *mbmi, const MB_MODE_INFO_EXT *mbmi_ext,
   PREDICTION_MODE mode = mbmi->mode;
   int mv_idx = (mode == NEWFROMNEARMV);
 
-  if (mode == NEWMV || mode == NEWFROMNEARMV) {
+  if (mode == NEWMV || mode == NEWFROMNEARMV || mode == NEW_NEWMV) {
     for (i = 0; i < 1 + has_second_ref(mbmi); ++i) {
       const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[i]][mv_idx].as_mv;
       const MV diff = {mvs[i].as_mv.row - ref->row,
                        mvs[i].as_mv.col - ref->col};
       vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
     }
+  } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
+    const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[1]][0].as_mv;
+    const MV diff = {mvs[1].as_mv.row - ref->row,
+                     mvs[1].as_mv.col - ref->col};
+    vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
+  } else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) {
+    const MV *ref = &mbmi_ext->ref_mvs[mbmi->ref_frame[0]][0].as_mv;
+    const MV diff = {mvs[0].as_mv.row - ref->row,
+                     mvs[0].as_mv.col - ref->col};
+    vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
   }
 }
 
@@ -249,13 +259,23 @@ static void inc_mvs_sub8x8(const MODE_INFO *mi,
   int i;
   PREDICTION_MODE mode = mi->bmi[block].as_mode;
 
-  if (mode == NEWMV || mode == NEWFROMNEARMV) {
+  if (mode == NEWMV || mode == NEWFROMNEARMV || mode == NEW_NEWMV) {
     for (i = 0; i < 1 + has_second_ref(&mi->mbmi); ++i) {
       const MV *ref = &mi->bmi[block].ref_mv[i].as_mv;
       const MV diff = {mvs[i].as_mv.row - ref->row,
                        mvs[i].as_mv.col - ref->col};
       vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
     }
+  } else if (mode == NEAREST_NEWMV || mode == NEAR_NEWMV) {
+    const MV *ref = &mi->bmi[block].ref_mv[1].as_mv;
+    const MV diff = {mvs[1].as_mv.row - ref->row,
+                     mvs[1].as_mv.col - ref->col};
+    vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
+  } else if (mode == NEW_NEARESTMV || mode == NEW_NEARMV) {
+    const MV *ref = &mi->bmi[block].ref_mv[0].as_mv;
+    const MV diff = {mvs[0].as_mv.row - ref->row,
+                     mvs[0].as_mv.col - ref->col};
+    vp10_inc_mv(&diff, counts, vp10_use_mv_hp(ref));
   }
 }
 #else
index 797abacafa64a62a99e4898576fddd5b32f60c4c..d5c432f8dfd14d757a985706b2b68d68d54651ea 100644 (file)
@@ -482,6 +482,10 @@ typedef struct VP10_COMP {
 #endif
 
   unsigned int inter_mode_cost[INTER_MODE_CONTEXTS][INTER_MODES];
+#if CONFIG_EXT_INTER
+  unsigned int inter_compound_mode_cost[INTER_MODE_CONTEXTS]
+                                       [INTER_COMPOUND_MODES];
+#endif  // CONFIG_EXT_INTER
   int intra_uv_mode_cost[INTRA_MODES][INTRA_MODES];
   int y_mode_costs[INTRA_MODES][INTRA_MODES][INTRA_MODES];
   int switchable_interp_costs[SWITCHABLE_FILTER_CONTEXTS][SWITCHABLE_FILTERS];
index ed0f53909f55abfb83f532056c28ee0494d38a34..ab1e60f0e8a7ff8570ccec93b5616638c2af0e3c 100644 (file)
@@ -67,6 +67,11 @@ static unsigned int do_16x16_motion_iteration(VP10_COMP *cpi,
         &distortion, &sse, NULL, 0, 0);
   }
 
+#if CONFIG_EXT_INTER
+  if (has_second_ref(&xd->mi[0]->mbmi))
+    xd->mi[0]->mbmi.mode = NEW_NEWMV;
+  else
+#endif  // CONFIG_EXT_INTER
   xd->mi[0]->mbmi.mode = NEWMV;
   xd->mi[0]->mbmi.mv[0].as_mv = *dst_mv;
 
index d67f7c388e964f1b65a0a10184dd861b67440f81..9dede8ee1f5c32f360e42a67a5df05e2e5f5faa0 100644 (file)
@@ -386,6 +386,12 @@ void vp10_initialize_rd_consts(VP10_COMP *cpi) {
       vp10_cost_tokens((int *)cpi->inter_mode_cost[i],
                       cm->fc->inter_mode_probs[i], vp10_inter_mode_tree);
 #endif
+#if CONFIG_EXT_INTER
+    for (i = 0; i < INTER_MODE_CONTEXTS; ++i)
+      vp10_cost_tokens((int *)cpi->inter_compound_mode_cost[i],
+                       cm->fc->inter_compound_mode_probs[i],
+                       vp10_inter_compound_mode_tree);
+#endif  // CONFIG_EXT_INTER
   }
 }
 
@@ -692,11 +698,11 @@ void vp10_set_rd_speed_thresholds(VP10_COMP *cpi) {
 
 #if CONFIG_EXT_INTER
   rd->thresh_mult[THR_NEWFROMNEARMV] += 1000;
-#if CONFIG_EXT_REF
+#if CONFIG_EXT_REFS
   rd->thresh_mult[THR_NEWFROMNEARL2] += 1000;
   rd->thresh_mult[THR_NEWFROMNEARL3] += 1000;
   rd->thresh_mult[THR_NEWFROMNEARL4] += 1000;
-#endif  // CONFIG_EXT_REF
+#endif  // CONFIG_EXT_REFS
   rd->thresh_mult[THR_NEWFROMNEARG] += 1000;
   rd->thresh_mult[THR_NEWFROMNEARA] += 1000;
 #endif  // CONFIG_EXT_INTER
@@ -712,6 +718,59 @@ void vp10_set_rd_speed_thresholds(VP10_COMP *cpi) {
 
   rd->thresh_mult[THR_TM] += 1000;
 
+#if CONFIG_EXT_INTER
+  rd->thresh_mult[THR_COMP_NEAREST_NEARESTLA] += 1000;
+  rd->thresh_mult[THR_COMP_NEAREST_NEARESTGA] += 1000;
+  rd->thresh_mult[THR_COMP_NEAREST_NEARLA] += 1200;
+  rd->thresh_mult[THR_COMP_NEAREST_NEARGA] += 1200;
+  rd->thresh_mult[THR_COMP_NEAR_NEARESTLA] += 1200;
+  rd->thresh_mult[THR_COMP_NEAR_NEARESTGA] += 1200;
+  rd->thresh_mult[THR_COMP_NEAREST_NEWLA] += 1500;
+  rd->thresh_mult[THR_COMP_NEAREST_NEWGA] += 1500;
+  rd->thresh_mult[THR_COMP_NEW_NEARESTLA] += 1500;
+  rd->thresh_mult[THR_COMP_NEW_NEARESTGA] += 1500;
+  rd->thresh_mult[THR_COMP_NEAR_NEWLA] += 1700;
+  rd->thresh_mult[THR_COMP_NEAR_NEWGA] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEARLA] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEARGA] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEWLA] += 2000;
+  rd->thresh_mult[THR_COMP_NEW_NEWGA] += 2000;
+  rd->thresh_mult[THR_COMP_ZERO_ZEROLA] += 2500;
+  rd->thresh_mult[THR_COMP_ZERO_ZEROGA] += 2500;
+
+#if CONFIG_EXT_REFS
+  rd->thresh_mult[THR_COMP_NEAREST_NEARESTL2A] += 1000;
+  rd->thresh_mult[THR_COMP_NEAREST_NEARL2A] += 1200;
+  rd->thresh_mult[THR_COMP_NEAR_NEARESTL2A] += 1200;
+  rd->thresh_mult[THR_COMP_NEAREST_NEWL2A] += 1500;
+  rd->thresh_mult[THR_COMP_NEW_NEARESTL2A] += 1500;
+  rd->thresh_mult[THR_COMP_NEAR_NEWL2A] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEARL2A] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEWL2A] += 2000;
+  rd->thresh_mult[THR_COMP_ZERO_ZEROL2A] += 2500;
+
+  rd->thresh_mult[THR_COMP_NEAREST_NEARESTL3A] += 1000;
+  rd->thresh_mult[THR_COMP_NEAREST_NEARL3A] += 1200;
+  rd->thresh_mult[THR_COMP_NEAR_NEARESTL3A] += 1200;
+  rd->thresh_mult[THR_COMP_NEAREST_NEWL3A] += 1500;
+  rd->thresh_mult[THR_COMP_NEW_NEARESTL3A] += 1500;
+  rd->thresh_mult[THR_COMP_NEAR_NEWL3A] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEARL3A] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEWL3A] += 2000;
+  rd->thresh_mult[THR_COMP_ZERO_ZEROL3A] += 2500;
+
+  rd->thresh_mult[THR_COMP_NEAREST_NEARESTL4A] += 1000;
+  rd->thresh_mult[THR_COMP_NEAREST_NEARL4A] += 1200;
+  rd->thresh_mult[THR_COMP_NEAR_NEARESTL4A] += 1200;
+  rd->thresh_mult[THR_COMP_NEAREST_NEWL4A] += 1500;
+  rd->thresh_mult[THR_COMP_NEW_NEARESTL4A] += 1500;
+  rd->thresh_mult[THR_COMP_NEAR_NEWL4A] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEARL4A] += 1700;
+  rd->thresh_mult[THR_COMP_NEW_NEWL4A] += 2000;
+  rd->thresh_mult[THR_COMP_ZERO_ZEROL4A] += 2500;
+
+#endif  // CONFIG_EXT_REFS
+#else
   rd->thresh_mult[THR_COMP_NEARESTLA] += 1000;
 #if CONFIG_EXT_REFS
   rd->thresh_mult[THR_COMP_NEARESTL2A] += 1000;
@@ -740,6 +799,7 @@ void vp10_set_rd_speed_thresholds(VP10_COMP *cpi) {
   rd->thresh_mult[THR_COMP_ZEROL4A] += 2500;
 #endif  // CONFIG_EXT_REFS
   rd->thresh_mult[THR_COMP_ZEROGA] += 2500;
+#endif  // CONFIG_EXT_INTER
 
   rd->thresh_mult[THR_H_PRED] += 2000;
   rd->thresh_mult[THR_V_PRED] += 2000;
index 2b6106d955e6384782ca52fe0af7021761cd6d45..2303c200552134e7b48e1ca589d3c7fd8ffa4e72 100644 (file)
@@ -39,13 +39,13 @@ extern "C" {
 
 #if CONFIG_EXT_REFS
 #if CONFIG_EXT_INTER
-#define MAX_MODES 60
+#define MAX_MODES 85
 #else
 #define MAX_MODES 54
 #endif  // CONFIG_EXT_INTER
 #else
 #if CONFIG_EXT_INTER
-#define MAX_MODES 33
+#define MAX_MODES 43
 #else
 #define MAX_MODES 30
 #endif  // CONFIG_EXT_INTER
@@ -94,11 +94,11 @@ typedef enum {
 
 #if CONFIG_EXT_INTER
   THR_NEWFROMNEARMV,
-#if CONFIG_EXT_REF
+#if CONFIG_EXT_REFS
   THR_NEWFROMNEARL2,
   THR_NEWFROMNEARL3,
   THR_NEWFROMNEARL4,
-#endif  // CONFIG_EXT_REF
+#endif  // CONFIG_EXT_REFS
   THR_NEWFROMNEARA,
   THR_NEWFROMNEARG,
 #endif  // CONFIG_EXT_INTER
@@ -112,6 +112,15 @@ typedef enum {
   THR_ZEROG,
   THR_ZEROA,
 
+#if CONFIG_EXT_INTER
+  THR_COMP_NEAREST_NEARESTLA,
+#if CONFIG_EXT_REFS
+  THR_COMP_NEAREST_NEARESTL2A,
+  THR_COMP_NEAREST_NEARESTL3A,
+  THR_COMP_NEAREST_NEARESTL4A,
+#endif  // CONFIG_EXT_REFS
+  THR_COMP_NEAREST_NEARESTGA,
+#else  // CONFIG_EXT_INTER
   THR_COMP_NEARESTLA,
 #if CONFIG_EXT_REFS
   THR_COMP_NEARESTL2A,
@@ -119,9 +128,57 @@ typedef enum {
   THR_COMP_NEARESTL4A,
 #endif  // CONFIG_EXT_REFS
   THR_COMP_NEARESTGA,
+#endif  // CONFIG_EXT_INTER
 
   THR_TM,
 
+#if CONFIG_EXT_INTER
+  THR_COMP_NEAR_NEARESTLA,
+  THR_COMP_NEAR_NEARESTGA,
+  THR_COMP_NEAREST_NEARLA,
+  THR_COMP_NEAREST_NEARGA,
+  THR_COMP_NEW_NEARESTLA,
+  THR_COMP_NEW_NEARESTGA,
+  THR_COMP_NEAREST_NEWLA,
+  THR_COMP_NEAREST_NEWGA,
+  THR_COMP_NEW_NEARLA,
+  THR_COMP_NEW_NEARGA,
+  THR_COMP_NEAR_NEWLA,
+  THR_COMP_NEAR_NEWGA,
+  THR_COMP_NEW_NEWLA,
+  THR_COMP_NEW_NEWGA,
+  THR_COMP_ZERO_ZEROLA,
+  THR_COMP_ZERO_ZEROGA,
+
+#if CONFIG_EXT_REFS
+  THR_COMP_NEAR_NEARESTL2A,
+  THR_COMP_NEAREST_NEARL2A,
+  THR_COMP_NEW_NEARESTL2A,
+  THR_COMP_NEAREST_NEWL2A,
+  THR_COMP_NEW_NEARL2A,
+  THR_COMP_NEAR_NEWL2A,
+  THR_COMP_NEW_NEWL2A,
+  THR_COMP_ZERO_ZEROL2A,
+
+  THR_COMP_NEAR_NEARESTL3A,
+  THR_COMP_NEAREST_NEARL3A,
+  THR_COMP_NEW_NEARESTL3A,
+  THR_COMP_NEAREST_NEWL3A,
+  THR_COMP_NEW_NEARL3A,
+  THR_COMP_NEAR_NEWL3A,
+  THR_COMP_NEW_NEWL3A,
+  THR_COMP_ZERO_ZEROL3A,
+
+  THR_COMP_NEAR_NEARESTL4A,
+  THR_COMP_NEAREST_NEARL4A,
+  THR_COMP_NEW_NEARESTL4A,
+  THR_COMP_NEAREST_NEWL4A,
+  THR_COMP_NEW_NEARL4A,
+  THR_COMP_NEAR_NEWL4A,
+  THR_COMP_NEW_NEWL4A,
+  THR_COMP_ZERO_ZEROL4A,
+#endif  // CONFIG_EXT_REFS
+#else
   THR_COMP_NEARLA,
   THR_COMP_NEWLA,
 #if CONFIG_EXT_REFS
@@ -142,6 +199,7 @@ typedef enum {
   THR_COMP_ZEROL4A,
 #endif  // CONFIG_EXT_REFS
   THR_COMP_ZEROGA,
+#endif  // CONFIG_EXT_INTER
 
   THR_H_PRED,
   THR_V_PRED,
index ec67dca291f05375c35c63d13580ce1aa27072ce..0ec4af138786e649cba8b5b87318aad18c4b27c1 100644 (file)
@@ -148,11 +148,11 @@ static const MODE_DEFINITION vp10_mode_order[MAX_MODES] = {
 
 #if CONFIG_EXT_INTER
   {NEWFROMNEARMV,    {LAST_FRAME,   NONE}},
-#if CONFIG_EXT_REF
+#if CONFIG_EXT_REFS
   {NEWFROMNEARMV,    {LAST2_FRAME,  NONE}},
   {NEWFROMNEARMV,    {LAST3_FRAME,  NONE}},
   {NEWFROMNEARMV,    {LAST4_FRAME,  NONE}},
-#endif  // CONFIG_EXT_REF
+#endif  // CONFIG_EXT_REFS
   {NEWFROMNEARMV,    {ALTREF_FRAME, NONE}},
   {NEWFROMNEARMV,    {GOLDEN_FRAME, NONE}},
 #endif  // CONFIG_EXT_INTER
@@ -166,6 +166,15 @@ static const MODE_DEFINITION vp10_mode_order[MAX_MODES] = {
   {ZEROMV,    {GOLDEN_FRAME, NONE}},
   {ZEROMV,    {ALTREF_FRAME, NONE}},
 
+#if CONFIG_EXT_INTER
+  {NEAREST_NEARESTMV, {LAST_FRAME,   ALTREF_FRAME}},
+#if CONFIG_EXT_REFS
+  {NEAREST_NEARESTMV, {LAST2_FRAME,  ALTREF_FRAME}},
+  {NEAREST_NEARESTMV, {LAST3_FRAME,  ALTREF_FRAME}},
+  {NEAREST_NEARESTMV, {LAST4_FRAME,  ALTREF_FRAME}},
+#endif  // CONFIG_EXT_REFS
+  {NEAREST_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+#else  // CONFIG_EXT_INTER
   {NEARESTMV, {LAST_FRAME,   ALTREF_FRAME}},
 #if CONFIG_EXT_REFS
   {NEARESTMV, {LAST2_FRAME,  ALTREF_FRAME}},
@@ -173,9 +182,56 @@ static const MODE_DEFINITION vp10_mode_order[MAX_MODES] = {
   {NEARESTMV, {LAST4_FRAME,  ALTREF_FRAME}},
 #endif  // CONFIG_EXT_REFS
   {NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+#endif  // CONFIG_EXT_INTER
 
   {TM_PRED,   {INTRA_FRAME,  NONE}},
 
+#if CONFIG_EXT_INTER
+  {NEAR_NEARESTMV, {LAST_FRAME,   ALTREF_FRAME}},
+  {NEAR_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+  {NEAREST_NEARMV, {LAST_FRAME,   ALTREF_FRAME}},
+  {NEAREST_NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+  {NEW_NEARESTMV, {LAST_FRAME,   ALTREF_FRAME}},
+  {NEW_NEARESTMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+  {NEAREST_NEWMV, {LAST_FRAME,   ALTREF_FRAME}},
+  {NEAREST_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+  {NEW_NEARMV, {LAST_FRAME,   ALTREF_FRAME}},
+  {NEW_NEARMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+  {NEAR_NEWMV, {LAST_FRAME,   ALTREF_FRAME}},
+  {NEAR_NEWMV, {GOLDEN_FRAME, ALTREF_FRAME}},
+  {NEW_NEWMV,      {LAST_FRAME,   ALTREF_FRAME}},
+  {NEW_NEWMV,      {GOLDEN_FRAME, ALTREF_FRAME}},
+  {ZERO_ZEROMV,    {LAST_FRAME,   ALTREF_FRAME}},
+  {ZERO_ZEROMV,    {GOLDEN_FRAME, ALTREF_FRAME}},
+#if CONFIG_EXT_REFS
+  {NEAR_NEARESTMV, {LAST2_FRAME,  ALTREF_FRAME}},
+  {NEAREST_NEARMV, {LAST2_FRAME,  ALTREF_FRAME}},
+  {NEW_NEARESTMV,  {LAST2_FRAME,  ALTREF_FRAME}},
+  {NEAREST_NEWMV,  {LAST2_FRAME,  ALTREF_FRAME}},
+  {NEW_NEARMV,     {LAST2_FRAME,  ALTREF_FRAME}},
+  {NEAR_NEWMV,     {LAST2_FRAME,  ALTREF_FRAME}},
+  {NEW_NEWMV,      {LAST2_FRAME,  ALTREF_FRAME}},
+  {ZERO_ZEROMV,    {LAST2_FRAME,  ALTREF_FRAME}},
+
+  {NEAR_NEARESTMV, {LAST3_FRAME,  ALTREF_FRAME}},
+  {NEAREST_NEARMV, {LAST3_FRAME,  ALTREF_FRAME}},
+  {NEW_NEARESTMV,  {LAST3_FRAME,  ALTREF_FRAME}},
+  {NEAREST_NEWMV,  {LAST3_FRAME,  ALTREF_FRAME}},
+  {NEW_NEARMV,     {LAST3_FRAME,  ALTREF_FRAME}},
+  {NEAR_NEWMV,     {LAST3_FRAME,  ALTREF_FRAME}},
+  {NEW_NEWMV,      {LAST3_FRAME,  ALTREF_FRAME}},
+  {ZERO_ZEROMV,    {LAST3_FRAME,  ALTREF_FRAME}},
+
+  {NEAR_NEARESTMV, {LAST4_FRAME,  ALTREF_FRAME}},
+  {NEAREST_NEARMV, {LAST4_FRAME,  ALTREF_FRAME}},
+  {NEW_NEARESTMV,  {LAST4_FRAME,  ALTREF_FRAME}},
+  {NEAREST_NEWMV,  {LAST4_FRAME,  ALTREF_FRAME}},
+  {NEW_NEARMV,     {LAST4_FRAME,  ALTREF_FRAME}},
+  {NEAR_NEWMV,     {LAST4_FRAME,  ALTREF_FRAME}},
+  {NEW_NEWMV,      {LAST4_FRAME,  ALTREF_FRAME}},
+  {ZERO_ZEROMV,    {LAST4_FRAME,  ALTREF_FRAME}},
+#endif  // CONFIG_EXT_REFS
+#else
   {NEARMV,    {LAST_FRAME,   ALTREF_FRAME}},
   {NEWMV,     {LAST_FRAME,   ALTREF_FRAME}},
 #if CONFIG_EXT_REFS
@@ -196,6 +252,7 @@ static const MODE_DEFINITION vp10_mode_order[MAX_MODES] = {
   {ZEROMV,    {LAST4_FRAME,  ALTREF_FRAME}},
 #endif  // CONFIG_EXT_REFS
   {ZEROMV,    {GOLDEN_FRAME, ALTREF_FRAME}},
+#endif  // CONFIG_EXT_INTER
 
   {H_PRED,    {INTRA_FRAME,  NONE}},
   {V_PRED,    {INTRA_FRAME,  NONE}},
@@ -3150,13 +3207,22 @@ static int cost_mv_ref(const VP10_COMP *cpi, PREDICTION_MODE mode,
                        int16_t mode_context) {
 #if CONFIG_REF_MV
   int mode_cost = 0;
+#if CONFIG_EXT_INTER
+  int16_t mode_ctx = is_compound ? mode_context :
+                                   (mode_context & NEWMV_CTX_MASK);
+#else
   int16_t mode_ctx = mode_context & NEWMV_CTX_MASK;
+#endif  // CONFIG_EXT_INTER
   int16_t is_all_zero_mv = mode_context & (1 << ALL_ZERO_FLAG_OFFSET);
 
   assert(is_inter_mode(mode));
 
 #if CONFIG_EXT_INTER
-  if (mode == NEWMV || mode == NEWFROMNEARMV) {
+  if (is_compound) {
+    return cpi->inter_compound_mode_cost[mode_context]
+                                        [INTER_COMPOUND_OFFSET(mode)];
+  } else {
+    if (mode == NEWMV || mode == NEWFROMNEARMV) {
 #else
   if (mode == NEWMV) {
 #endif  // CONFIG_EXT_INTER
@@ -3191,9 +3257,21 @@ static int cost_mv_ref(const VP10_COMP *cpi, PREDICTION_MODE mode,
       return mode_cost;
     }
   }
+#if CONFIG_EXT_INTER
+  }
+#endif  // CONFIG_EXT_INTER
 #else
   assert(is_inter_mode(mode));
+#if CONFIG_EXT_INTER
+  if (is_inter_compound_mode(mode)) {
+    return cpi->inter_compound_mode_cost[mode_context]
+                                        [INTER_COMPOUND_OFFSET(mode)];
+  } else {
+#endif  // CONFIG_EXT_INTER
   return cpi->inter_mode_cost[mode_context][INTER_OFFSET(mode)];
+#if CONFIG_EXT_INTER
+  }
+#endif  // CONFIG_EXT_INTER
 #endif
 }
 
@@ -3221,7 +3299,6 @@ static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
     case NEWMV:
 #if CONFIG_EXT_INTER
     case NEWFROMNEARMV:
-      if (!is_compound) {
 #endif  // CONFIG_EXT_INTER
       this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
 #if CONFIG_EXT_INTER
@@ -3231,36 +3308,13 @@ static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
 #endif  // CONFIG_EXT_INTER
       thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv, &best_ref_mv[0]->as_mv,
                                     mvjcost, mvcost, MV_COST_WEIGHT_SUB);
-#if CONFIG_EXT_INTER
-      } else {
-        if (compound_seg_newmvs[0].as_int == INVALID_MV ||
-            compound_seg_newmvs[1].as_int == INVALID_MV) {
-          this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
-          this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
-        } else {
-          this_mv[0].as_int = compound_seg_newmvs[0].as_int;
-          this_mv[1].as_int = compound_seg_newmvs[1].as_int;
-        }
-        if (!cpi->common.allow_high_precision_mv ||
-            !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
-          lower_mv_precision(&this_mv[0].as_mv, 0);
-        if (!cpi->common.allow_high_precision_mv ||
-            !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
-          lower_mv_precision(&this_mv[1].as_mv, 0);
-        thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
-                                       &best_ref_mv[0]->as_mv,
-                                       mvjcost, mvcost, MV_COST_WEIGHT_SUB);
-        thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
-                                       &best_ref_mv[1]->as_mv,
-                                       mvjcost, mvcost, MV_COST_WEIGHT_SUB);
-      }
-#else
+#if !CONFIG_EXT_INTER
       if (is_compound) {
         this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
         thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
                                       mvjcost, mvcost, MV_COST_WEIGHT_SUB);
       }
-#endif  // CONFIG_EXT_INTER
+#endif  // !CONFIG_EXT_INTER
       break;
     case NEARMV:
     case NEARESTMV:
@@ -3273,6 +3327,60 @@ static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
       if (is_compound)
         this_mv[1].as_int = 0;
       break;
+#if CONFIG_EXT_INTER
+    case NEW_NEWMV:
+      if (compound_seg_newmvs[0].as_int == INVALID_MV ||
+          compound_seg_newmvs[1].as_int == INVALID_MV) {
+        this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
+        this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
+      } else {
+        this_mv[0].as_int = compound_seg_newmvs[0].as_int;
+        this_mv[1].as_int = compound_seg_newmvs[1].as_int;
+      }
+      if (!cpi->common.allow_high_precision_mv ||
+          !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
+        lower_mv_precision(&this_mv[0].as_mv, 0);
+      if (!cpi->common.allow_high_precision_mv ||
+          !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
+        lower_mv_precision(&this_mv[1].as_mv, 0);
+      thismvcost += vp10_mv_bit_cost(&this_mv[0].as_mv,
+                                     &best_ref_mv[0]->as_mv,
+                                     mvjcost, mvcost, MV_COST_WEIGHT_SUB);
+      thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv,
+                                     &best_ref_mv[1]->as_mv,
+                                     mvjcost, mvcost, MV_COST_WEIGHT_SUB);
+      break;
+    case NEW_NEARMV:
+    case NEW_NEARESTMV:
+      this_mv[0].as_int = seg_mvs[mbmi->ref_frame[0]].as_int;
+      if (!cpi->common.allow_high_precision_mv ||
+          !vp10_use_mv_hp(&best_ref_mv[0]->as_mv))
+        lower_mv_precision(&this_mv[0].as_mv, 0);
+      thismvcost += vp10_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[mode][mbmi->ref_frame[1]].as_int;
+      break;
+    case NEAR_NEWMV:
+    case NEAREST_NEWMV:
+      this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
+      this_mv[1].as_int = seg_mvs[mbmi->ref_frame[1]].as_int;
+      if (!cpi->common.allow_high_precision_mv ||
+          !vp10_use_mv_hp(&best_ref_mv[1]->as_mv))
+        lower_mv_precision(&this_mv[1].as_mv, 0);
+      thismvcost += vp10_mv_bit_cost(&this_mv[1].as_mv, &best_ref_mv[1]->as_mv,
+                                     mvjcost, mvcost, MV_COST_WEIGHT_SUB);
+      break;
+    case NEAREST_NEARMV:
+    case NEAR_NEARESTMV:
+    case NEAREST_NEARESTMV:
+      this_mv[0].as_int = frame_mv[mode][mbmi->ref_frame[0]].as_int;
+      this_mv[1].as_int = frame_mv[mode][mbmi->ref_frame[1]].as_int;
+       break;
+    case ZERO_ZEROMV:
+      this_mv[0].as_int = 0;
+      this_mv[1].as_int = 0;
+      break;
+#endif  // CONFIG_EXT_INTER
     default:
       break;
   }
@@ -3288,6 +3396,11 @@ static int set_and_cost_bmi_mvs(VP10_COMP *cpi, MACROBLOCK *x, MACROBLOCKD *xd,
       memmove(&mic->bmi[i + idy * 2 + idx], &mic->bmi[i], sizeof(mic->bmi[i]));
 
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+  if (is_compound)
+    mode_ctx = mbmi_ext->compound_mode_context[mbmi->ref_frame[0]];
+  else
+#endif  // CONFIG_EXT_INTER
   mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
                                         mbmi->ref_frame, mbmi->sb_type, i);
 #endif
@@ -3441,7 +3554,11 @@ typedef struct {
   int64_t sse;
   int segment_yrate;
   PREDICTION_MODE modes[4];
+#if CONFIG_EXT_INTER
+  SEG_RDSTAT rdstat[4][INTER_MODES + INTER_COMPOUND_MODES];
+#else
   SEG_RDSTAT rdstat[4][INTER_MODES];
+#endif  // CONFIG_EXT_INTER
   int mvthresh;
 } BEST_SEG_INFO;
 
@@ -3480,6 +3597,9 @@ static INLINE void mi_buf_restore(MACROBLOCK *x, struct buf_2d orig_src,
 // TODO(aconverse): Find out if this is still productive then clean up or remove
 static int check_best_zero_mv(
     const VP10_COMP *cpi, const int16_t mode_context[MAX_REF_FRAMES],
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+    const int16_t compound_mode_context[MAX_REF_FRAMES],
+#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
     int_mv frame_mv[MB_MODE_COUNT][MAX_REF_FRAMES], int this_mode,
     const MV_REFERENCE_FRAME ref_frames[2],
     const BLOCK_SIZE bsize, int block) {
@@ -3527,6 +3647,56 @@ static int check_best_zero_mv(
       }
     }
   }
+#if CONFIG_EXT_INTER
+  else if ((this_mode == NEAREST_NEARESTMV || this_mode == NEAREST_NEARMV ||
+            this_mode == NEAR_NEARESTMV || this_mode == ZERO_ZEROMV) &&
+            frame_mv[this_mode][ref_frames[0]].as_int == 0 &&
+            frame_mv[this_mode][ref_frames[1]].as_int == 0) {
+#if CONFIG_REF_MV
+    int16_t rfc = compound_mode_context[ref_frames[0]];
+    int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, 1, rfc);
+    int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, 1, rfc);
+    int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, 1, rfc);
+    int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, 1, rfc);
+#else
+    int16_t rfc = mode_context[ref_frames[0]];
+    int c1 = cost_mv_ref(cpi, NEAREST_NEARMV, rfc);
+    int c2 = cost_mv_ref(cpi, NEAREST_NEARESTMV, rfc);
+    int c3 = cost_mv_ref(cpi, ZERO_ZEROMV, rfc);
+    int c4 = cost_mv_ref(cpi, NEAR_NEARESTMV, rfc);
+#endif
+
+    if (this_mode == NEAREST_NEARMV) {
+      if (c1 > c3) return 0;
+    } else if (this_mode == NEAREST_NEARESTMV) {
+      if (c2 > c3) return 0;
+    } else if (this_mode == NEAR_NEARESTMV) {
+      if (c4 > c3) return 0;
+    } else {
+      assert(this_mode == ZERO_ZEROMV);
+      if (ref_frames[1] == NONE) {
+        if ((c3 >= c2 &&
+             frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0) ||
+            (c3 >= c1 &&
+             frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0) ||
+            (c3 >= c4 &&
+             frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0))
+          return 0;
+      } else {
+        if ((c3 >= c2 &&
+             frame_mv[NEAREST_NEARESTMV][ref_frames[0]].as_int == 0 &&
+             frame_mv[NEAREST_NEARESTMV][ref_frames[1]].as_int == 0) ||
+            (c3 >= c1 &&
+             frame_mv[NEAREST_NEARMV][ref_frames[0]].as_int == 0 &&
+             frame_mv[NEAREST_NEARMV][ref_frames[1]].as_int == 0) ||
+            (c3 >= c4 &&
+             frame_mv[NEAR_NEARESTMV][ref_frames[0]].as_int == 0 &&
+             frame_mv[NEAR_NEARESTMV][ref_frames[1]].as_int == 0))
+          return 0;
+      }
+    }
+  }
+#endif  // CONFIG_EXT_INTER
   return 1;
 }
 
@@ -3827,13 +3997,40 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
         mv_ref_list[1].as_int = frame_mv[NEARMV][frame].as_int;
         vp10_find_best_ref_mvs(cm->allow_high_precision_mv, mv_ref_list,
                              &ref_mvs_sub8x8[0][ref], &ref_mvs_sub8x8[1][ref]);
+
+        if (has_second_rf) {
+          frame_mv[ZERO_ZEROMV][frame].as_int = 0;
+          frame_mv[NEAREST_NEARESTMV][frame].as_int =
+            frame_mv[NEARESTMV][frame].as_int;
+
+          if (ref == 0) {
+            frame_mv[NEAREST_NEARMV][frame].as_int =
+              frame_mv[NEARESTMV][frame].as_int;
+            frame_mv[NEAR_NEARESTMV][frame].as_int =
+              frame_mv[NEARMV][frame].as_int;
+            frame_mv[NEAREST_NEWMV][frame].as_int =
+              frame_mv[NEARESTMV][frame].as_int;
+            frame_mv[NEAR_NEWMV][frame].as_int =
+              frame_mv[NEARMV][frame].as_int;
+          } else if (ref == 1) {
+            frame_mv[NEAREST_NEARMV][frame].as_int =
+              frame_mv[NEARMV][frame].as_int;
+            frame_mv[NEAR_NEARESTMV][frame].as_int =
+              frame_mv[NEARESTMV][frame].as_int;
+            frame_mv[NEW_NEARESTMV][frame].as_int =
+              frame_mv[NEARESTMV][frame].as_int;
+            frame_mv[NEW_NEARMV][frame].as_int =
+              frame_mv[NEARMV][frame].as_int;
+          }
+        }
 #endif  // CONFIG_EXT_INTER
       }
 
       // search for the best motion vector on this segment
 #if CONFIG_EXT_INTER
-      for (this_mode = NEARESTMV;
-          this_mode <= (has_second_rf ? NEWMV : NEWFROMNEARMV); ++this_mode) {
+      for (this_mode = (has_second_rf ? NEAREST_NEARESTMV : NEARESTMV);
+           this_mode <= (has_second_rf ? NEW_NEWMV : NEWFROMNEARMV);
+           ++this_mode) {
 #else
       for (this_mode = NEARESTMV; this_mode <= NEWMV; ++this_mode) {
 #endif  // CONFIG_EXT_INTER
@@ -3843,6 +4040,7 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
         mode_idx = INTER_OFFSET(this_mode);
 #if CONFIG_EXT_INTER
         mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
+
         for (ref = 0; ref < 1 + has_second_rf; ++ref)
           bsi->ref_mv[ref]->as_int = ref_mvs_sub8x8[mv_idx][ref].as_int;
 #endif  // CONFIG_EXT_INTER
@@ -3850,7 +4048,11 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
         if (!(inter_mode_mask & (1 << this_mode)))
           continue;
 
-        if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv,
+        if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+                                mbmi_ext->compound_mode_context,
+#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
+                                frame_mv,
                                 this_mode, mbmi->ref_frame, bsize, i))
           continue;
 
@@ -3977,7 +4179,12 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
             continue;
         }
 
-        if (has_second_rf && this_mode == NEWMV &&
+        if (has_second_rf &&
+#if CONFIG_EXT_INTER
+            this_mode == NEW_NEWMV &&
+#else
+            this_mode == NEWMV &&
+#endif  // CONFIG_EXT_INTER
             mbmi->interp_filter == EIGHTTAP) {
           // adjust src pointers
           mi_buf_shift(x, i);
@@ -4133,7 +4340,11 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
       if (best_rd == INT64_MAX) {
         int iy, midx;
         for (iy = i + 1; iy < 4; ++iy)
+#if CONFIG_EXT_INTER
+          for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
+#else
           for (midx = 0; midx < INTER_MODES; ++midx)
+#endif  // CONFIG_EXT_INTER
             bsi->rdstat[iy][midx].brdcost = INT64_MAX;
         bsi->segment_rd = INT64_MAX;
         return INT64_MAX;
@@ -4168,7 +4379,11 @@ static int64_t rd_pick_best_sub8x8_mode(VP10_COMP *cpi, MACROBLOCK *x,
       if (this_segment_rd > bsi->segment_rd) {
         int iy, midx;
         for (iy = i + 1; iy < 4; ++iy)
+#if CONFIG_EXT_INTER
+          for (midx = 0; midx < INTER_MODES + INTER_COMPOUND_MODES; ++midx)
+#else
           for (midx = 0; midx < INTER_MODES; ++midx)
+#endif  // CONFIG_EXT_INTER
             bsi->rdstat[iy][midx].brdcost = INT64_MAX;
         bsi->segment_rd = INT64_MAX;
         return INT64_MAX;
@@ -4400,6 +4615,9 @@ static void setup_buffer_inter(
 #if CONFIG_REF_MV
                     &mbmi_ext->ref_mv_count[ref_frame],
                     mbmi_ext->ref_mv_stack[ref_frame],
+#if CONFIG_EXT_INTER
+                    mbmi_ext->compound_mode_context,
+#endif  // CONFIG_EXT_INTER
 #endif
                     candidates, mi_row, mi_col,
                     NULL, NULL, mbmi_ext->mode_context);
@@ -4630,6 +4848,9 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
 #if CONFIG_EXT_INTER
   int mv_idx = (this_mode == NEWFROMNEARMV) ? 1 : 0;
   int_mv single_newmv[MAX_REF_FRAMES];
+#if CONFIG_REF_MV
+  uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
+#endif
 #endif  // CONFIG_EXT_INTER
 #if CONFIG_VP9_HIGHBITDEPTH
   DECLARE_ALIGNED(16, uint16_t, tmp_buf16[MAX_MB_PLANE * 64 * 64]);
@@ -4659,6 +4880,11 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
   int16_t mode_ctx = mbmi_ext->mode_context[refs[0]];
 
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+  if (is_comp_pred)
+    mode_ctx = mbmi_ext->compound_mode_context[refs[0]];
+  else
+#endif  // CONFIG_EXT_INTER
   mode_ctx = vp10_mode_context_analyzer(mbmi_ext->mode_context,
                                         mbmi->ref_frame, bsize, -1);
 #endif
@@ -4679,7 +4905,8 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
       lf = xd->mi[-1]->mbmi.interp_filter;
 
 #if CONFIG_EXT_INTER
-    if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV) || (af == lf))
+    if ((this_mode != NEWMV && this_mode != NEWFROMNEARMV &&
+        this_mode != NEW_NEWMV) || (af == lf))
 #else
     if ((this_mode != NEWMV) || (af == lf))
 #endif  // CONFIG_EXT_INTER
@@ -4692,9 +4919,64 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
       return INT64_MAX;
 
     if (cpi->sf.adaptive_mode_search) {
+#if CONFIG_EXT_INTER
+      switch (this_mode) {
+        case NEAREST_NEARESTMV:
+          if (single_filter[NEARESTMV][refs[0]] ==
+              single_filter[NEARESTMV][refs[1]])
+            best_filter = single_filter[NEARESTMV][refs[0]];
+          break;
+        case NEAREST_NEARMV:
+          if (single_filter[NEARESTMV][refs[0]] ==
+              single_filter[NEARMV][refs[1]])
+            best_filter = single_filter[NEARESTMV][refs[0]];
+          break;
+        case NEAR_NEARESTMV:
+          if (single_filter[NEARMV][refs[0]] ==
+              single_filter[NEARESTMV][refs[1]])
+            best_filter = single_filter[NEARMV][refs[0]];
+          break;
+        case ZERO_ZEROMV:
+          if (single_filter[ZEROMV][refs[0]] ==
+              single_filter[ZEROMV][refs[1]])
+            best_filter = single_filter[ZEROMV][refs[0]];
+          break;
+        case NEW_NEWMV:
+          if (single_filter[NEWMV][refs[0]] ==
+              single_filter[NEWMV][refs[1]])
+            best_filter = single_filter[NEWMV][refs[0]];
+          break;
+        case NEAREST_NEWMV:
+          if (single_filter[NEARESTMV][refs[0]] ==
+              single_filter[NEWMV][refs[1]])
+            best_filter = single_filter[NEARESTMV][refs[0]];
+          break;
+        case NEAR_NEWMV:
+          if (single_filter[NEARMV][refs[0]] ==
+              single_filter[NEWMV][refs[1]])
+            best_filter = single_filter[NEARMV][refs[0]];
+          break;
+        case NEW_NEARESTMV:
+          if (single_filter[NEWMV][refs[0]] ==
+              single_filter[NEARESTMV][refs[1]])
+            best_filter = single_filter[NEWMV][refs[0]];
+          break;
+        case NEW_NEARMV:
+          if (single_filter[NEWMV][refs[0]] ==
+              single_filter[NEARMV][refs[1]])
+            best_filter = single_filter[NEWMV][refs[0]];
+          break;
+        default:
+          if (single_filter[this_mode][refs[0]] ==
+              single_filter[this_mode][refs[1]])
+            best_filter = single_filter[this_mode][refs[0]];
+          break;
+      }
+#else
       if (single_filter[this_mode][refs[0]] ==
           single_filter[this_mode][refs[1]])
         best_filter = single_filter[this_mode][refs[0]];
+#endif  // CONFIG_EXT_INTER
     }
   }
 
@@ -4708,9 +4990,38 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
 #if CONFIG_EXT_INTER
       for (i = 0; i < 2; ++i) {
         single_newmv[refs[i]].as_int =
-            single_newmvs[mv_idx][refs[i]].as_int;
+          single_newmvs[mv_idx][refs[i]].as_int;
       }
-#endif  // CONFIG_EXT_INTER
+
+      if (this_mode == NEW_NEWMV) {
+        frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
+        frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
+
+        if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
+          joint_motion_search(cpi, x, bsize, frame_mv,
+                              mi_row, mi_col, NULL, single_newmv, &rate_mv);
+        } else {
+          rate_mv  = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
+                                      &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
+                                      x->nmvjointcost, x->mvcost,
+                                      MV_COST_WEIGHT);
+          rate_mv += vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
+                                      &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
+                                      x->nmvjointcost, x->mvcost,
+                                      MV_COST_WEIGHT);
+        }
+      } else if (this_mode == NEAREST_NEWMV || this_mode == NEAR_NEWMV) {
+        frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
+        rate_mv = vp10_mv_bit_cost(&frame_mv[refs[1]].as_mv,
+                                   &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
+                                   x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+      } else {
+        frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
+        rate_mv = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
+                                   &x->mbmi_ext->ref_mvs[refs[0]][0].as_mv,
+                                   x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
+      }
+#else
       // Initialize mv using single prediction mode result.
       frame_mv[refs[0]].as_int = single_newmv[refs[0]].as_int;
       frame_mv[refs[1]].as_int = single_newmv[refs[1]].as_int;
@@ -4718,9 +5029,6 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
       if (cpi->sf.comp_inter_joint_search_thresh <= bsize) {
         joint_motion_search(cpi, x, bsize, frame_mv,
                             mi_row, mi_col,
-#if CONFIG_EXT_INTER
-                            NULL,
-#endif  // CONFIG_EXT_INTER
                             single_newmv, &rate_mv);
       } else {
         rate_mv  = vp10_mv_bit_cost(&frame_mv[refs[0]].as_mv,
@@ -4730,6 +5038,7 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
                                    &x->mbmi_ext->ref_mvs[refs[1]][0].as_mv,
                                    x->nmvjointcost, x->mvcost, MV_COST_WEIGHT);
       }
+#endif  // CONFIG_EXT_INTER
       *rate2 += rate_mv;
     } else {
       int_mv tmp_mv;
@@ -4777,8 +5086,12 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
   }
 
 #if CONFIG_REF_MV
+#if CONFIG_EXT_INTER
+  if (this_mode == NEAREST_NEARESTMV) {
+#else
   if (this_mode == NEARESTMV && is_comp_pred) {
     uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
+#endif  // CONFIG_EXT_INTER
     if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
       cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
       cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
@@ -4793,6 +5106,51 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
     }
   }
 
+#if CONFIG_EXT_INTER
+  if (mbmi_ext->ref_mv_count[ref_frame_type] > 0) {
+    if (this_mode == NEAREST_NEWMV || this_mode == NEAREST_NEARMV) {
+      cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][0].this_mv;
+
+      lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
+      clamp_mv2(&cur_mv[0].as_mv, xd);
+      if (mv_check_bounds(x, &cur_mv[0].as_mv))
+        return INT64_MAX;
+      mbmi->mv[0].as_int = cur_mv[0].as_int;
+    }
+
+    if (this_mode == NEW_NEARESTMV || this_mode == NEAR_NEARESTMV) {
+      cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][0].comp_mv;
+
+      lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
+      clamp_mv2(&cur_mv[1].as_mv, xd);
+      if (mv_check_bounds(x, &cur_mv[1].as_mv))
+        return INT64_MAX;
+      mbmi->mv[1].as_int = cur_mv[1].as_int;
+    }
+  }
+
+  if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
+    if (this_mode == NEAR_NEWMV || this_mode == NEAR_NEARESTMV) {
+      cur_mv[0] = mbmi_ext->ref_mv_stack[ref_frame_type][1].this_mv;
+
+      lower_mv_precision(&cur_mv[0].as_mv, cm->allow_high_precision_mv);
+      clamp_mv2(&cur_mv[0].as_mv, xd);
+      if (mv_check_bounds(x, &cur_mv[0].as_mv))
+        return INT64_MAX;
+      mbmi->mv[0].as_int = cur_mv[0].as_int;
+    }
+
+    if (this_mode == NEW_NEARMV || this_mode == NEAREST_NEARMV) {
+      cur_mv[1] = mbmi_ext->ref_mv_stack[ref_frame_type][1].comp_mv;
+
+      lower_mv_precision(&cur_mv[1].as_mv, cm->allow_high_precision_mv);
+      clamp_mv2(&cur_mv[1].as_mv, xd);
+      if (mv_check_bounds(x, &cur_mv[1].as_mv))
+        return INT64_MAX;
+      mbmi->mv[1].as_int = cur_mv[1].as_int;
+    }
+  }
+#else
   if (this_mode == NEARMV && is_comp_pred) {
     uint8_t ref_frame_type = vp10_ref_frame_type(mbmi->ref_frame);
     if (mbmi_ext->ref_mv_count[ref_frame_type] > 1) {
@@ -4808,6 +5166,7 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
       }
     }
   }
+#endif  // CONFIG_EXT_INTER
 #endif
 
   // do first prediction into the destination buffer. Do the next
@@ -4845,7 +5204,11 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
   }
 
   if (RDCOST(x->rdmult, x->rddiv, *rate2, 0) > ref_best_rd &&
+#if CONFIG_EXT_INTER
+      mbmi->mode != NEARESTMV && mbmi->mode != NEAREST_NEARESTMV)
+#else
       mbmi->mode != NEARESTMV)
+#endif  // CONFIG_EXT_INTER
     return INT64_MAX;
 
   pred_exists = 0;
@@ -4994,9 +5357,64 @@ static int64_t handle_inter_mode(VP10_COMP *cpi, MACROBLOCK *x,
 
   if (cpi->sf.adaptive_mode_search)
     if (is_comp_pred)
+#if CONFIG_EXT_INTER
+      switch (this_mode) {
+        case NEAREST_NEARESTMV:
+          if (single_skippable[NEARESTMV][refs[0]] &&
+              single_skippable[NEARESTMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        case ZERO_ZEROMV:
+          if (single_skippable[ZEROMV][refs[0]] &&
+              single_skippable[ZEROMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        case NEW_NEWMV:
+          if (single_skippable[NEWMV][refs[0]] &&
+              single_skippable[NEWMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        case NEAREST_NEWMV:
+          if (single_skippable[NEARESTMV][refs[0]] &&
+              single_skippable[NEWMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        case NEAR_NEWMV:
+          if (single_skippable[NEARMV][refs[0]] &&
+              single_skippable[NEWMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        case NEW_NEARESTMV:
+          if (single_skippable[NEWMV][refs[0]] &&
+              single_skippable[NEARESTMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        case NEW_NEARMV:
+          if (single_skippable[NEWMV][refs[0]] &&
+              single_skippable[NEARMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        case NEAREST_NEARMV:
+          if (single_skippable[NEARESTMV][refs[0]] &&
+              single_skippable[NEARMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        case NEAR_NEARESTMV:
+          if (single_skippable[NEARMV][refs[0]] &&
+              single_skippable[NEARESTMV][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+        default:
+          if (single_skippable[this_mode][refs[0]] &&
+              single_skippable[this_mode][refs[1]])
+            memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+          break;
+      }
+#else
       if (single_skippable[this_mode][refs[0]] &&
           single_skippable[this_mode][refs[1]])
         memset(skip_txfm, SKIP_TXFM_AC_DC, sizeof(skip_txfm));
+#endif  // CONFIG_EXT_INTER
 
   if (cpi->sf.use_rd_breakout && ref_best_rd < INT64_MAX) {
     // if current pred_error modeled rd is substantially more than the best
@@ -5387,6 +5805,9 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ++ref_frame) {
     x->pred_mv_sad[ref_frame] = INT_MAX;
     x->mbmi_ext->mode_context[ref_frame] = 0;
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+    x->mbmi_ext->compound_mode_context[ref_frame] = 0;
+#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
     if (cpi->ref_frame_flags & flag_list[ref_frame]) {
       assert(get_ref_frame_buffer(cpi, ref_frame) != NULL);
       setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
@@ -5396,6 +5817,8 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
     frame_mv[ZEROMV][ref_frame].as_int = 0;
 #if CONFIG_EXT_INTER
     frame_mv[NEWFROMNEARMV][ref_frame].as_int = INVALID_MV;
+    frame_mv[NEW_NEWMV][ref_frame].as_int = INVALID_MV;
+    frame_mv[ZERO_ZEROMV][ref_frame].as_int = 0;
 #endif  // CONFIG_EXT_INTER
   }
 
@@ -5408,6 +5831,9 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
 #if CONFIG_REF_MV
                       &mbmi_ext->ref_mv_count[ref_frame],
                       mbmi_ext->ref_mv_stack[ref_frame],
+#if CONFIG_EXT_INTER
+                      mbmi_ext->compound_mode_context,
+#endif  // CONFIG_EXT_INTER
 #endif
                       candidates, mi_row, mi_col,
                       NULL, NULL, mbmi_ext->mode_context);
@@ -5462,6 +5888,14 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
         mode_skip_mask[ALTREF_FRAME] |= (1 << NEARMV);
       if (frame_mv[NEARESTMV][ALTREF_FRAME].as_int != 0)
         mode_skip_mask[ALTREF_FRAME] |= (1 << NEARESTMV);
+#if CONFIG_EXT_INTER
+      if (frame_mv[NEAREST_NEARESTMV][ALTREF_FRAME].as_int != 0)
+        mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARESTMV);
+      if (frame_mv[NEAREST_NEARMV][ALTREF_FRAME].as_int != 0)
+        mode_skip_mask[ALTREF_FRAME] |= (1 << NEAREST_NEARMV);
+      if (frame_mv[NEAR_NEARESTMV][ALTREF_FRAME].as_int != 0)
+        mode_skip_mask[ALTREF_FRAME] |= (1 << NEAR_NEARESTMV);
+#endif  // CONFIG_EXT_INTER
     }
   }
 
@@ -5531,6 +5965,50 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
     ref_frame = vp10_mode_order[mode_index].ref_frame[0];
     second_ref_frame = vp10_mode_order[mode_index].ref_frame[1];
 
+#if CONFIG_EXT_INTER
+    if (this_mode == NEAREST_NEARESTMV) {
+      frame_mv[NEAREST_NEARESTMV][ref_frame].as_int =
+          frame_mv[NEARESTMV][ref_frame].as_int;
+      frame_mv[NEAREST_NEARESTMV][second_ref_frame].as_int =
+          frame_mv[NEARESTMV][second_ref_frame].as_int;
+    } else if (this_mode == NEAREST_NEARMV) {
+      frame_mv[NEAREST_NEARMV][ref_frame].as_int =
+          frame_mv[NEARESTMV][ref_frame].as_int;
+      frame_mv[NEAREST_NEARMV][second_ref_frame].as_int =
+          frame_mv[NEARMV][second_ref_frame].as_int;
+    } else if (this_mode == NEAR_NEARESTMV) {
+      frame_mv[NEAR_NEARESTMV][ref_frame].as_int =
+          frame_mv[NEARMV][ref_frame].as_int;
+      frame_mv[NEAR_NEARESTMV][second_ref_frame].as_int =
+          frame_mv[NEARESTMV][second_ref_frame].as_int;
+    } else if (this_mode == NEAREST_NEWMV) {
+      frame_mv[NEAREST_NEWMV][ref_frame].as_int =
+          frame_mv[NEARESTMV][ref_frame].as_int;
+      frame_mv[NEAREST_NEWMV][second_ref_frame].as_int =
+          frame_mv[NEWMV][second_ref_frame].as_int;
+    } else if (this_mode == NEW_NEARESTMV) {
+      frame_mv[NEW_NEARESTMV][ref_frame].as_int =
+          frame_mv[NEWMV][ref_frame].as_int;
+      frame_mv[NEW_NEARESTMV][second_ref_frame].as_int =
+          frame_mv[NEARESTMV][second_ref_frame].as_int;
+    } else if (this_mode == NEAR_NEWMV) {
+      frame_mv[NEAR_NEWMV][ref_frame].as_int =
+        frame_mv[NEARMV][ref_frame].as_int;
+      frame_mv[NEAR_NEWMV][second_ref_frame].as_int =
+          frame_mv[NEWMV][second_ref_frame].as_int;
+    } else if (this_mode == NEW_NEARMV) {
+      frame_mv[NEW_NEARMV][ref_frame].as_int =
+          frame_mv[NEWMV][ref_frame].as_int;
+      frame_mv[NEW_NEARMV][second_ref_frame].as_int =
+        frame_mv[NEARMV][second_ref_frame].as_int;
+    } else if (this_mode == NEW_NEWMV) {
+      frame_mv[NEW_NEWMV][ref_frame].as_int =
+          frame_mv[NEWMV][ref_frame].as_int;
+      frame_mv[NEW_NEWMV][second_ref_frame].as_int =
+          frame_mv[NEWMV][second_ref_frame].as_int;
+    }
+#endif  // CONFIG_EXT_INTER
+
     // Look at the reference frame of the best mode so far and set the
     // skip mask to look at a subset of the remaining modes.
     if (midx == mode_skip_start && best_mode_index >= 0) {
@@ -5635,7 +6113,11 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
       }
     } else {
       const MV_REFERENCE_FRAME ref_frames[2] = {ref_frame, second_ref_frame};
-      if (!check_best_zero_mv(cpi, mbmi_ext->mode_context, frame_mv,
+      if (!check_best_zero_mv(cpi, mbmi_ext->mode_context,
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+                              mbmi_ext->compound_mode_context,
+#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
+                              frame_mv,
                               this_mode, ref_frames, bsize, -1))
         continue;
     }
@@ -6008,6 +6490,7 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
   if (best_mbmode.mode == NEWMV
 #if CONFIG_EXT_INTER
       || best_mbmode.mode == NEWFROMNEARMV
+      || best_mbmode.mode == NEW_NEWMV
 #endif  // CONFIG_EXT_INTER
   ) {
     const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
@@ -6048,14 +6531,29 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
 
       if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
           nearestmv[1].as_int == best_mbmode.mv[1].as_int)
+#if CONFIG_EXT_INTER
+        best_mbmode.mode = NEAREST_NEARESTMV;
+      else if (nearestmv[0].as_int == best_mbmode.mv[0].as_int &&
+               nearmv[1].as_int == best_mbmode.mv[1].as_int)
+        best_mbmode.mode = NEAREST_NEARMV;
+      else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
+               nearestmv[1].as_int == best_mbmode.mv[1].as_int)
+        best_mbmode.mode = NEAR_NEARESTMV;
+      else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
+        best_mbmode.mode = ZERO_ZEROMV;
+#else
         best_mbmode.mode = NEARESTMV;
       else if (nearmv[0].as_int == best_mbmode.mv[0].as_int &&
           nearmv[1].as_int == best_mbmode.mv[1].as_int)
         best_mbmode.mode = NEARMV;
       else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
         best_mbmode.mode = ZEROMV;
+#endif  // CONFIG_EXT_INTER
     }
 #else
+#if CONFIG_EXT_INTER
+    if (!comp_pred_mode) {
+#endif  // CONFIG_EXT_INTER
     if (frame_mv[NEARESTMV][refs[0]].as_int == best_mbmode.mv[0].as_int &&
         ((comp_pred_mode && frame_mv[NEARESTMV][refs[1]].as_int ==
             best_mbmode.mv[1].as_int) || !comp_pred_mode))
@@ -6067,16 +6565,46 @@ void vp10_rd_pick_inter_mode_sb(VP10_COMP *cpi,
     else if (best_mbmode.mv[0].as_int == 0 &&
         ((comp_pred_mode && best_mbmode.mv[1].as_int == 0) || !comp_pred_mode))
       best_mbmode.mode = ZEROMV;
+#if CONFIG_EXT_INTER
+    } else {
+      const MV_REFERENCE_FRAME refs[2] = {best_mbmode.ref_frame[0],
+          best_mbmode.ref_frame[1]};
+
+      if (frame_mv[NEAREST_NEARESTMV][refs[0]].as_int ==
+            best_mbmode.mv[0].as_int &&
+          frame_mv[NEAREST_NEARESTMV][refs[1]].as_int ==
+            best_mbmode.mv[1].as_int)
+        best_mbmode.mode = NEAREST_NEARESTMV;
+      else if (frame_mv[NEAREST_NEARMV][refs[0]].as_int ==
+                 best_mbmode.mv[0].as_int &&
+               frame_mv[NEAREST_NEARMV][refs[1]].as_int ==
+                 best_mbmode.mv[1].as_int)
+        best_mbmode.mode = NEAREST_NEARMV;
+      else if (frame_mv[NEAR_NEARESTMV][refs[0]].as_int ==
+                 best_mbmode.mv[0].as_int &&
+               frame_mv[NEAR_NEARESTMV][refs[1]].as_int ==
+                 best_mbmode.mv[1].as_int)
+        best_mbmode.mode = NEAR_NEARESTMV;
+      else if (best_mbmode.mv[0].as_int == 0 && best_mbmode.mv[1].as_int == 0)
+        best_mbmode.mode = ZERO_ZEROMV;
+    }
+#endif  // CONFIG_EXT_INTER
 #endif
   }
 
 #if CONFIG_REF_MV
   if (best_mbmode.ref_frame[0] > INTRA_FRAME &&
       best_mbmode.mv[0].as_int == 0 &&
+#if CONFIG_EXT_INTER
+      best_mbmode.ref_frame[1] == NONE) {
+#else
       (best_mbmode.ref_frame[1] == NONE || best_mbmode.mv[1].as_int == 0)) {
+#endif  // CONFIG_EXT_INTER
     int16_t mode_ctx = mbmi_ext->mode_context[best_mbmode.ref_frame[0]];
+#if !CONFIG_EXT_INTER
     if (best_mbmode.ref_frame[1] > NONE)
       mode_ctx &= (mbmi_ext->mode_context[best_mbmode.ref_frame[1]] | 0x00ff);
+#endif  // !CONFIG_EXT_INTER
 
     if (mode_ctx & (1 << ALL_ZERO_FLAG_OFFSET))
       best_mbmode.mode = ZEROMV;
@@ -6381,6 +6909,9 @@ void vp10_rd_pick_inter_mode_sub8x8(struct VP10_COMP *cpi,
 
   for (ref_frame = LAST_FRAME; ref_frame <= ALTREF_FRAME; ref_frame++) {
     x->mbmi_ext->mode_context[ref_frame] = 0;
+#if CONFIG_REF_MV && CONFIG_EXT_INTER
+    x->mbmi_ext->compound_mode_context[ref_frame] = 0;
+#endif  // CONFIG_REF_MV && CONFIG_EXT_INTER
     if (cpi->ref_frame_flags & flag_list[ref_frame]) {
       setup_buffer_inter(cpi, x, ref_frame, bsize, mi_row, mi_col,
                          frame_mv[NEARESTMV], frame_mv[NEARMV],
index a48a76c31f6c323c48239d36ce69679ac953a1bd..170e537429187b038ae8dec274b68663a6c351e3 100644 (file)
@@ -35,16 +35,40 @@ enum {
 enum {
   INTER_ALL =
       (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) |
-      (1 << NEWMV) | (1 << NEWFROMNEARMV),
-  INTER_NEAREST = (1 << NEARESTMV),
-  INTER_NEAREST_NEW = (1 << NEARESTMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV),
-  INTER_NEAREST_ZERO = (1 << NEARESTMV) | (1 << ZEROMV),
+      (1 << NEWMV) | (1 << NEWFROMNEARMV) |
+      (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),
+  INTER_NEAREST = (1 << NEARESTMV) | (1 << NEAREST_NEARESTMV) |
+                  (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+                  (1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV),
+  INTER_NEAREST_NEW = (1 << NEARESTMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV) |
+                      (1 << NEAREST_NEARESTMV) | (1 << NEW_NEWMV) |
+                      (1 << NEAR_NEARESTMV) | (1 << NEAREST_NEARMV) |
+                      (1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV) |
+                      (1 << NEW_NEARMV) | (1 << NEAR_NEWMV),
+  INTER_NEAREST_ZERO = (1 << NEARESTMV) | (1 << ZEROMV) |
+                       (1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) |
+                       (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+                       (1 << NEAREST_NEWMV) | (1 << NEW_NEARESTMV),
   INTER_NEAREST_NEW_ZERO =
-      (1 << NEARESTMV) | (1 << ZEROMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV),
+      (1 << NEARESTMV) | (1 << ZEROMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV) |
+      (1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) | (1 << NEW_NEWMV) |
+      (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+      (1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV) |
+      (1 << NEW_NEARMV) | (1 << NEAR_NEWMV),
   INTER_NEAREST_NEAR_NEW =
-      (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV),
+      (1 << NEARESTMV) | (1 << NEARMV) | (1 << NEWMV) | (1 << NEWFROMNEARMV) |
+      (1 << NEAREST_NEARESTMV) | (1 << NEW_NEWMV) |
+      (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+      (1 << NEW_NEARESTMV) | (1 << NEAREST_NEWMV) |
+      (1 << NEW_NEARMV) | (1 << NEAR_NEWMV),
   INTER_NEAREST_NEAR_ZERO =
-      (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV)
+      (1 << NEARESTMV) | (1 << NEARMV) | (1 << ZEROMV) |
+      (1 << NEAREST_NEARESTMV) | (1 << ZERO_ZEROMV) |
+      (1 << NEAREST_NEARMV) | (1 << NEAR_NEARESTMV) |
+      (1 << NEAREST_NEWMV) | (1 << NEW_NEARESTMV) |
+      (1 << NEW_NEARMV) | (1 << NEAR_NEWMV)
 };
 #else
 enum {