Add enc option and RDO logic to disable smooth interintra mode

Add a commandline option: --enable-smooth-interintra
By default, --enable-smooth-interintra=1, meaning aomenc will allow
and try smooth interintra mode.
When --enable-smooth-interintra=0 is specified, aomenc will omit
smooth interintra mode in RDO therefore smooth interintra mode will
not be used at all. New logic for only testing wedge interintra is
also added.

Change-Id: Idcf306207534b7bacd95fe8c0c4c7c5feca23495
diff --git a/aom/aomcx.h b/aom/aomcx.h
index b2b3753..3fd7290 100644
--- a/aom/aomcx.h
+++ b/aom/aomcx.h
@@ -785,6 +785,15 @@
    */
   AV1E_SET_ENABLE_INTERINTRA_COMP,
 
+  /*!\brief Codec control function to turn on / off smooth inter-intra
+   * mode for a sequence.
+   *
+   * This will enable or disable usage of smooth inter-intra mode.
+   * The default value is 1.
+   *
+   */
+  AV1E_SET_ENABLE_SMOOTH_INTERINTRA,
+
   /*!\brief Codec control function to turn on / off difference weighted
    * compound.
    *
@@ -1141,6 +1150,9 @@
 AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_INTERINTRA_COMP, unsigned int)
 #define AOM_CTRL_AV1E_SET_ENABLE_INTERINTRA_COMP
 
+AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_SMOOTH_INTERINTRA, unsigned int)
+#define AOM_CTRL_AV1E_SET_ENABLE_SMOOTH_INTERINTRA
+
 AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_DIFF_WTD_COMP, unsigned int)
 #define AOM_CTRL_AV1E_SET_ENABLE_DIFF_WTD_COMP
 
diff --git a/apps/aomenc.c b/apps/aomenc.c
index 5cfb341..558983f 100644
--- a/apps/aomenc.c
+++ b/apps/aomenc.c
@@ -457,6 +457,10 @@
     ARG_DEF(NULL, "enable-interintra-comp", 1,
             "Enable interintra compound "
             "(0: false, 1: true (default))");
+static const arg_def_t enable_smooth_interintra =
+    ARG_DEF(NULL, "enable-smooth-interintra", 1,
+            "Enable smooth interintra mode "
+            "(0: false, 1: true (default))");
 static const arg_def_t enable_diff_wtd_comp =
     ARG_DEF(NULL, "enable-diff-wtd-comp", 1,
             "Enable difference-weighted compound "
@@ -691,6 +695,7 @@
                                        &enable_dist_wtd_comp,
                                        &enable_masked_comp,
                                        &enable_interintra_comp,
+                                       &enable_smooth_interintra,
                                        &enable_diff_wtd_comp,
                                        &enable_interinter_wedge,
                                        &enable_interintra_wedge,
@@ -762,6 +767,7 @@
                                         AV1E_SET_ENABLE_DIST_WTD_COMP,
                                         AV1E_SET_ENABLE_MASKED_COMP,
                                         AV1E_SET_ENABLE_INTERINTRA_COMP,
+                                        AV1E_SET_ENABLE_SMOOTH_INTERINTRA,
                                         AV1E_SET_ENABLE_DIFF_WTD_COMP,
                                         AV1E_SET_ENABLE_INTERINTER_WEDGE,
                                         AV1E_SET_ENABLE_INTERINTRA_WEDGE,
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index c31e77f..7381d61 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -96,16 +96,17 @@
   unsigned int cdf_update_mode;
   int enable_order_hint;
   int enable_dist_wtd_comp;
-  int enable_ref_frame_mvs;     // sequence level
-  int allow_ref_frame_mvs;      // frame level
-  int enable_masked_comp;       // enable masked compound for sequence
-  int enable_interintra_comp;   // enable interintra compound for sequence
-  int enable_diff_wtd_comp;     // enable diff-wtd compound usage
-  int enable_interinter_wedge;  // enable interinter-wedge compound usage
-  int enable_interintra_wedge;  // enable interintra-wedge compound usage
-  int enable_global_motion;     // enable global motion usage for sequence
-  int enable_warped_motion;     // sequence level
-  int allow_warped_motion;      // frame level
+  int enable_ref_frame_mvs;      // sequence level
+  int allow_ref_frame_mvs;       // frame level
+  int enable_masked_comp;        // enable masked compound for sequence
+  int enable_interintra_comp;    // enable interintra compound for sequence
+  int enable_smooth_interintra;  // enable smooth interintra mode usage
+  int enable_diff_wtd_comp;      // enable diff-wtd compound usage
+  int enable_interinter_wedge;   // enable interinter-wedge compound usage
+  int enable_interintra_wedge;   // enable interintra-wedge compound usage
+  int enable_global_motion;      // enable global motion usage for sequence
+  int enable_warped_motion;      // sequence level
+  int allow_warped_motion;       // frame level
   int enable_filter_intra;
   int enable_superres;
 #if CONFIG_DENOISE
@@ -183,6 +184,7 @@
   1,                            // allow ref_frame_mvs frame level
   1,                            // enable masked compound at sequence level
   1,                            // enable interintra compound at sequence level
+  1,                            // enable smooth interintra mode
   1,                            // enable difference-weighted compound
   1,                            // enable interinter wedge compound
   1,                            // enable interintra wedge compound
@@ -689,6 +691,8 @@
   oxcf->enable_interinter_wedge =
       extra_cfg->enable_masked_comp & extra_cfg->enable_interinter_wedge;
   oxcf->enable_interintra_comp = extra_cfg->enable_interintra_comp;
+  oxcf->enable_smooth_interintra =
+      extra_cfg->enable_interintra_comp && extra_cfg->enable_smooth_interintra;
   oxcf->enable_interintra_wedge =
       extra_cfg->enable_interintra_comp & extra_cfg->enable_interintra_wedge;
   oxcf->enable_ref_frame_mvs =
@@ -1094,6 +1098,14 @@
   return update_extra_cfg(ctx, &extra_cfg);
 }
 
+static aom_codec_err_t ctrl_set_enable_smooth_interintra(
+    aom_codec_alg_priv_t *ctx, va_list args) {
+  struct av1_extracfg extra_cfg = ctx->extra_cfg;
+  extra_cfg.enable_smooth_interintra =
+      CAST(AV1E_SET_ENABLE_SMOOTH_INTERINTRA, args);
+  return update_extra_cfg(ctx, &extra_cfg);
+}
+
 static aom_codec_err_t ctrl_set_enable_diff_wtd_comp(aom_codec_alg_priv_t *ctx,
                                                      va_list args) {
   struct av1_extracfg extra_cfg = ctx->extra_cfg;
@@ -1887,6 +1899,7 @@
   { AV1E_SET_ALLOW_REF_FRAME_MVS, ctrl_set_allow_ref_frame_mvs },
   { AV1E_SET_ENABLE_MASKED_COMP, ctrl_set_enable_masked_comp },
   { AV1E_SET_ENABLE_INTERINTRA_COMP, ctrl_set_enable_interintra_comp },
+  { AV1E_SET_ENABLE_SMOOTH_INTERINTRA, ctrl_set_enable_smooth_interintra },
   { AV1E_SET_ENABLE_DIFF_WTD_COMP, ctrl_set_enable_diff_wtd_comp },
   { AV1E_SET_ENABLE_INTERINTER_WEDGE, ctrl_set_enable_interinter_wedge },
   { AV1E_SET_ENABLE_INTERINTRA_WEDGE, ctrl_set_enable_interintra_wedge },
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index f750316..f1a2750 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -328,6 +328,7 @@
   unsigned int allow_ref_frame_mvs;
   int enable_masked_comp;
   int enable_interintra_comp;
+  int enable_smooth_interintra;
   int enable_diff_wtd_comp;
   int enable_interinter_wedge;
   int enable_interintra_wedge;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index 34918ad..5299d85 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -8731,7 +8731,8 @@
   MACROBLOCKD *xd = &x->e_mbd;
 
   INTERINTRA_MODE best_interintra_mode = II_DC_PRED;
-  int64_t rd, best_interintra_rd = INT64_MAX;
+  int64_t rd = INT64_MAX;
+  int64_t best_interintra_rd = INT64_MAX;
   int rmode, rate_sum;
   int64_t dist_sum;
   int tmp_rate_mv = 0;
@@ -8754,42 +8755,45 @@
 
   restore_dst_buf(xd, *orig_dst, num_planes);
   mbmi->ref_frame[1] = INTRA_FRAME;
-  mbmi->use_wedge_interintra = 0;
   best_interintra_mode = args->inter_intra_mode[mbmi->ref_frame[0]];
-  int j = 0;
-  if (cpi->sf.reuse_inter_intra_mode == 0 ||
-      best_interintra_mode == INTERINTRA_MODES) {
-    for (j = 0; j < INTERINTRA_MODES; ++j) {
-      mbmi->interintra_mode = (INTERINTRA_MODE)j;
+
+  if (cpi->oxcf.enable_smooth_interintra) {
+    mbmi->use_wedge_interintra = 0;
+    int j = 0;
+    if (cpi->sf.reuse_inter_intra_mode == 0 ||
+        best_interintra_mode == INTERINTRA_MODES) {
+      for (j = 0; j < INTERINTRA_MODES; ++j) {
+        mbmi->interintra_mode = (INTERINTRA_MODE)j;
+        rmode = interintra_mode_cost[mbmi->interintra_mode];
+        av1_build_intra_predictors_for_interintra(cm, xd, bsize, 0, orig_dst,
+                                                  intrapred, bw);
+        av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
+        model_rd_sb_fn[MODELRD_TYPE_INTERINTRA](
+            cpi, bsize, x, xd, 0, 0, mi_row, mi_col, &rate_sum, &dist_sum,
+            &tmp_skip_txfm_sb, &tmp_skip_sse_sb, NULL, NULL, NULL);
+        rd = RDCOST(x->rdmult, tmp_rate_mv + rate_sum + rmode, dist_sum);
+        if (rd < best_interintra_rd) {
+          best_interintra_rd = rd;
+          best_interintra_mode = mbmi->interintra_mode;
+        }
+      }
+      args->inter_intra_mode[mbmi->ref_frame[0]] = best_interintra_mode;
+    }
+    if (j == 0 || best_interintra_mode != II_SMOOTH_PRED) {
+      mbmi->interintra_mode = best_interintra_mode;
       rmode = interintra_mode_cost[mbmi->interintra_mode];
       av1_build_intra_predictors_for_interintra(cm, xd, bsize, 0, orig_dst,
                                                 intrapred, bw);
       av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
-      model_rd_sb_fn[MODELRD_TYPE_INTERINTRA](
-          cpi, bsize, x, xd, 0, 0, mi_row, mi_col, &rate_sum, &dist_sum,
-          &tmp_skip_txfm_sb, &tmp_skip_sse_sb, NULL, NULL, NULL);
-      rd = RDCOST(x->rdmult, tmp_rate_mv + rate_sum + rmode, dist_sum);
-      if (rd < best_interintra_rd) {
-        best_interintra_rd = rd;
-        best_interintra_mode = mbmi->interintra_mode;
-      }
     }
-    args->inter_intra_mode[mbmi->ref_frame[0]] = best_interintra_mode;
-  }
-  if (j == 0 || best_interintra_mode != II_SMOOTH_PRED) {
-    mbmi->interintra_mode = best_interintra_mode;
-    rmode = interintra_mode_cost[mbmi->interintra_mode];
-    av1_build_intra_predictors_for_interintra(cm, xd, bsize, 0, orig_dst,
-                                              intrapred, bw);
-    av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
-  }
-  rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
-                           &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
-  if (rd != INT64_MAX)
-    rd = RDCOST(x->rdmult, *rate_mv + rmode + rate_sum + rwedge, dist_sum);
-  best_interintra_rd = rd;
-  if (ref_best_rd < INT64_MAX && (best_interintra_rd >> 1) > ref_best_rd) {
-    return -1;
+    rd = estimate_yrd_for_sb(cpi, bsize, x, &rate_sum, &dist_sum,
+                             &tmp_skip_txfm_sb, &tmp_skip_sse_sb, INT64_MAX);
+    if (rd != INT64_MAX)
+      rd = RDCOST(x->rdmult, *rate_mv + rmode + rate_sum + rwedge, dist_sum);
+    best_interintra_rd = rd;
+    if (ref_best_rd < INT64_MAX && (best_interintra_rd >> 1) > ref_best_rd) {
+      return -1;
+    }
   }
   if (is_wedge_used) {
     int64_t best_interintra_rd_nowedge = rd;
@@ -8801,9 +8805,51 @@
       rwedge = av1_cost_literal(get_interintra_wedge_bits(bsize)) +
                x->wedge_interintra_cost[bsize][1];
 
-      best_interintra_rd_wedge =
-          pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
+      if (!cpi->oxcf.enable_smooth_interintra) {
+        if (best_interintra_mode == INTERINTRA_MODES) {
+          mbmi->interintra_mode = II_SMOOTH_PRED;
+          best_interintra_mode = II_SMOOTH_PRED;
+          av1_build_intra_predictors_for_interintra(cm, xd, bsize, 0, orig_dst,
+                                                    intrapred, bw);
+          best_interintra_rd_wedge =
+              pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
 
+          int j = 0;
+          for (j = 0; j < INTERINTRA_MODES; ++j) {
+            mbmi->interintra_mode = (INTERINTRA_MODE)j;
+            rmode = interintra_mode_cost[mbmi->interintra_mode];
+            av1_build_intra_predictors_for_interintra(cm, xd, bsize, 0,
+                                                      orig_dst, intrapred, bw);
+            av1_combine_interintra(xd, bsize, 0, tmp_buf, bw, intrapred, bw);
+            model_rd_sb_fn[MODELRD_TYPE_INTERINTRA](
+                cpi, bsize, x, xd, 0, 0, mi_row, mi_col, &rate_sum, &dist_sum,
+                &tmp_skip_txfm_sb, &tmp_skip_sse_sb, NULL, NULL, NULL);
+            rd = RDCOST(x->rdmult, tmp_rate_mv + rate_sum + rmode, dist_sum);
+            if (rd < best_interintra_rd) {
+              best_interintra_rd_wedge = rd;
+              best_interintra_mode = mbmi->interintra_mode;
+            }
+          }
+          args->inter_intra_mode[mbmi->ref_frame[0]] = best_interintra_mode;
+          mbmi->interintra_mode = best_interintra_mode;
+
+          if (best_interintra_mode != II_SMOOTH_PRED) {
+            av1_build_intra_predictors_for_interintra(cm, xd, bsize, 0,
+                                                      orig_dst, intrapred, bw);
+          }
+        } else {
+          mbmi->interintra_mode = best_interintra_mode;
+          av1_build_intra_predictors_for_interintra(cm, xd, bsize, 0, orig_dst,
+                                                    intrapred, bw);
+          best_interintra_rd_wedge =
+              pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
+        }
+      } else {
+        best_interintra_rd_wedge =
+            pick_interintra_wedge(cpi, x, bsize, intrapred_, tmp_buf_);
+      }
+
+      rmode = interintra_mode_cost[mbmi->interintra_mode];
       best_interintra_rd_wedge +=
           RDCOST(x->rdmult, rmode + *rate_mv + rwedge, 0);
       rd = INT64_MAX;