More frame size unit tests

Add a unit test with comment about setting max frame sizes
for random input.

BUG=aomedia:3349

Change-Id: Idf0a1caab9aaf302ce44c164ceba9e93df232e0b
(cherry picked from commit f9f3436dd36a5dd055af4504073ff339082784f8)
diff --git a/test/frame_size_tests.cc b/test/frame_size_tests.cc
index 3b7cd1f..3b35db8 100644
--- a/test/frame_size_tests.cc
+++ b/test/frame_size_tests.cc
@@ -160,6 +160,82 @@
   EXPECT_EQ(frame_count, kNumFramesPerResolution * kFrameSizes.size());
 }
 
+TEST_P(AV1ResolutionChange, RandomInput) {
+  struct FrameSize {
+    unsigned int width;
+    unsigned int height;
+  };
+  static constexpr std::array<FrameSize, 4> kFrameSizes = { {
+      { 50, 200 },
+      { 100, 200 },
+      { 100, 300 },
+      { 200, 400 },
+  } };
+
+  aom_codec_iface_t *iface = aom_codec_av1_cx();
+  aom_codec_enc_cfg_t cfg;
+  ASSERT_EQ(aom_codec_enc_config_default(iface, &cfg, usage_), AOM_CODEC_OK);
+
+  // Resolution changes are only permitted with one pass encoding with no lag.
+  cfg.g_pass = AOM_RC_ONE_PASS;
+  cfg.g_lag_in_frames = 0;
+  cfg.rc_end_usage = rc_mode_;
+  // For random input source, if max frame sizes are not set, the first encoded
+  // frame size will be locked as the max frame size, and the encoder will
+  // identify it as unsupported bitstream.
+  unsigned int max_width = cfg.g_w;   // default frame width
+  unsigned int max_height = cfg.g_h;  // default frame height
+  for (const auto &frame_size : kFrameSizes) {
+    max_width = frame_size.width > max_width ? frame_size.width : max_width;
+    max_height =
+        frame_size.height > max_height ? frame_size.height : max_height;
+  }
+  cfg.g_forced_max_frame_width = max_width;
+  cfg.g_forced_max_frame_height = max_height;
+
+  aom_codec_ctx_t ctx;
+  EXPECT_EQ(aom_codec_enc_init(&ctx, iface, &cfg, 0), AOM_CODEC_OK);
+  std::unique_ptr<aom_codec_ctx_t, decltype(&aom_codec_destroy)> enc(
+      &ctx, &aom_codec_destroy);
+  EXPECT_EQ(aom_codec_control(enc.get(), AOME_SET_CPUUSED, cpu_used_),
+            AOM_CODEC_OK);
+
+  size_t frame_count = 0;
+  ::libaom_test::RandomVideoSource video;
+  video.Begin();
+  constexpr int kNumFramesPerResolution = 2;
+  for (const auto &frame_size : kFrameSizes) {
+    cfg.g_w = frame_size.width;
+    cfg.g_h = frame_size.height;
+    EXPECT_EQ(aom_codec_enc_config_set(enc.get(), &cfg), AOM_CODEC_OK);
+    video.SetSize(cfg.g_w, cfg.g_h);
+
+    aom_codec_iter_t iter;
+    const aom_codec_cx_pkt_t *pkt;
+
+    for (int i = 0; i < kNumFramesPerResolution; ++i) {
+      video.Next();  // SetSize() does not call FillFrame().
+      EXPECT_EQ(aom_codec_encode(enc.get(), video.img(), video.pts(),
+                                 video.duration(), /*flags=*/0),
+                AOM_CODEC_OK);
+
+      iter = nullptr;
+      while ((pkt = aom_codec_get_cx_data(enc.get(), &iter)) != nullptr) {
+        ASSERT_EQ(pkt->kind, AOM_CODEC_CX_FRAME_PKT);
+        // The frame following a resolution change should be a keyframe as the
+        // change is too extreme to allow previous references to be used.
+        if (i == 0 || usage_ == AOM_USAGE_ALL_INTRA) {
+          EXPECT_NE(pkt->data.frame.flags & AOM_FRAME_IS_KEY, 0u)
+              << "frame " << frame_count;
+        }
+        frame_count++;
+      }
+    }
+  }
+
+  EXPECT_EQ(frame_count, kNumFramesPerResolution * kFrameSizes.size());
+}
+
 TEST_P(AV1ResolutionChange, InvalidInputSize) {
   struct FrameSize {
     unsigned int width;