Add additional encoder ext_tile tests

Added additional ext_tile tests in the encoder to make sure the
correctness of large scale tile encoding. The tests include frame
header testing and frame context testing for camera frames.

Change-Id: Ib6ea76dd5a306421ba46292b6677389f4582e4b3
diff --git a/aom/aomcx.h b/aom/aomcx.h
index 8b4207d..a8202fd 100644
--- a/aom/aomcx.h
+++ b/aom/aomcx.h
@@ -1182,6 +1182,13 @@
    * tuning the encoder for VMAF.
    */
   AV1E_SET_VMAF_MODEL_PATH = 153,
+
+  /*!\brief Codec control function to enable EXT_TILE_DEBUG in AV1 encoder.
+   * Please note that this is only used in lightfield example test.
+   *
+   * 0 : off, 1 : enable EXT_TILE_DEBUG
+   */
+  AV1E_ENABLE_EXT_TILE_DEBUG = 154,
 };
 
 /*!\brief aom 1-D scaling mode
@@ -1590,6 +1597,9 @@
 AOM_CTRL_USE_TYPE(AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, unsigned int)
 #define AOM_CTRL_AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST
 
+AOM_CTRL_USE_TYPE(AV1E_ENABLE_EXT_TILE_DEBUG, unsigned int)
+#define AOM_CTRL_AV1E_ENABLE_EXT_TILE_DEBUG
+
 AOM_CTRL_USE_TYPE(AV1E_SET_VMAF_MODEL_PATH, const char *)
 #define AOM_CTRL_AV1E_SET_VMAF_MODEL_PATH
 
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 4ad0d6b..728c36d 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -152,6 +152,7 @@
   COST_UPDATE_TYPE coeff_cost_upd_freq;
   COST_UPDATE_TYPE mode_cost_upd_freq;
   COST_UPDATE_TYPE mv_cost_upd_freq;
+  unsigned int ext_tile_debug;
 };
 
 static struct av1_extracfg default_extra_cfg = {
@@ -277,6 +278,7 @@
   COST_UPD_SB,  // coeff_cost_upd_freq
   COST_UPD_SB,  // mode_cost_upd_freq
   COST_UPD_SB,  // mv_cost_upd_freq
+  0,            // ext_tile_debug
 };
 
 struct aom_codec_alg_priv {
@@ -422,6 +424,7 @@
         "or kf_max_dist instead.");
 
   RANGE_CHECK_HI(extra_cfg, motion_vector_unit_test, 2);
+  RANGE_CHECK_HI(extra_cfg, ext_tile_debug, 1);
   RANGE_CHECK_HI(extra_cfg, enable_auto_alt_ref, 1);
   RANGE_CHECK_HI(extra_cfg, enable_auto_bwd_ref, 2);
   RANGE_CHECK(extra_cfg, cpu_used, 0, 8);
@@ -963,6 +966,7 @@
 
   oxcf->frame_periodic_boost = extra_cfg->frame_periodic_boost;
   oxcf->motion_vector_unit_test = extra_cfg->motion_vector_unit_test;
+  oxcf->ext_tile_debug = extra_cfg->ext_tile_debug;
 
   oxcf->chroma_subsampling_x = extra_cfg->chroma_subsampling_x;
   oxcf->chroma_subsampling_y = extra_cfg->chroma_subsampling_y;
@@ -1724,6 +1728,13 @@
   return update_extra_cfg(ctx, &extra_cfg);
 }
 
+static aom_codec_err_t ctrl_enable_ext_tile_debug(aom_codec_alg_priv_t *ctx,
+                                                  va_list args) {
+  struct av1_extracfg extra_cfg = ctx->extra_cfg;
+  extra_cfg.ext_tile_debug = CAST(AV1E_ENABLE_EXT_TILE_DEBUG, args);
+  return update_extra_cfg(ctx, &extra_cfg);
+}
+
 static aom_codec_err_t ctrl_set_target_seq_level_idx(aom_codec_alg_priv_t *ctx,
                                                      va_list args) {
   struct av1_extracfg extra_cfg = ctx->extra_cfg;
@@ -2655,6 +2666,7 @@
   { AV1E_SET_DENOISE_NOISE_LEVEL, ctrl_set_denoise_noise_level },
   { AV1E_SET_DENOISE_BLOCK_SIZE, ctrl_set_denoise_block_size },
   { AV1E_ENABLE_MOTION_VECTOR_UNIT_TEST, ctrl_enable_motion_vector_unit_test },
+  { AV1E_ENABLE_EXT_TILE_DEBUG, ctrl_enable_ext_tile_debug },
   { AV1E_SET_TARGET_SEQ_LEVEL_IDX, ctrl_set_target_seq_level_idx },
   { AV1E_SET_TIER_MASK, ctrl_set_tier_mask },
   { AV1E_SET_MIN_CR, ctrl_set_min_cr },
diff --git a/av1/common/debugmodes.c b/av1/common/debugmodes.c
index 50d1e60..8306f29 100644
--- a/av1/common/debugmodes.c
+++ b/av1/common/debugmodes.c
@@ -93,6 +93,13 @@
                                          const char *filename) {
   FILE *hdrFile = fopen(filename, "w");
   fwrite(data, size, sizeof(uint8_t), hdrFile);
+
+  // Reset order hints(7bit + a previous bit) to 0, so that all camera frame
+  // headers are identical in large scale coding.
+  uint8_t zero = 0;
+  fseek(hdrFile, 1, SEEK_SET);
+  // Reset second byte.
+  fwrite(&zero, 1, sizeof(uint8_t), hdrFile);
   fclose(hdrFile);
 }
 
diff --git a/av1/encoder/bitstream.c b/av1/encoder/bitstream.c
index 59e2e7b..b34c48c 100644
--- a/av1/encoder/bitstream.c
+++ b/av1/encoder/bitstream.c
@@ -3437,6 +3437,9 @@
   size_t total_length;
 } FrameHeaderInfo;
 
+extern void av1_print_uncompressed_frame_header(const uint8_t *data, int size,
+                                                const char *filename);
+
 static uint32_t write_tiles_in_tg_obus(AV1_COMP *const cpi, uint8_t *const dst,
                                        struct aom_write_bit_buffer *saved_wb,
                                        uint8_t obu_extension_header,
@@ -3481,9 +3484,8 @@
     data += frame_header_size;
     total_size += frame_header_size;
 
-#define EXT_TILE_DEBUG 0
-#if EXT_TILE_DEBUG
-    {
+    // (yunqing) This test ensures the correctness of large scale tile coding.
+    if (cpi->oxcf.ext_tile_debug) {
       char fn[20] = "./fh";
       fn[4] = cm->current_frame.frame_number / 100 + '0';
       fn[5] = (cm->current_frame.frame_number % 100) / 10 + '0';
@@ -3492,8 +3494,6 @@
       av1_print_uncompressed_frame_header(data - frame_header_size,
                                           frame_header_size, fn);
     }
-#endif  // EXT_TILE_DEBUG
-#undef EXT_TILE_DEBUG
 
     int tile_size_bytes = 0;
     int tile_col_size_bytes = 0;
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 14a0d50..1948149 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -5830,6 +5830,9 @@
 }
 #endif
 
+extern void av1_print_frame_contexts(const FRAME_CONTEXT *fc,
+                                     const char *filename);
+
 static int encode_frame_to_data_rate(AV1_COMP *cpi, size_t *size,
                                      uint8_t *dest) {
   AV1_COMMON *const cm = &cpi->common;
@@ -6104,18 +6107,18 @@
   if (!cm->large_scale_tile) {
     cm->cur_frame->frame_context = *cm->fc;
   }
-#define EXT_TILE_DEBUG 0
-#if EXT_TILE_DEBUG
-  if (cm->large_scale_tile && is_stat_consumption_stage(cpi)) {
-    char fn[20] = "./fc";
-    fn[4] = current_frame->frame_number / 100 + '0';
-    fn[5] = (current_frame->frame_number % 100) / 10 + '0';
-    fn[6] = (current_frame->frame_number % 10) + '0';
-    fn[7] = '\0';
-    av1_print_frame_contexts(cm->fc, fn);
+
+  if (cpi->oxcf.ext_tile_debug) {
+    // (yunqing) This test ensures the correctness of large scale tile coding.
+    if (cm->large_scale_tile && is_stat_consumption_stage(cpi)) {
+      char fn[20] = "./fc";
+      fn[4] = current_frame->frame_number / 100 + '0';
+      fn[5] = (current_frame->frame_number % 100) / 10 + '0';
+      fn[6] = (current_frame->frame_number % 10) + '0';
+      fn[7] = '\0';
+      av1_print_frame_contexts(cm->fc, fn);
+    }
   }
-#endif  // EXT_TILE_DEBUG
-#undef EXT_TILE_DEBUG
 
 #if CONFIG_COLLECT_COMPONENT_TIMING
   end_timing(cpi, encode_frame_to_data_rate_time);
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index 596f825..b2cd141 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -371,6 +371,7 @@
   unsigned int full_still_picture_hdr;
   int enable_dual_filter;
   unsigned int motion_vector_unit_test;
+  unsigned int ext_tile_debug;
   int enable_rect_partitions;
   int enable_ab_partitions;
   int enable_1to4_partitions;
diff --git a/examples/lightfield_encoder.c b/examples/lightfield_encoder.c
index df58207..e80fe24 100644
--- a/examples/lightfield_encoder.c
+++ b/examples/lightfield_encoder.c
@@ -259,8 +259,10 @@
     die_codec(&codec, "Failed to turn off auto altref");
   if (aom_codec_control(&codec, AV1E_SET_FRAME_PARALLEL_DECODING, 0))
     die_codec(&codec, "Failed to set frame parallel decoding");
-  // if (aom_codec_control(&codec, AOME_SET_CPUUSED, 4))
-  //   die_codec(&codec, "Failed to set cpu-used");
+  if (aom_codec_control(&codec, AV1E_ENABLE_EXT_TILE_DEBUG, 1))
+    die_codec(&codec, "Failed to enable encoder ext_tile debug");
+  if (aom_codec_control(&codec, AOME_SET_CPUUSED, 1))
+    die_codec(&codec, "Failed to set cpu-used");
 
   // Note: The superblock is a sequence parameter and has to be the same for 1
   // sequence. In lightfield application, must choose the superblock size(either
diff --git a/test/lightfield_test.sh b/test/lightfield_test.sh
index 19b6934..3de88af 100755
--- a/test/lightfield_test.sh
+++ b/test/lightfield_test.sh
@@ -46,6 +46,22 @@
 
   [ -e "${lf_file}" ] || return 1
 
+  # Check to ensure all camera frames have the identical frame header. If not identical, this test fails.
+  for i in ./fh*; do
+    diff ./fh004 $i > /dev/null
+      if [ $? -eq 1 ]; then
+      return 1
+    fi
+  done
+
+  # Check to ensure all camera frames use the identical frame context. If not identical, this test fails.
+  for i in ./fc*; do
+    diff ./fc004 $i > /dev/null
+      if [ $? -eq 1 ]; then
+      return 1
+    fi
+  done
+
   # Parse lightfield bitstream to construct and output a new bitstream that can
   # be decoded by an AV1 decoder.
   local bs_decoder="${LIBAOM_BIN_PATH}/lightfield_bitstream_parsing${AOM_TEST_EXE_SUFFIX}"