Introduce SUPERRES_AUTO mode.

This mode will automatically pick superres for appropriate frames, and
choose the superres denominator appropriately as well.

For now, it uses superres only for keyframes that aren't used as
references, and only in constant quality mode.

Change-Id: Ia30ba8a853f83535665168498634cee469f7f7a4
diff --git a/aom/aom_encoder.h b/aom/aom_encoder.h
index 777236f..60c1c82 100644
--- a/aom/aom_encoder.h
+++ b/aom/aom_encoder.h
@@ -406,8 +406,7 @@
    * upscaling after the encode/decode process. Taking control of upscaling and
    * using restoration filters should allow it to outperform normal resizing.
    *
-   * Mode 0 is SUPERRES_NONE, mode 1 is SUPERRES_FIXED, mode 2 is
-   * SUPERRES_RANDOM and mode 3 is SUPERRES_QTHRESH.
+   * Valid values are 0 to 4 as defined in enum SUPERRES_MODE.
    */
   unsigned int rc_superres_mode;
 
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 285e6a5..d42d818 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -2122,7 +2122,7 @@
         SCALE_NUMERATOR,  // rc_resize_denominator
         SCALE_NUMERATOR,  // rc_resize_kf_denominator
 
-        0,                // rc_superres_mode
+        SUPERRES_NONE,    // rc_superres_mode
         SCALE_NUMERATOR,  // rc_superres_denominator
         SCALE_NUMERATOR,  // rc_superres_kf_denominator
         63,               // rc_superres_qthresh
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 9428a92..10ca859 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -4143,6 +4143,29 @@
       }
       break;
     }
+    case SUPERRES_AUTO: {
+      // Don't use when screen content tools are used.
+      if (cpi->common.allow_screen_content_tools) break;
+      // Don't use for inter frames.
+      if (!frame_is_intra_only(&cpi->common)) break;
+      // Don't use for keyframes that can be used as references.
+      if (cpi->rc.frames_to_key != 1) break;
+      // Don't use for any rate control mode other than constant quality.
+      if (oxcf->rc_mode != AOM_Q) break;
+
+      // Now decide the use of superres based on 'q'.
+      int bottom_index, top_index;
+      const int q = av1_rc_pick_q_and_bounds(
+          cpi, cpi->oxcf.width, cpi->oxcf.height, &bottom_index, &top_index);
+
+      const int qthresh = 128;
+      if (q <= qthresh) {
+        new_denom = SCALE_NUMERATOR;
+      } else {
+        new_denom = get_superres_denom_for_qindex(cpi, q);
+      }
+      break;
+    }
     default: assert(0);
   }
   return new_denom;
diff --git a/av1/encoder/encoder.h b/av1/encoder/encoder.h
index dec531f..c0f50bf 100644
--- a/av1/encoder/encoder.h
+++ b/av1/encoder/encoder.h
@@ -121,13 +121,14 @@
 } UENUM1BYTE(RESIZE_MODE);
 
 enum {
-  SUPERRES_NONE = 0,     // No frame superres allowed
-  SUPERRES_FIXED = 1,    // All frames are coded at the specified scale,
-                         // and super-resolved.
-  SUPERRES_RANDOM = 2,   // All frames are coded at a random scale,
-                         // and super-resolved.
-  SUPERRES_QTHRESH = 3,  // Superres scale for a frame is determined based on
-                         // q_index
+  SUPERRES_NONE,     // No frame superres allowed.
+  SUPERRES_FIXED,    // All frames are coded at the specified scale,
+                     // and super-resolved.
+  SUPERRES_RANDOM,   // All frames are coded at a random scale,
+                     // and super-resolved.
+  SUPERRES_QTHRESH,  // Superres scale for a frame is determined based on
+                     // q_index.
+  SUPERRES_AUTO,     // Automatically select superres for appropriate frames.
   SUPERRES_MODES
 } UENUM1BYTE(SUPERRES_MODE);
 
diff --git a/test/horz_superres_test.cc b/test/horz_superres_test.cc
index 1627684..2239431b 100644
--- a/test/horz_superres_test.cc
+++ b/test/horz_superres_test.cc
@@ -50,10 +50,14 @@
   { "screendata.y4m", AOM_IMG_FMT_I420, AOM_BITS_8, 0, 4, 1 },
 };
 
-// Superres modes tested
+// TODO(urvang): Add separate tests for SUPERRES_AUTO and SUPERRES_RANDOM,
+// as they don't use the denoms. SUPERRES_QTHRESH tests should also not use the
+// denominators.
 // SUPERRES_QTHRESH is not included, as it has its own test
-const SUPERRES_MODE kSuperresModesNotQThresh[] = { SUPERRES_FIXED,
-                                                   SUPERRES_RANDOM };
+const SUPERRES_MODE kSuperresModesNotQThresh[] = {
+  SUPERRES_FIXED,
+  SUPERRES_RANDOM,
+};
 
 // Superres denominators and superres kf denominators to be tested
 typedef tuple<int, int> SuperresDenominatorPair;