rtc-svc: Fix to SVC for HD with spatial layers > 1

The seq_params->sb_size is set on key frame/first frame,
and so when #spatial_layers > 1 it should be set based on
the top/highest resolution (oxcf.width/height), instead of
the resolution for the given/base layer (cm->width/height).

This fixed crash for SVC 720p input with #spatial_layers > 1.

Add unittest which catches the issue.

Change-Id: Ia16fabad33aca997b88b7e372063eabcddd5e555
diff --git a/av1/encoder/encoder.c b/av1/encoder/encoder.c
index 260bb1c..50b4409 100644
--- a/av1/encoder/encoder.c
+++ b/av1/encoder/encoder.c
@@ -586,6 +586,12 @@
 
   assert(cpi->oxcf.superblock_size == AOM_SUPERBLOCK_SIZE_DYNAMIC);
 
+  if (cpi->svc.number_spatial_layers > 1) {
+    // Use the configured size (top resolution) for spatial layers.
+    return AOMMIN(cpi->oxcf.width, cpi->oxcf.height) > 480 ? BLOCK_128X128
+                                                           : BLOCK_64X64;
+  }
+
   // TODO(any): Possibly could improve this with a heuristic.
   // When superres / resize is on, 'cm->width / height' can change between
   // calls, so we don't apply this heuristic there.
diff --git a/test/svc_datarate_test.cc b/test/svc_datarate_test.cc
index 1d950f9..28e517b 100644
--- a/test/svc_datarate_test.cc
+++ b/test/svc_datarate_test.cc
@@ -471,6 +471,47 @@
     }
   }
 
+  virtual void BasicRateTargetingSVC3TL3SLHDTest() {
+    cfg_.rc_buf_initial_sz = 500;
+    cfg_.rc_buf_optimal_sz = 500;
+    cfg_.rc_buf_sz = 1000;
+    cfg_.rc_dropframe_thresh = 0;
+    cfg_.rc_min_quantizer = 0;
+    cfg_.rc_max_quantizer = 63;
+    cfg_.rc_end_usage = AOM_CBR;
+    cfg_.g_lag_in_frames = 0;
+    cfg_.g_error_resilient = 1;
+
+    ::libaom_test::Y4mVideoSource video("niklas_1280_720_30.y4m", 0, 60);
+    const int bitrate_array[2] = { 600, 1200 };
+    cfg_.rc_target_bitrate = bitrate_array[GET_PARAM(4)];
+    ResetModel();
+    number_temporal_layers_ = 3;
+    number_spatial_layers_ = 3;
+    // SL0
+    const int bitrate_sl0 = 1 * cfg_.rc_target_bitrate / 8;
+    target_layer_bitrate_[0] = 50 * bitrate_sl0 / 100;
+    target_layer_bitrate_[1] = 70 * bitrate_sl0 / 100;
+    target_layer_bitrate_[2] = bitrate_sl0;
+    // SL1
+    const int bitrate_sl1 = 3 * cfg_.rc_target_bitrate / 8;
+    target_layer_bitrate_[3] = 50 * bitrate_sl1 / 100;
+    target_layer_bitrate_[4] = 70 * bitrate_sl1 / 100;
+    target_layer_bitrate_[5] = bitrate_sl1;
+    // SL2
+    const int bitrate_sl2 = 4 * cfg_.rc_target_bitrate / 8;
+    target_layer_bitrate_[6] = 50 * bitrate_sl2 / 100;
+    target_layer_bitrate_[7] = 70 * bitrate_sl2 / 100;
+    target_layer_bitrate_[8] = bitrate_sl2;
+    ASSERT_NO_FATAL_FAILURE(RunLoop(&video));
+    for (int i = 0; i < number_temporal_layers_ * number_spatial_layers_; i++) {
+      ASSERT_GE(effective_datarate_tl[i], target_layer_bitrate_[i] * 0.70)
+          << " The datarate for the file is lower than target by too much!";
+      ASSERT_LE(effective_datarate_tl[i], target_layer_bitrate_[i] * 1.4)
+          << " The datarate for the file is greater than target by too much!";
+    }
+  }
+
   virtual void BasicRateTargetingSVC3TL3SLKfTest() {
     cfg_.rc_buf_initial_sz = 500;
     cfg_.rc_buf_optimal_sz = 500;
@@ -547,6 +588,11 @@
   BasicRateTargetingSVC3TL3SLTest();
 }
 
+// Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers.
+TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLHD) {
+  BasicRateTargetingSVC3TL3SLHDTest();
+}
+
 // Check basic rate targeting for CBR, for 3 spatial, 3 temporal layers,
 // for auto key frame mode with short key frame period.
 TEST_P(DatarateTestSVC, BasicRateTargetingSVC3TL3SLKf) {