Add command line option to disable OBMC

Add a commandline option: --enable-obmc
By default, --enable-obmc=1, meaning aomenc will allow and try
OBMC prediction mode.
When --enable-obmc=0 is specified, aomenc will omit OBMC mode in
RDO therefore OBMC mode will not be used at all.

Change-Id: I91f8c82bf6e3918e795a06e9f5844ea7fad6794e
diff --git a/aom/aomcx.h b/aom/aomcx.h
index b41de2d..360d302 100644
--- a/aom/aomcx.h
+++ b/aom/aomcx.h
@@ -561,6 +561,16 @@
    */
   AV1E_SET_ENABLE_RESTORATION,
 
+  /*!\brief Codec control function to predict with OBMC mode.
+   *
+   *                          0 = do not allow OBMC mode
+   *                          1 = allow OBMC mode
+   *
+   *  By default, the encoder allows OBMC prediction mode.
+   *
+   */
+  AV1E_SET_ENABLE_OBMC,
+
   /*!\brief Codec control function to encode without trellis quantization.
    *
    *                          0 = apply trellis quantization
@@ -1023,6 +1033,9 @@
 AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_RESTORATION, unsigned int)
 #define AOM_CTRL_AV1E_SET_ENABLE_RESTORATION
 
+AOM_CTRL_USE_TYPE(AV1E_SET_ENABLE_OBMC, unsigned int)
+#define AOM_CTRL_AV1E_SET_ENABLE_OBMC
+
 AOM_CTRL_USE_TYPE(AV1E_SET_DISABLE_TRELLIS_QUANT, unsigned int)
 #define AOM_CTRL_AV1E_SET_DISABLE_TRELLIS_QUANT
 
diff --git a/apps/aomenc.c b/apps/aomenc.c
index 025e519..343e852 100644
--- a/apps/aomenc.c
+++ b/apps/aomenc.c
@@ -457,6 +457,8 @@
     ARG_DEF(NULL, "enable-warped-motion", 1,
             "Enable local warped motion "
             "(0: false, 1: true (default))");
+static const arg_def_t enable_obmc = ARG_DEF(
+    NULL, "enable-obmc", 1, "Enable OBMC (0: false, 1: true (default))");
 static const arg_def_t disable_trellis_quant =
     ARG_DEF(NULL, "disable-trellis-quant", 1,
             "Disable trellis optimization of quantized coefficients (0: false ("
@@ -663,6 +665,7 @@
                                        &enable_interintra_comp,
                                        &enable_global_motion,
                                        &enable_warped_motion,
+                                       &enable_obmc,
                                        &disable_trellis_quant,
                                        &enable_qm,
                                        &qm_min,
@@ -726,6 +729,7 @@
                                         AV1E_SET_ENABLE_INTERINTRA_COMP,
                                         AV1E_SET_ENABLE_GLOBAL_MOTION,
                                         AV1E_SET_ENABLE_WARPED_MOTION,
+                                        AV1E_SET_ENABLE_OBMC,
                                         AV1E_SET_DISABLE_TRELLIS_QUANT,
                                         AV1E_SET_ENABLE_QM,
                                         AV1E_SET_QM_MIN,
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index e7d3d45..7a094ea 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -56,6 +56,7 @@
   unsigned int lossless;
   unsigned int enable_cdef;
   unsigned int enable_restoration;
+  unsigned int enable_obmc;
   unsigned int disable_trellis_quant;
   unsigned int enable_qm;
   unsigned int qm_y;
@@ -135,6 +136,7 @@
   0,                       // lossless
   !CONFIG_SHARP_SETTINGS,  // enable_cdef
   1,                       // enable_restoration
+  1,                       // enable_obmc
   0,                       // disable_trellis_quant
   0,                       // enable_qm
   DEFAULT_QM_Y,            // qm_y
@@ -528,6 +530,7 @@
 
   oxcf->enable_cdef = extra_cfg->enable_cdef;
   oxcf->enable_restoration = extra_cfg->enable_restoration;
+  oxcf->enable_obmc = extra_cfg->enable_obmc;
   oxcf->disable_trellis_quant = extra_cfg->disable_trellis_quant;
   oxcf->using_qm = extra_cfg->enable_qm;
   oxcf->qm_y = extra_cfg->qm_y;
@@ -948,6 +951,13 @@
   return update_extra_cfg(ctx, &extra_cfg);
 }
 
+static aom_codec_err_t ctrl_set_enable_obmc(aom_codec_alg_priv_t *ctx,
+                                            va_list args) {
+  struct av1_extracfg extra_cfg = ctx->extra_cfg;
+  extra_cfg.enable_obmc = CAST(AV1E_SET_ENABLE_OBMC, args);
+  return update_extra_cfg(ctx, &extra_cfg);
+}
+
 static aom_codec_err_t ctrl_set_disable_trellis_quant(aom_codec_alg_priv_t *ctx,
                                                       va_list args) {
   struct av1_extracfg extra_cfg = ctx->extra_cfg;
@@ -1798,6 +1808,7 @@
   { AV1E_SET_LOSSLESS, ctrl_set_lossless },
   { AV1E_SET_ENABLE_CDEF, ctrl_set_enable_cdef },
   { AV1E_SET_ENABLE_RESTORATION, ctrl_set_enable_restoration },
+  { AV1E_SET_ENABLE_OBMC, ctrl_set_enable_obmc },
   { AV1E_SET_DISABLE_TRELLIS_QUANT, ctrl_set_disable_trellis_quant },
   { AV1E_SET_ENABLE_QM, ctrl_set_enable_qm },
   { AV1E_SET_QM_Y, ctrl_set_qm_y },
diff --git a/av1/encoder/encodeframe.c b/av1/encoder/encodeframe.c
index 2247809..33fd852 100644
--- a/av1/encoder/encodeframe.c
+++ b/av1/encoder/encodeframe.c
@@ -6363,8 +6363,10 @@
     }
 
     av1_build_inter_predictors_sb(cm, xd, mi_row, mi_col, NULL, bsize);
-    if (mbmi->motion_mode == OBMC_CAUSAL)
+    if (mbmi->motion_mode == OBMC_CAUSAL) {
+      assert(cpi->oxcf.enable_obmc == 1);
       av1_build_obmc_inter_predictors_sb(cm, xd, mi_row, mi_col);
+    }
 
 #if CONFIG_MISMATCH_DEBUG
     if (dry_run == OUTPUT_ENABLED) {
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 53c74e9..3fbb0ce 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -215,6 +215,7 @@
   DELTAQ_MODE deltaq_mode;
   int enable_cdef;
   int enable_restoration;
+  int enable_obmc;
   int disable_trellis_quant;
   int using_qm;
   int qm_y;
diff --git a/av1/encoder/rdopt.c b/av1/encoder/rdopt.c
index ffdaf1c..4863c7b 100644
--- a/av1/encoder/rdopt.c
+++ b/av1/encoder/rdopt.c
@@ -9005,6 +9005,9 @@
       assert(mbmi->ref_frame[1] != INTRA_FRAME);
     }
 
+    if (cpi->oxcf.enable_obmc == 0 && mbmi->motion_mode == OBMC_CAUSAL)
+      continue;
+
     if (identical_obmc_mv_field_detected) {
       if (cpi->sf.skip_obmc_in_uniform_mv_field &&
           mbmi->motion_mode == OBMC_CAUSAL)