Impose a maximum frame area of 2^30

Revert commit e645ba3c6e601fd86ff9d050d47e8c82c0ea3361, which imposed a
smaller maximum frame dimension of 32768 (= 2^15). Just impose a maximum
on the frame area (width * height). This allows one dimension (width or
height) to attain the 65536 (= 2^16) maximum allowed by the AV1
specification.

Bug: aomedia:3508
Change-Id: I2609df4b658ec161fba4bcb41634bed9ee4d6303
diff --git a/av1/av1_cx_iface.c b/av1/av1_cx_iface.c
index 719859df..588b0a4 100644
--- a/av1/av1_cx_iface.c
+++ b/av1/av1_cx_iface.c
@@ -636,20 +636,28 @@
 static aom_codec_err_t validate_config(aom_codec_alg_priv_t *ctx,
                                        const aom_codec_enc_cfg_t *cfg,
                                        const struct av1_extracfg *extra_cfg) {
-  // The AV1 specification allows a maximum frame dimension (width or height)
-  // of 65536 (= 2^16). To avoid integer overflows when multiplying width by
-  // height (or values derived from width and height) using the int type,
-  // impose a smaller maximum frame dimension of 32768 (= 2^15).
-  RANGE_CHECK(cfg, g_w, 1, 32768);
-  RANGE_CHECK(cfg, g_h, 1, 32768);
-  RANGE_CHECK_HI(cfg, g_forced_max_frame_width, 32768);
-  RANGE_CHECK_HI(cfg, g_forced_max_frame_height, 32768);
+  RANGE_CHECK(cfg, g_w, 1, 65536);                        // 16 bits available
+  RANGE_CHECK(cfg, g_h, 1, 65536);                        // 16 bits available
+  RANGE_CHECK_HI(cfg, g_forced_max_frame_width, 65536);   // 16 bits available
+  RANGE_CHECK_HI(cfg, g_forced_max_frame_height, 65536);  // 16 bits available
   if (cfg->g_forced_max_frame_width) {
     RANGE_CHECK_HI(cfg, g_w, cfg->g_forced_max_frame_width);
   }
   if (cfg->g_forced_max_frame_height) {
     RANGE_CHECK_HI(cfg, g_h, cfg->g_forced_max_frame_height);
   }
+  // To avoid integer overflows when multiplying width by height (or values
+  // derived from width and height) using the int type, impose a maximum frame
+  // area (width * height) of 2^30.
+  const unsigned int max_frame_width =
+      cfg->g_forced_max_frame_width ? cfg->g_forced_max_frame_width : cfg->g_w;
+  const unsigned int max_frame_height = cfg->g_forced_max_frame_height
+                                            ? cfg->g_forced_max_frame_height
+                                            : cfg->g_h;
+  const int64_t max_frame_area = (int64_t)max_frame_width * max_frame_height;
+  if (max_frame_area > (1 << 30)) {
+    ERROR("max_frame_area out of range [..2^30]");
+  }
   RANGE_CHECK(cfg, g_timebase.den, 1, 1000000000);
   RANGE_CHECK(cfg, g_timebase.num, 1, cfg->g_timebase.den);
   RANGE_CHECK_HI(cfg, g_profile, MAX_PROFILES - 1);
diff --git a/test/encode_api_test.cc b/test/encode_api_test.cc
index eecc723..e6ef4c2 100644
--- a/test/encode_api_test.cc
+++ b/test/encode_api_test.cc
@@ -66,16 +66,20 @@
   EXPECT_EQ(AOM_CODEC_INVALID_PARAM,
             aom_codec_enc_config_default(iface, &cfg, 3));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
-  cfg.g_w = (1 << 15) + 1;
+  cfg.g_w = 1 << 16;
+  cfg.g_h = (1 << 14) + 1;
   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
-  cfg.g_h = (1 << 15) + 1;
+  cfg.g_w = (1 << 14) + 1;
+  cfg.g_h = 1 << 16;
   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
-  cfg.g_forced_max_frame_width = (1 << 15) + 1;
+  cfg.g_forced_max_frame_width = 1 << 16;
+  cfg.g_forced_max_frame_height = (1 << 14) + 1;
   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
-  cfg.g_forced_max_frame_height = (1 << 15) + 1;
+  cfg.g_forced_max_frame_width = (1 << 14) + 1;
+  cfg.g_forced_max_frame_height = 1 << 16;
   EXPECT_EQ(AOM_CODEC_INVALID_PARAM, aom_codec_enc_init(&enc, iface, &cfg, 0));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_config_default(iface, &cfg, kUsage));
   EXPECT_EQ(AOM_CODEC_OK, aom_codec_enc_init(&enc, iface, &cfg, 0));