Guard support of 7.x and 8.x levels under a config flag.

Also only output 7.x and 8.x levels when explicitly asked.

BUG: aomedia:2871
Change-Id: I803c7320f3bf4ac8aed7fc1969b40f721bdf621a
(cherry picked from commit 66a86fe73fb794205f4c28c71dd835cd4733c6b2)
diff --git a/aom/aomcx.h b/aom/aomcx.h
index b7d1d9d..9c21942 100644
--- a/aom/aomcx.h
+++ b/aom/aomcx.h
@@ -616,11 +616,13 @@
    * point (OP), int parameter
    * Possible values are in the form of "ABxy".
    *  - AB: OP index.
-   *  - xy: Target level index for the OP. Can be values 0~27 (corresponding to
-   *    level 2.0 ~ 8.3, note levels 2.2, 2.3, 3.2, 3.3, 4.2 & 4.3 are
-   *    undefined, and that levels 7.x and 8.x are in draft status), 31
-   *    (maximum parameters level, no level-based constraints) or 32 (keep
-   *    level stats only for level monitoring).
+   *  - xy: Target level index for the OP. Possible values are:
+   *    + 0~27: corresponding to level 2.0 ~ 8.3. Note:
+   *      > Levels 2.2, 2.3, 3.2, 3.3, 4.2 & 4.3 are undefined.
+   *      > Levels 7.x and 8.x are in draft status, available under the config
+   *        flag CONFIG_CWG_C013.
+   *    + 31: maximum parameters level, no level-based constraints.
+   *    + 32: keep level stats only for level monitoring.
    *
    * E.g.:
    * - "0" means target level index 0 (2.0) for the 0th OP;
diff --git a/av1/common/av1_common_int.h b/av1/common/av1_common_int.h
index f3f2823..304a551 100644
--- a/av1/common/av1_common_int.h
+++ b/av1/common/av1_common_int.h
@@ -1871,7 +1871,14 @@
           // The following levels are currently undefined.
           seq_level_idx != SEQ_LEVEL_2_2 && seq_level_idx != SEQ_LEVEL_2_3 &&
           seq_level_idx != SEQ_LEVEL_3_2 && seq_level_idx != SEQ_LEVEL_3_3 &&
-          seq_level_idx != SEQ_LEVEL_4_2 && seq_level_idx != SEQ_LEVEL_4_3);
+          seq_level_idx != SEQ_LEVEL_4_2 && seq_level_idx != SEQ_LEVEL_4_3
+#if !CONFIG_CWG_C013
+          && seq_level_idx != SEQ_LEVEL_7_0 && seq_level_idx != SEQ_LEVEL_7_1 &&
+          seq_level_idx != SEQ_LEVEL_7_2 && seq_level_idx != SEQ_LEVEL_7_3 &&
+          seq_level_idx != SEQ_LEVEL_8_0 && seq_level_idx != SEQ_LEVEL_8_1 &&
+          seq_level_idx != SEQ_LEVEL_8_2 && seq_level_idx != SEQ_LEVEL_8_3
+#endif
+         );
 }
 
 /*!\endcond */
diff --git a/av1/common/tile_common.c b/av1/common/tile_common.c
index 45f4d0c..508fe30 100644
--- a/av1/common/tile_common.c
+++ b/av1/common/tile_common.c
@@ -40,6 +40,7 @@
   const int sb_size_log2 = seq_params->mib_size_log2 + MI_SIZE_LOG2;
   tiles->max_width_sb = MAX_TILE_WIDTH >> sb_size_log2;
 
+#if CONFIG_CWG_C013
   bool use_level_7_above = false;
   for (int i = 0; i < seq_params->operating_points_cnt_minus_1 + 1; i++) {
     if (seq_params->seq_level_idx[i] >= SEQ_LEVEL_7_0 &&
@@ -57,6 +58,9 @@
   const int max_tile_area_sb =
       (use_level_7_above ? MAX_TILE_AREA_LEVEL_7_AND_ABOVE : MAX_TILE_AREA) >>
       (2 * sb_size_log2);
+#else
+  const int max_tile_area_sb = MAX_TILE_AREA >> (2 * sb_size_log2);
+#endif
 
   tiles->min_log2_cols = tile_log2(tiles->max_width_sb, sb_cols);
   tiles->max_log2_cols = tile_log2(1, AOMMIN(sb_cols, MAX_TILE_COLS));
diff --git a/av1/common/tile_common.h b/av1/common/tile_common.h
index 9a72009..8615a2c 100644
--- a/av1/common/tile_common.h
+++ b/av1/common/tile_common.h
@@ -52,7 +52,9 @@
 // The minimum tile width or height is fixed at one superblock
 #define MAX_TILE_WIDTH (4096)        // Max Tile width in pixels
 #define MAX_TILE_AREA (4096 * 2304)  // Maximum tile area in pixels
+#if CONFIG_CWG_C013
 #define MAX_TILE_AREA_LEVEL_7_AND_ABOVE (4096 * 4608)
+#endif
 
 void av1_get_uniform_tile_size(const struct AV1Common *cm, int *w, int *h);
 void av1_get_tile_limits(struct AV1Common *const cm);
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index aef55cb..0ba4405 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -363,6 +363,9 @@
 static void set_bitstream_level_tier(AV1_PRIMARY *const ppi, int width,
                                      int height, double init_framerate) {
   SequenceHeader *const seq_params = &ppi->seq_params;
+#if CONFIG_CWG_C013
+  AV1LevelParams *const level_params = &ppi->level_params;
+#endif
   // TODO(any): This is a placeholder function that only addresses dimensions
   // and max display sample rates.
   // Need to add checks for max bit rate, max decoded luma sample rate, header
@@ -403,25 +406,33 @@
   } else if (does_level_match(width, height, init_framerate, 8192, 4352, 120.0,
                               2)) {
     level = SEQ_LEVEL_6_2;
-  } else if (does_level_match(width, height, init_framerate, 16384, 8704, 30.0,
-                              2)) {
-    level = SEQ_LEVEL_7_0;
-  } else if (does_level_match(width, height, init_framerate, 16384, 8704, 60.0,
-                              2)) {
-    level = SEQ_LEVEL_7_1;
-  } else if (does_level_match(width, height, init_framerate, 16384, 8704, 120.0,
-                              2)) {
-    level = SEQ_LEVEL_7_2;
-  } else if (does_level_match(width, height, init_framerate, 32768, 17408, 30.0,
-                              2)) {
-    level = SEQ_LEVEL_8_0;
-  } else if (does_level_match(width, height, init_framerate, 32768, 17408, 60.0,
-                              2)) {
-    level = SEQ_LEVEL_8_1;
-  } else if (does_level_match(width, height, init_framerate, 32768, 17408,
-                              120.0, 2)) {
-    level = SEQ_LEVEL_8_2;
   }
+#if CONFIG_CWG_C013
+  // TODO(bohanli): currently target level is only working for the 0th operating
+  // point, so scalable coding is not supported.
+  else if (level_params->target_seq_level_idx[0] >= SEQ_LEVEL_7_0 &&
+           level_params->target_seq_level_idx[0] <= SEQ_LEVEL_8_3) {
+    // Only use level 7.x to 8.x when explicitly asked to.
+    if (does_level_match(width, height, init_framerate, 16384, 8704, 30.0, 2)) {
+      level = SEQ_LEVEL_7_0;
+    } else if (does_level_match(width, height, init_framerate, 16384, 8704,
+                                60.0, 2)) {
+      level = SEQ_LEVEL_7_1;
+    } else if (does_level_match(width, height, init_framerate, 16384, 8704,
+                                120.0, 2)) {
+      level = SEQ_LEVEL_7_2;
+    } else if (does_level_match(width, height, init_framerate, 32768, 17408,
+                                30.0, 2)) {
+      level = SEQ_LEVEL_8_0;
+    } else if (does_level_match(width, height, init_framerate, 32768, 17408,
+                                60.0, 2)) {
+      level = SEQ_LEVEL_8_1;
+    } else if (does_level_match(width, height, init_framerate, 32768, 17408,
+                                120.0, 2)) {
+      level = SEQ_LEVEL_8_2;
+    }
+  }
+#endif
 
   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
     seq_params->seq_level_idx[i] = level;
diff --git a/av1/encoder/level.c b/av1/encoder/level.c
index 4d17142..8f8892f 100644
--- a/av1/encoder/level.c
+++ b/av1/encoder/level.c
@@ -209,6 +209,7 @@
     .high_cr = 4.0,
     .max_tiles = 128,
     .max_tile_cols = 16 },
+#if CONFIG_CWG_C013
   { .level = SEQ_LEVEL_7_0,
     .max_picture_size = 142606336,
     .max_h_size = 32768,
@@ -313,6 +314,7 @@
     .high_cr = 4.0,
     .max_tiles = 512,
     .max_tile_cols = 64 },
+#endif
 };
 
 typedef enum {
@@ -1016,9 +1018,13 @@
       break;
     }
 
+#if CONFIG_CWG_C013
     const int max_tile_size = (level >= SEQ_LEVEL_7_0 && level <= SEQ_LEVEL_8_3)
                                   ? MAX_TILE_AREA_LEVEL_7_AND_ABOVE
                                   : MAX_TILE_AREA;
+#else
+    const int max_tile_size = MAX_TILE_AREA;
+#endif
     if (level_stats->max_tile_size > max_tile_size) {
       fail_id = TILE_TOO_LARGE;
       break;
diff --git a/build/cmake/aom_config_defaults.cmake b/build/cmake/aom_config_defaults.cmake
index eafd26c..d63990b 100644
--- a/build/cmake/aom_config_defaults.cmake
+++ b/build/cmake/aom_config_defaults.cmake
@@ -155,6 +155,8 @@
                    "AV1 experiment: Enable tensorflow lite library.")
 set_aom_config_var(CONFIG_THREE_PASS 0
                    "AV1 experiment: Enable three-pass encoding.")
+set_aom_config_var(CONFIG_CWG_C013 0
+                   "AV1 experiment: Support for 7.x and 8.x levels.")
 
 #
 # Variables in this section control optional features of the build system.
diff --git a/test/invalid_file_test.cc b/test/invalid_file_test.cc
index 1fc849e..10a3bc4 100644
--- a/test/invalid_file_test.cc
+++ b/test/invalid_file_test.cc
@@ -146,7 +146,11 @@
   { 1, "invalid-oss-fuzz-10227.ivf", nullptr },
   { 4, "invalid-oss-fuzz-10555.ivf", nullptr },
   { 1, "invalid-oss-fuzz-10705.ivf", nullptr },
+#if CONFIG_CWG_C013
   { 1, "invalid-oss-fuzz-10723.ivf", "invalid-oss-fuzz-10723.ivf.res.3" },
+#else
+  { 1, "invalid-oss-fuzz-10723.ivf", "invalid-oss-fuzz-10723.ivf.res.2" },
+#endif
   { 1, "invalid-oss-fuzz-10779.ivf", nullptr },
   { 1, "invalid-oss-fuzz-11477.ivf", nullptr },
   { 1, "invalid-oss-fuzz-11479.ivf", "invalid-oss-fuzz-11479.ivf.res.2" },
diff --git a/test/level_test.cc b/test/level_test.cc
index 8759b9b..1156262 100644
--- a/test/level_test.cc
+++ b/test/level_test.cc
@@ -88,7 +88,7 @@
     for (int level = 0; level <= 32; ++level) {
       const int target_level = operating_point * 100 + level;
       if ((level < 28 && level != 2 && level != 3 && level != 6 && level != 7 &&
-           level != 10 && level != 11) ||
+           level != 10 && level != 11 && (CONFIG_CWG_C013 || level < 20)) ||
           level == kLevelMax || level == kLevelKeepStats ||
           operating_point > 31) {
         EXPECT_EQ(AOM_CODEC_OK,
diff --git a/test/test-data.sha1 b/test/test-data.sha1
index 7e4abae..3ac50a4 100644
--- a/test/test-data.sha1
+++ b/test/test-data.sha1
@@ -22,6 +22,7 @@
 cf5945085fe85456a1f74bf4cc7998b88b3f4b62 *invalid-oss-fuzz-10705.ivf
 758671858368ffd2a2c0727898de5661f7cf7d68 *invalid-oss-fuzz-10705.ivf.res
 88e29851122cca3f336824f7fa4d9f757f91110c *invalid-oss-fuzz-10723.ivf
+64f8a208dec7f1580fbe0371aa15e62bb1262715 *invalid-oss-fuzz-10723.ivf.res.2
 1af486cd2cc83ebeddc76ca7a1c512cc0ec568d5 *invalid-oss-fuzz-10723.ivf.res.3
 0784acc8931090ec24eba752d6c27e359e68fe7d *invalid-oss-fuzz-10779.ivf
 5d9474c0309b7ca09a182d888f73b37a8fe1362c *invalid-oss-fuzz-10779.ivf.res
diff --git a/test/test_data_util.cmake b/test/test_data_util.cmake
index 9a6accb..b5d6fda 100644
--- a/test/test_data_util.cmake
+++ b/test/test_data_util.cmake
@@ -552,6 +552,7 @@
               "invalid-oss-fuzz-10705.ivf"
               "invalid-oss-fuzz-10705.ivf.res"
               "invalid-oss-fuzz-10723.ivf"
+              "invalid-oss-fuzz-10723.ivf.res.2"
               "invalid-oss-fuzz-10723.ivf.res.3"
               "invalid-oss-fuzz-10779.ivf"
               "invalid-oss-fuzz-10779.ivf.res"