ncobmc_adapt_weight: allow the usage of new motion mode

The new motion mode "NCOBMC_ADAPT_WEIGHT" cannot be used
in the motion search loop as it requires all mvs from the
neighboring blocks. This patch add a wrapper to skip checking
this mode during mv search.

Change-Id: I3a39954e91101929f26b5479c8c6ae22abdc7bce
diff --git a/av1/common/blockd.h b/av1/common/blockd.h
index 638548f..3471977 100644
--- a/av1/common/blockd.h
+++ b/av1/common/blockd.h
@@ -1371,12 +1371,33 @@
 }
 
 #if CONFIG_NCOBMC_ADAPT_WEIGHT && CONFIG_MOTION_VAR
-static INLINE NCOBMC_MODE ncobmc_mode_allowed(BLOCK_SIZE block) {
-  if (block < BLOCK_8X8 || block > BLOCK_64X64)
+static INLINE NCOBMC_MODE ncobmc_mode_allowed_bsize(BLOCK_SIZE bsize) {
+  if (bsize < BLOCK_8X8 || bsize > BLOCK_64X64)
     return NO_OVERLAP;
   else
     return (NCOBMC_MODE)(MAX_NCOBMC_MODES - 1);
 }
+
+static INLINE MOTION_MODE
+motion_mode_allowed_wrapper(int for_mv_search,
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                            int block, const WarpedMotionParams *gm_params,
+#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                            const MODE_INFO *mi) {
+  const MB_MODE_INFO *mbmi = &mi->mbmi;
+  MOTION_MODE motion_mode_for_mv_search = motion_mode_allowed(
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+      int block, const WarpedMotionParams *gm_params,
+#endif
+      mi);
+  int ncobmc_mode_allowed =
+      ncobmc_mode_allowed_bsize(mbmi->sb_type) && is_inter_mode(mbmi->mode);
+  if (for_mv_search)
+    return motion_mode_for_mv_search;
+  else
+    return ncobmc_mode_allowed ? NCOBMC_ADAPT_WEIGHT
+                               : motion_mode_for_mv_search;
+}
 #endif
 
 static INLINE void assert_motion_mode_valid(MOTION_MODE mode,
@@ -1385,11 +1406,20 @@
                                             const WarpedMotionParams *gm_params,
 #endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
                                             const MODE_INFO *mi) {
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+  const MOTION_MODE last_motion_mode_allowed =
+      motion_mode_allowed_wrapper(0,
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  block, gm_params,
+#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  mi);
+#else
   const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
 #if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
       block, gm_params,
 #endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
       mi);
+#endif
   // Check that the input mode is not illegal
   if (last_motion_mode_allowed < mode)
     assert(0 && "Illegal motion mode selected");
diff --git a/av1/decoder/decodemv.c b/av1/decoder/decodemv.c
index 0de16c7..f3f8b89 100644
--- a/av1/decoder/decodemv.c
+++ b/av1/decoder/decodemv.c
@@ -315,11 +315,20 @@
 static MOTION_MODE read_motion_mode(AV1_COMMON *cm, MACROBLOCKD *xd,
                                     MODE_INFO *mi, aom_reader *r) {
   MB_MODE_INFO *mbmi = &mi->mbmi;
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+  const MOTION_MODE last_motion_mode_allowed =
+      motion_mode_allowed_wrapper(0,
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  0, xd->global_motion,
+#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  mi);
+#else
   const MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
 #if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
       0, xd->global_motion,
 #endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
       mi);
+#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
   int motion_mode;
   FRAME_COUNTS *counts = xd->counts;
 
@@ -346,11 +355,14 @@
                              NCOBMC_MODE ncobmc_mode[2], aom_reader *r) {
   MB_MODE_INFO *mbmi = &mi->mbmi;
   FRAME_COUNTS *counts = xd->counts;
+  MOTION_MODE last_motion_mode_allowed =
+      motion_mode_allowed_wrapper(0,
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  0, cm->global_motion,
+#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  mi);
   ADAPT_OVERLAP_BLOCK ao_block = adapt_overlap_block_lookup[mbmi->sb_type];
-
-  if (ncobmc_mode_allowed(mbmi->sb_type) == NO_OVERLAP ||
-      ao_block == ADAPT_OVERLAP_BLOCK_INVALID)
-    return;
+  if (last_motion_mode_allowed < NCOBMC_ADAPT_WEIGHT) return;
 
   ncobmc_mode[0] = aom_read_tree(r, av1_ncobmc_mode_tree,
                                  cm->fc->ncobmc_mode_prob[ao_block], ACCT_STR);
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 0e0d609..386c8b3 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -593,12 +593,20 @@
 static void write_motion_mode(const AV1_COMMON *cm, const MODE_INFO *mi,
                               aom_writer *w) {
   const MB_MODE_INFO *mbmi = &mi->mbmi;
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+  MOTION_MODE last_motion_mode_allowed =
+      motion_mode_allowed_wrapper(0,
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  0, cm->global_motion,
+#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  mi);
+#else
   MOTION_MODE last_motion_mode_allowed = motion_mode_allowed(
 #if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
       0, cm->global_motion,
 #endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
       mi);
-
+#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
   if (last_motion_mode_allowed == SIMPLE_TRANSLATION) return;
 #if CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
   if (last_motion_mode_allowed == OBMC_CAUSAL) {
@@ -618,10 +626,14 @@
 static void write_ncobmc_mode(const AV1_COMMON *cm, const MODE_INFO *mi,
                               aom_writer *w) {
   const MB_MODE_INFO *mbmi = &mi->mbmi;
+  MOTION_MODE last_motion_mode_allowed =
+      motion_mode_allowed_wrapper(0,
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  0, cm->global_motion,
+#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                  mi);
   ADAPT_OVERLAP_BLOCK ao_block = adapt_overlap_block_lookup[mbmi->sb_type];
-  if (ncobmc_mode_allowed(mbmi->sb_type) == NO_OVERLAP ||
-      ao_block == ADAPT_OVERLAP_BLOCK_INVALID)
-    return;
+  if (last_motion_mode_allowed < NCOBMC_ADAPT_WEIGHT) return;
 
   av1_write_token(w, av1_ncobmc_mode_tree, cm->fc->ncobmc_mode_prob[ao_block],
                   &ncobmc_mode_encodings[mbmi->ncobmc_mode[0]]);
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 25fd9dc..511066d 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -1705,11 +1705,20 @@
 #endif  // CONFIG_EXT_INTER
 
 #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+        const MOTION_MODE motion_allowed =
+            motion_mode_allowed_wrapper(0,
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                        0, xd->global_motion,
+#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                        mi);
+#else
         const MOTION_MODE motion_allowed = motion_mode_allowed(
 #if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
             0, xd->global_motion,
 #endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
             mi);
+#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
 #if CONFIG_SUPERTX
         if (!supertx_enabled)
 #endif  // CONFIG_SUPERTX
@@ -1729,7 +1738,7 @@
 #endif  // CONFIG_MOTION_VAR && CONFIG_WARPED_MOTION
 
 #if CONFIG_NCOBMC_ADAPT_WEIGHT
-        if (ncobmc_mode_allowed(mbmi->sb_type) > NO_OVERLAP) {
+        if (motion_allowed == NCOBMC_ADAPT_WEIGHT) {
           ADAPT_OVERLAP_BLOCK ao_block =
               adapt_overlap_block_lookup[mbmi->sb_type];
           ++counts->ncobmc_mode[ao_block][mbmi->ncobmc_mode[0]];
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index afa3970..02acee9 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -7837,11 +7837,23 @@
 #endif  // CONFIG_WARPED_MOTION
 #if CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION
   rate2_nocoeff = rd_stats->rate;
+#if CONFIG_NCOBMC_ADAPT_WEIGHT
+  // We cannot estimate the rd cost for the motion mode NCOBMC_ADAPT_WEIGHT
+  // right now since it requires mvs from all neighboring blocks. We will
+  // check if this mode is beneficial after all the mv's in the current
+  // superblock are selected.
+  last_motion_mode_allowed = motion_mode_allowed_wrapper(1,
+#if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                                         0, xd->global_motion,
+#endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
+                                                         mi);
+#else
   last_motion_mode_allowed = motion_mode_allowed(
 #if CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
       0, xd->global_motion,
 #endif  // CONFIG_GLOBAL_MOTION && SEPARATE_GLOBAL_MOTION
       mi);
+#endif  // CONFIG_NCOBMC_ADAPT_WEIGHT
   base_mbmi = *mbmi;
 #endif  // CONFIG_MOTION_VAR || CONFIG_WARPED_MOTION