AV1 levels: add an option for level monitoring

If the target level index is 24, encoder keeps level related stats so
that it can passively measure the bitstream level, while not trying
to actively enforce any level constraints.

Change-Id: I5793f7dfc83d34b302587b2e70b595750ad82289
diff --git a/aom/aomcx.h b/aom/aomcx.h
index 77d68b0..bf21285 100644
--- a/aom/aomcx.h
+++ b/aom/aomcx.h
@@ -518,8 +518,8 @@
    * 4 digits).
    *   AB: OP index.
    *   xy: Target level index for the OP. Can be values 0~23(corresponding to
-   *   level 2.0 ~ 7.3) or 31(maximum level parameter, no level-based
-   *   constraints).
+   *   level 2.0 ~ 7.3) or 24(keep level stats only for level monitoring) or
+   *   31(maximum level parameter, no level-based constraints).
    * E.g. "0" means target level index 0 for the 0th OP;
    *      "111" means target level index 11 for the 1st OP;
    *      "1021" means target level index 21 for the 10th OP.
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 13e108f..87cedcf 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -506,8 +506,10 @@
   RANGE_CHECK(extra_cfg, tx_size_search_method, 0, 2);
 
   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
-    if (!is_valid_seq_level_idx(extra_cfg->target_seq_level_idx[i]))
+    const int level_idx = extra_cfg->target_seq_level_idx[i];
+    if (!is_valid_seq_level_idx(level_idx) && level_idx != SEQ_LEVELS) {
       ERROR("Target sequence level index is invalid");
+    }
   }
 
   return AOM_CODEC_OK;
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 73f3138..9609c89 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -2444,7 +2444,7 @@
          sizeof(cpi->target_seq_level_idx));
   cpi->keep_level_stats = 0;
   for (int i = 0; i < MAX_NUM_OPERATING_POINTS; ++i) {
-    if (cpi->target_seq_level_idx[i] < SEQ_LEVELS) {
+    if (cpi->target_seq_level_idx[i] <= SEQ_LEVELS) {
       cpi->keep_level_stats |= 1u << i;
       if (!cpi->level_info[i]) {
         CHECK_MEM_ERROR(cm, cpi->level_info[i],
diff --git a/test/level_test.cc b/test/level_test.cc
index e3b0ef1..c730826 100644
--- a/test/level_test.cc
+++ b/test/level_test.cc
@@ -79,7 +79,7 @@
   for (int operating_point = 0; operating_point <= 32; ++operating_point) {
     for (int level = 0; level <= 32; ++level) {
       const int target_level = operating_point * 100 + level;
-      if ((level >= 0 && level <= 23) || level == 31 || operating_point > 31) {
+      if ((level >= 0 && level <= 24) || level == 31 || operating_point > 31) {
         EXPECT_EQ(AOM_CODEC_OK,
                   aom_codec_control(&enc, AV1E_SET_TARGET_SEQ_LEVEL_IDX,
                                     target_level));