add support of config file

add the new implementation of the config file support to allow control
flags to be passed in from config file to turn on/off individual coding
tool for tool-on and tool-off tests.

Change-Id: I079bc768dbce5be7cc9d28dae6f346bc1ff26e0e
diff --git a/Sample.cfg b/Sample.cfg
new file mode 100644
index 0000000..d24663d
--- /dev/null
+++ b/Sample.cfg
@@ -0,0 +1,36 @@
+#sample config file
+super_block_size = 128                  # super block size. 0, 64 or 128
+max_partition_size = 128                # max partition size(8, 16, 32, 64, 128)
+min_partition_size = 4                  # min partition size(4, 8, 16, 32, 64)
+disable_rect_partition_type = 0         # disable rectangle partition type
+disable_ab_partition_type = 0           # disable AB partition type
+disable_1to4_partition_type = 0         # disable 1 to 4 and 4 to 1 partition type
+disable_intra_angle_delta = 0           # disable intra angle delta
+disable_paeth_intra = 0                 # disable paeth intra
+disable_smooth_intra = 0                # disable intra smooth mode
+disable_intra_edge_filter = 0           # disable intra edge filter
+disable_filter_intra = 0                # disable filter intra
+disable_intrabc = 0                     # disable Intra Block Copy
+disable_cfl = 0                         # disable chroma from luma prediction
+disable_palette = 0                     # disable Palette
+disable_flip_idtx = 0                   # disable flip and identity transform
+disable_tx_64x64 = 0                    # disable 64x64 transform
+reduced_tx_type_set = 0                 # use reduced transform type set
+tx_size_search_method = 0               # 0:FULL_RD, 1 : FAST_RD, 2 : USE_LARGEST
+reduced_reference_set = 0               # use reduced reference frame set
+disable_obmc = 0                        # disable OBMC
+disable_warp_motion = 0                 # disable Warped Motion
+disable_global_motion = 0               # disable global motion
+disable_ref_frame_mv = 0                # disable ref mv
+disable_dual_filter = 0                 # disable dual interpolation filter
+disable_one_sided_comp = 0              # disable one sided compound mode
+disable_masked_comp = 0                 # disable masked compound prediction
+disable_diff_wtd_comp = 0               # disable difference weighted compound mode
+disable_inter_inter_wedge = 0           # disable inter/inter wedge comp
+disable_dist_wtd_comp = 0               # disable distant weighted compound mode
+disable_inter_intra_comp = 0            # disable inter/intra compound mode.
+disable_inter_intra_wedge = 0           # disable inter/intra wedge comp
+disable_smooth_inter_intra = 0          # disable smooth inter/intra
+disable_cdef = 0                        # disable CDEF filter
+disable_lr = 0                          # disable Loop Restoration Filter
+disable_trellis_quant = 0               # disable trellis quantization
\ No newline at end of file
diff --git a/aom/aom_encoder.h b/aom/aom_encoder.h
index 9d02e8c..cad8d0f 100644
--- a/aom/aom_encoder.h
+++ b/aom/aom_encoder.h
@@ -41,7 +41,7 @@
  * fields to structures
  */
 #define AOM_ENCODER_ABI_VERSION \
-  (6 + AOM_CODEC_ABI_VERSION) /**<\hideinitializer*/
+  (7 + AOM_CODEC_ABI_VERSION) /**<\hideinitializer*/
 
 /*! \brief Encoder capabilities bitfield
  *
@@ -209,6 +209,158 @@
   AOM_KF_DISABLED = 0 /**< Encoder does not place keyframes. */
 };
 
+/*!\brief Encoder Config Options
+ *
+ * This type allows to enumerate and control flags defined for encoder control
+ * via config file at runtime.
+ */
+typedef struct cfg_options {
+  /*!\brief Indicate init by cfg file
+   * 0 or 1
+   */
+  unsigned int init_by_cfg_file;
+  /*!\brief Superblock size
+   * 0, 64 or 128
+   */
+  unsigned int super_block_size;
+  /*!\brief max partition size
+   * 8, 16, 32, 64, 128
+   */
+  unsigned int max_partition_size;
+  /*!\brief min partition size
+   * 8, 16, 32, 64, 128
+   */
+  unsigned int min_partition_size;
+  /*!\brief disable AB Shape partition type
+   *
+   */
+  unsigned int disable_ab_partition_type;
+  /*!\brief disable rectangular partition type
+   *
+   */
+  unsigned int disable_rect_partition_type;
+  /*!\brief disable 1:4/4:1 partition type
+   *
+   */
+  unsigned int disable_1to4_partition_type;
+  /*!\brief disable flip and identity transform type
+   *
+   */
+  unsigned int disable_flip_idtx;
+  /*!\brief disable CDEF filter
+   *
+   */
+  unsigned int disable_cdef;
+  /*!\brief disable Loop Restoration Filter
+   *
+   */
+  unsigned int disable_lr;
+  /*!\brief disable OBMC
+   *
+   */
+  unsigned int disable_obmc;
+  /*!\brief disable Warped Motion
+   *
+   */
+  unsigned int disable_warp_motion;
+  /*!\brief disable global motion
+   *
+   */
+  unsigned int disable_global_motion;
+  /*!\brief disable dist weighted compound
+   *
+   */
+  unsigned int disable_dist_wtd_comp;
+  /*!\brief disable diff weighted compound
+   *
+   */
+  unsigned int disable_diff_wtd_comp;
+  /*!\brief disable inter/intra compound
+   *
+   */
+  unsigned int disable_inter_intra_comp;
+  /*!\brief disable masked compound
+   *
+   */
+  unsigned int disable_masked_comp;
+  /*!\brief disable one sided compound
+   *
+   */
+  unsigned int disable_one_sided_comp;
+  /*!\brief disable Palette
+   *
+   */
+  unsigned int disable_palette;
+  /*!\brief disable Intra Block Copy
+   *
+   */
+  unsigned int disable_intrabc;
+  /*!\brief disable chroma from luma
+   *
+   */
+  unsigned int disable_cfl;
+  /*!\brief disable intra smooth mode
+   *
+   */
+  unsigned int disable_smooth_intra;
+  /*!\brief disable filter intra
+   *
+   */
+  unsigned int disable_filter_intra;
+  /*!\brief disable dual filter
+   *
+   */
+  unsigned int disable_dual_filter;
+  /*!\brief disable intra angle delta
+   *
+   */
+  unsigned int disable_intra_angle_delta;
+  /*!\brief specify transform size search method
+   * 0:FULLRD,1:FASTRD,2:USELARGEST
+   */
+  unsigned int tx_size_search_method;
+  /*!\brief disable intra edge filter
+   *
+   */
+  unsigned int disable_intra_edge_filter;
+  /*!\brief disable 64x64 transform
+   *
+   */
+  unsigned int disable_tx_64x64;
+  /*!\brief disable smooth inter/intra
+   *
+   */
+  unsigned int disable_smooth_inter_intra;
+  /*!\brief disable inter/inter wedge comp
+   *
+   */
+  unsigned int disable_inter_inter_wedge;
+  /*!\brief disable inter/intra wedge comp
+   *
+   */
+  unsigned int disable_inter_intra_wedge;
+  /*!\brief disable paeth intra
+   *
+   */
+  unsigned int disable_paeth_intra;
+  /*!\brief disable trellis quantization
+   *
+   */
+  unsigned int disable_trellis_quant;
+  /*!\brief disable ref frame MV
+   *
+   */
+  unsigned int disable_ref_frame_mv;
+  /*!\brief use reduced reference frame set
+   *
+   */
+  unsigned int reduced_reference_set;
+  /*!\brief use reduced transform type set
+   *
+   */
+  unsigned int reduced_tx_type_set;
+} cfg_options_t;
+
 /*!\brief Encoded Frame Flags
  *
  * This type indicates a bitfield to be passed to aom_codec_encode(), defining
@@ -723,6 +875,11 @@
    * The number of heights specified is given by tile_height_count
    */
   int tile_heights[MAX_TILE_HEIGHTS];
+
+  /*!\brief Options defined per config file
+   *
+   */
+  cfg_options_t encoder_cfg;
 } aom_codec_enc_cfg_t; /**< alias for struct aom_codec_enc_cfg */
 
 /*!\brief Initialize an encoder instance
diff --git a/aom/src/aom_encoder.c b/aom/src/aom_encoder.c
index fbe6823..c65d678 100644
--- a/aom/src/aom_encoder.c
+++ b/aom/src/aom_encoder.c
@@ -24,6 +24,8 @@
 
 #include <limits.h>
 #include <string.h>
+
+#include "aom/aom_encoder.h"
 #include "aom/internal/aom_codec_internal.h"
 
 #define SAVE_STATUS(ctx, var) (ctx ? (ctx->err = var) : var)
@@ -167,6 +169,17 @@
     }
   }
 
+#if CONFIG_OPTIONS_FILE
+  /* default values */
+  if (cfg) {
+    memset(&cfg->encoder_cfg, 0, sizeof(cfg->encoder_cfg));
+    cfg->encoder_cfg.super_block_size = 0;  // Dynamic
+    cfg->encoder_cfg.max_partition_size = 128;
+    cfg->encoder_cfg.min_partition_size = 4;
+    cfg->encoder_cfg.disable_trellis_quant = 3;
+  }
+#endif
+
   return res;
 }
 
diff --git a/apps/aomenc.c b/apps/aomenc.c
index 4e23aeb..9b06b28 100644
--- a/apps/aomenc.c
+++ b/apps/aomenc.c
@@ -158,6 +158,9 @@
     ARG_DEF("v", "verbose", 0, "Show encoder parameters");
 static const arg_def_t psnrarg =
     ARG_DEF(NULL, "psnr", 0, "Show PSNR in status line");
+#if CONFIG_OPTIONS_FILE
+static const arg_def_t use_cfg = ARG_DEF("c", "cfg", 1, "Config file to use");
+#endif
 
 static const struct arg_enum_list test_decode_enum[] = {
   { "off", TEST_DECODE_OFF },
@@ -200,6 +203,9 @@
     NULL, "input-chroma-subsampling-y", 1, "chroma subsampling y value.");
 
 static const arg_def_t *main_args[] = { &help,
+#if CONFIG_OPTIONS_FILE
+                                        &use_cfg,
+#endif
                                         &debugmode,
                                         &outputfile,
                                         &codecarg,
@@ -1112,6 +1118,16 @@
   if (!rat->den) die("Error: %s has zero denominator\n", msg);
 }
 
+#if CONFIG_OPTIONS_FILE
+static void init_config(cfg_options_t *config) {
+  memset(config, 0, sizeof(cfg_options_t));
+  config->super_block_size = 0;  // Dynamic
+  config->max_partition_size = 128;
+  config->min_partition_size = 4;
+  config->disable_trellis_quant = 3;
+}
+#endif
+
 /* Parses global config arguments into the AvxEncoderConfig. Note that
  * argv is modified and overwrites all parsed arguments.
  */
@@ -1129,8 +1145,22 @@
   global->color_type = I420;
   global->csp = AOM_CSP_UNKNOWN;
 
+#if CONFIG_OPTIONS_FILE
+  int cfg_included = 0;
+  init_config(&global->encoder_config);
+#endif
+
   for (argi = argj = argv_local; (*argj = *argi); argi += arg.argv_step) {
     arg.argv_step = 1;
+
+#if CONFIG_OPTIONS_FILE
+    if (arg_match(&arg, &use_cfg, argi)) {
+      if (cfg_included) continue;
+      parse_cfg(arg.val, &global->encoder_config);
+      cfg_included = 1;
+      continue;
+    }
+#endif
     if (arg_match(&arg, &help, argi)) {
       show_help(stdout, 0);
       exit(EXIT_SUCCESS);
@@ -1322,6 +1352,11 @@
 
     /* Allows removal of the application version from the EBML tags */
     stream->webm_ctx.debug = global->debug;
+
+#if CONFIG_OPTIONS_FILE
+    memcpy(&stream->config.cfg.encoder_cfg, &global->encoder_config,
+           sizeof(stream->config.cfg.encoder_cfg));
+#endif
   }
 
   /* Output files must be specified for each stream */
@@ -1709,6 +1744,47 @@
   SHOW(kf_mode);
   SHOW(kf_min_dist);
   SHOW(kf_max_dist);
+
+#if CONFIG_OPTIONS_FILE
+#define SHOW_PARAMS(field)                    \
+  fprintf(stderr, "    %-28s = %d\n", #field, \
+          stream->config.cfg.encoder_cfg.field)
+  SHOW_PARAMS(super_block_size);
+  SHOW_PARAMS(max_partition_size);
+  SHOW_PARAMS(min_partition_size);
+  SHOW_PARAMS(disable_ab_partition_type);
+  SHOW_PARAMS(disable_rect_partition_type);
+  SHOW_PARAMS(disable_1to4_partition_type);
+  SHOW_PARAMS(disable_flip_idtx);
+  SHOW_PARAMS(disable_cdef);
+  SHOW_PARAMS(disable_lr);
+  SHOW_PARAMS(disable_obmc);
+  SHOW_PARAMS(disable_warp_motion);
+  SHOW_PARAMS(disable_global_motion);
+  SHOW_PARAMS(disable_dist_wtd_comp);
+  SHOW_PARAMS(disable_diff_wtd_comp);
+  SHOW_PARAMS(disable_inter_intra_comp);
+  SHOW_PARAMS(disable_masked_comp);
+  SHOW_PARAMS(disable_one_sided_comp);
+  SHOW_PARAMS(disable_palette);
+  SHOW_PARAMS(disable_intrabc);
+  SHOW_PARAMS(disable_cfl);
+  SHOW_PARAMS(disable_smooth_intra);
+  SHOW_PARAMS(disable_filter_intra);
+  SHOW_PARAMS(disable_dual_filter);
+  SHOW_PARAMS(disable_intra_angle_delta);
+  SHOW_PARAMS(tx_size_search_method);
+  SHOW_PARAMS(disable_intra_edge_filter);
+  SHOW_PARAMS(disable_tx_64x64);
+  SHOW_PARAMS(disable_smooth_inter_intra);
+  SHOW_PARAMS(disable_inter_inter_wedge);
+  SHOW_PARAMS(disable_inter_intra_wedge);
+  SHOW_PARAMS(disable_paeth_intra);
+  SHOW_PARAMS(disable_trellis_quant);
+  SHOW_PARAMS(disable_ref_frame_mv);
+  SHOW_PARAMS(reduced_reference_set);
+  SHOW_PARAMS(reduced_tx_type_set);
+#endif
 }
 
 static void open_output_file(struct stream_state *stream,
@@ -2162,7 +2238,11 @@
   argv = argv_dup(argc - 1, argv_ + 1);
   parse_global_config(&global, &argv);
 
+#if CONFIG_OPTIONS_FILE
+  if (argc < 2) usage_exit();
+#else
   if (argc < 3) usage_exit();
+#endif
 
   switch (global.color_type) {
     case I420: input.fmt = AOM_IMG_FMT_I420; break;
diff --git a/apps/aomenc.h b/apps/aomenc.h
index 5e59c1a..ba7bf0a 100644
--- a/apps/aomenc.h
+++ b/apps/aomenc.h
@@ -11,6 +11,7 @@
 #ifndef AOM_APPS_AOMENC_H_
 #define AOM_APPS_AOMENC_H_
 
+#include "aom/aom_codec.h"
 #include "aom/aom_encoder.h"
 
 #ifdef __cplusplus
@@ -54,6 +55,7 @@
   int disable_warning_prompt;
   int experimental_bitstream;
   aom_chroma_sample_position_t csp;
+  cfg_options_t encoder_config;
 };
 
 #ifdef __cplusplus
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index db4cb36..21b82d6 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -586,9 +586,61 @@
   oxcf->superres_kf_qthresh = 255;
 }
 
-static aom_codec_err_t set_encoder_config(
-    AV1EncoderConfig *oxcf, const aom_codec_enc_cfg_t *cfg,
-    const struct av1_extracfg *extra_cfg) {
+#if CONFIG_OPTIONS_FILE
+static void update_default_encoder_config(const cfg_options_t *cfg,
+                                          struct av1_extracfg *extra_cfg) {
+  extra_cfg->enable_cdef = (cfg->disable_cdef == 0);
+  extra_cfg->enable_restoration = (cfg->disable_lr == 0);
+  extra_cfg->superblock_size = (cfg->super_block_size == 64)
+                                   ? AOM_SUPERBLOCK_SIZE_64X64
+                                   : (cfg->super_block_size == 128)
+                                         ? AOM_SUPERBLOCK_SIZE_128X128
+                                         : AOM_SUPERBLOCK_SIZE_DYNAMIC;
+  extra_cfg->enable_warped_motion = (cfg->disable_warp_motion == 0);
+  extra_cfg->enable_dist_wtd_comp = (cfg->disable_dist_wtd_comp == 0);
+  extra_cfg->enable_diff_wtd_comp = (cfg->disable_diff_wtd_comp == 0);
+  extra_cfg->enable_dual_filter = (cfg->disable_dual_filter == 0);
+  extra_cfg->enable_angle_delta = (cfg->disable_intra_angle_delta == 0);
+  extra_cfg->enable_rect_partitions = (cfg->disable_rect_partition_type == 0);
+  extra_cfg->enable_ab_partitions = (cfg->disable_ab_partition_type == 0);
+  extra_cfg->enable_1to4_partitions = (cfg->disable_1to4_partition_type == 0);
+  extra_cfg->max_partition_size = cfg->max_partition_size;
+  extra_cfg->min_partition_size = cfg->min_partition_size;
+  extra_cfg->enable_intra_edge_filter = (cfg->disable_intra_edge_filter == 0);
+  extra_cfg->enable_tx64 = (cfg->disable_tx_64x64 == 0);
+  extra_cfg->enable_flip_idtx = (cfg->disable_flip_idtx == 0);
+  extra_cfg->enable_masked_comp = (cfg->disable_masked_comp == 0);
+  extra_cfg->enable_interintra_comp = (cfg->disable_inter_intra_comp == 0);
+  extra_cfg->enable_smooth_interintra = (cfg->disable_smooth_inter_intra == 0);
+  extra_cfg->enable_interinter_wedge = (cfg->disable_inter_inter_wedge == 0);
+  extra_cfg->enable_interintra_wedge = (cfg->disable_inter_intra_wedge == 0);
+  extra_cfg->enable_global_motion = (cfg->disable_global_motion == 0);
+  extra_cfg->enable_filter_intra = (cfg->disable_filter_intra == 0);
+  extra_cfg->enable_smooth_intra = (cfg->disable_smooth_intra == 0);
+  extra_cfg->enable_paeth_intra = (cfg->disable_paeth_intra == 0);
+  extra_cfg->enable_cfl_intra = (cfg->disable_cfl == 0);
+  extra_cfg->enable_obmc = (cfg->disable_obmc == 0);
+  extra_cfg->enable_palette = (cfg->disable_palette == 0);
+  extra_cfg->enable_intrabc = (cfg->disable_intrabc == 0);
+  extra_cfg->disable_trellis_quant = cfg->disable_trellis_quant;
+  extra_cfg->allow_ref_frame_mvs = (cfg->disable_ref_frame_mv == 0);
+  extra_cfg->enable_ref_frame_mvs = (cfg->disable_ref_frame_mv == 0);
+  extra_cfg->enable_onesided_comp = (cfg->disable_one_sided_comp == 0);
+  extra_cfg->tx_size_search_method = cfg->tx_size_search_method;
+  extra_cfg->enable_reduced_reference_set = cfg->reduced_reference_set;
+  extra_cfg->reduced_tx_type_set = cfg->reduced_tx_type_set;
+}
+#endif
+
+static aom_codec_err_t set_encoder_config(AV1EncoderConfig *oxcf,
+                                          const aom_codec_enc_cfg_t *cfg,
+                                          struct av1_extracfg *extra_cfg) {
+#if CONFIG_OPTIONS_FILE
+  if (cfg->encoder_cfg.init_by_cfg_file) {
+    update_default_encoder_config(&cfg->encoder_cfg, extra_cfg);
+  }
+#endif
+
   const int is_vbr = cfg->rc_end_usage == AOM_VBR;
   oxcf->profile = cfg->g_profile;
   oxcf->fwd_kf_enabled = cfg->fwd_kf_enabled;
@@ -636,6 +688,9 @@
     oxcf->init_framerate = 30;
     oxcf->timing_info_present = 0;
   }
+#if CONFIG_OPTIONS_FILE
+  oxcf->encoder_cfg = &cfg->encoder_cfg;
+#endif
 
   switch (cfg->g_pass) {
     case AOM_RC_ONE_PASS: oxcf->pass = 0; break;
@@ -669,6 +724,7 @@
   oxcf->enable_intrabc = extra_cfg->enable_intrabc;
   oxcf->enable_angle_delta = extra_cfg->enable_angle_delta;
   oxcf->disable_trellis_quant = extra_cfg->disable_trellis_quant;
+  oxcf->allow_ref_frame_mvs = extra_cfg->enable_ref_frame_mvs;
   oxcf->using_qm = extra_cfg->enable_qm;
   oxcf->qm_y = extra_cfg->qm_y;
   oxcf->qm_u = extra_cfg->qm_u;
@@ -971,7 +1027,7 @@
 }
 
 static aom_codec_err_t update_extra_cfg(aom_codec_alg_priv_t *ctx,
-                                        const struct av1_extracfg *extra_cfg) {
+                                        struct av1_extracfg *extra_cfg) {
   const aom_codec_err_t res = validate_config(ctx, &ctx->cfg, extra_cfg);
   if (res == AOM_CODEC_OK) {
     ctx->extra_cfg = *extra_cfg;
@@ -2542,6 +2598,8 @@
         0,            // tile_height_count
         { 0 },        // tile_widths
         { 0 },        // tile_heights
+        { 0, 128, 128, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+          0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // cfg
     } },
   { 1,
     {
@@ -2609,6 +2667,8 @@
         0,            // tile_height_count
         { 0 },        // tile_widths
         { 0 },        // tile_heights
+        { 0, 128, 128, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+          0, 0,   0,   0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },  // cfg
     } },
 };
 
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 95f7035..7fb49f9 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -428,6 +428,9 @@
   unsigned int tier_mask;
   // min_cr / 100 is the target minimum compression ratio for each frame.
   unsigned int min_cr;
+#if CONFIG_OPTIONS_FILE
+  const cfg_options_t *encoder_cfg;
+#endif
 } AV1EncoderConfig;
 
 static INLINE int is_lossless_requested(const AV1EncoderConfig *cfg) {
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index 5a043ec..7328a24 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -96,6 +96,7 @@
                    "Coefficient range check.")
 set_aom_config_var(CONFIG_DENOISE 1
                    "Denoise/noise modeling support in encoder.")
+set_aom_config_var(CONFIG_OPTIONS_FILE 1 "Enables encoder config file support.")
 set_aom_config_var(CONFIG_INSPECTION 0 "Enables bitstream inspection.")
 set_aom_config_var(CONFIG_INTERNAL_STATS 0 "Enables internal encoder stats.")
 set_aom_config_var(FORCE_HIGHBITDEPTH_DECODING 0
diff --git a/common/args.c b/common/args.c
index 7131e24..bf0b469 100644
--- a/common/args.c
+++ b/common/args.c
@@ -17,6 +17,7 @@
 
 #include "aom/aom_integer.h"
 #include "aom_ports/msvc.h"
+#include "aom/aom_codec.h"
 
 #if defined(__GNUC__) && __GNUC__
 extern void die(const char *fmt, ...) __attribute__((noreturn));
@@ -48,20 +49,31 @@
   if (end >= str) end[1] = '\0';
 }
 
-int arg_cfg(int *argc, char ***argv, const char *file) {
-  char **argv_local = (char **)*argv;
-  char **argv_org = (char **)*argv;
+static const char kSbSizeWarningString[] =
+    "super_block_size has to be 64 or 128.";
+static const char kMinpartWarningString[] =
+    "min_partition_size has to be smaller or equal to max_partition_size.";
+static const char kMaxpartWarningString[] =
+    "max_partition_size has to be smaller or equal to super_block_size.";
+
+int parse_cfg(const char *file, cfg_options_t *pConfig) {
   char line[1024 * 10];
   FILE *f = fopen(file, "r");
   if (!f) return 1;
 
+#define GET_PARAMS(field)          \
+  if (strcmp(left, #field) == 0) { \
+    pConfig->field = atoi(right);  \
+    continue;                      \
+  }
+
   while (fgets(line, sizeof(line) - 1, f)) {
     char *actual_line = ignore_front_spaces(line);
     char *left, *right, *comment;
     size_t length = strlen(actual_line);
 
     if (length == 0 || actual_line[0] == '#') continue;
-    right = strchr(actual_line, ':');
+    right = strchr(actual_line, '=');
     if (right == NULL) continue;
     right[0] = '\0';
 
@@ -74,23 +86,62 @@
     ignore_end_spaces(left);
     ignore_end_spaces(right);
 
-    char **new_args = argv_dup(*argc, (const char **)argv_local);
-    char *new_line = (char *)malloc(sizeof(*new_line) * 128);
+    GET_PARAMS(super_block_size);
+    GET_PARAMS(max_partition_size);
+    GET_PARAMS(min_partition_size);
+    GET_PARAMS(disable_ab_partition_type);
+    GET_PARAMS(disable_rect_partition_type);
+    GET_PARAMS(disable_1to4_partition_type);
+    GET_PARAMS(disable_flip_idtx);
+    GET_PARAMS(disable_cdef);
+    GET_PARAMS(disable_lr);
+    GET_PARAMS(disable_obmc);
+    GET_PARAMS(disable_warp_motion);
+    GET_PARAMS(disable_global_motion);
+    GET_PARAMS(disable_dist_wtd_comp);
+    GET_PARAMS(disable_diff_wtd_comp);
+    GET_PARAMS(disable_inter_intra_comp);
+    GET_PARAMS(disable_masked_comp);
+    GET_PARAMS(disable_one_sided_comp);
+    GET_PARAMS(disable_palette);
+    GET_PARAMS(disable_intrabc);
+    GET_PARAMS(disable_cfl);
+    GET_PARAMS(disable_smooth_intra);
+    GET_PARAMS(disable_filter_intra);
+    GET_PARAMS(disable_dual_filter);
+    GET_PARAMS(disable_intra_angle_delta);
+    GET_PARAMS(tx_size_search_method);
+    GET_PARAMS(disable_intra_edge_filter);
+    GET_PARAMS(disable_tx_64x64);
+    GET_PARAMS(disable_smooth_inter_intra);
+    GET_PARAMS(disable_inter_inter_wedge);
+    GET_PARAMS(disable_inter_intra_wedge);
+    GET_PARAMS(disable_paeth_intra);
+    GET_PARAMS(disable_trellis_quant);
+    GET_PARAMS(disable_ref_frame_mv);
+    GET_PARAMS(reduced_reference_set);
+    GET_PARAMS(reduced_tx_type_set);
 
-    if (argv_local != argv_org) free(argv_local);
-
-    if (!strcmp(right, "ON"))
-      snprintf(new_line, sizeof(*new_line) * 128, "--%s", left);
-    else
-      snprintf(new_line, sizeof(*new_line) * 128, "--%s=%s", left, right);
-
-    new_args[(*argc) - 1] = new_args[(*argc) - 2];
-    new_args[(*argc) - 2] = new_line;
-    argv_local = new_args;
-    *argv = new_args;
-    (*argc)++;
+    fprintf(stderr, "\nInvalid parameter: %s", left);
+    exit(-1);
   }
+
+  if (pConfig->super_block_size != 128 && pConfig->super_block_size != 64) {
+    fprintf(stderr, "\n%s", kSbSizeWarningString);
+    exit(-1);
+  }
+  if (pConfig->min_partition_size > pConfig->max_partition_size) {
+    fprintf(stderr, "\n%s", kMinpartWarningString);
+    exit(-1);
+  }
+  if (pConfig->max_partition_size > pConfig->super_block_size) {
+    fprintf(stderr, "\n%s", kMaxpartWarningString);
+    exit(-1);
+  }
+
   fclose(f);
+  pConfig->init_by_cfg_file = 1;
+
   return 0;
 }
 
@@ -209,10 +260,6 @@
   return 0;
 }
 
-struct aom_rational {
-  int num; /**< fraction numerator */
-  int den; /**< fraction denominator */
-};
 struct aom_rational arg_parse_rational(const struct arg *arg) {
   long int rawval;
   char *endptr;
diff --git a/common/args.h b/common/args.h
index 6a26642..fc289cf 100644
--- a/common/args.h
+++ b/common/args.h
@@ -13,6 +13,9 @@
 #define AOM_COMMON_ARGS_H_
 #include <stdio.h>
 
+#include "aom/aom_codec.h"
+#include "aom/aom_encoder.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -50,7 +53,7 @@
 int arg_match(struct arg *arg_, const struct arg_def *def, char **argv);
 char *ignore_front_spaces(const char *str);
 void ignore_end_spaces(char *str);
-int arg_cfg(int *argc, char ***argv, const char *file);
+int parse_cfg(const char *file, cfg_options_t *pConfig);
 const char *arg_next(struct arg *arg);
 void arg_show_usage(FILE *fp, const struct arg_def *const *defs);
 char **argv_dup(int argc, const char **argv);