Make AV1 respect spatial layer active flag.

Bug: webrtc:12788
Change-Id: Ied629e1635b6ff9bf92fab2d1af708163f9dd28c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/220928
Commit-Queue: Erik Språng <sprang@webrtc.org>
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#34189}
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
index 8c82476..84f3453 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder.cc
@@ -671,8 +671,15 @@
         encoded_image.content_type_ = VideoContentType::UNSPECIFIED;
         // If encoded image width/height info are added to aom_codec_cx_pkt_t,
         // use those values in lieu of the values in frame.
-        encoded_image._encodedHeight = frame.height();
-        encoded_image._encodedWidth = frame.width();
+        if (svc_params_) {
+          int n = svc_params_->scaling_factor_num[layer_frame.SpatialId()];
+          int d = svc_params_->scaling_factor_den[layer_frame.SpatialId()];
+          encoded_image._encodedWidth = cfg_.g_w * n / d;
+          encoded_image._encodedHeight = cfg_.g_h * n / d;
+        } else {
+          encoded_image._encodedWidth = cfg_.g_w;
+          encoded_image._encodedHeight = cfg_.g_h;
+        }
         encoded_image.timing_.flags = VideoSendTiming::kInvalid;
         int qp = -1;
         ret = aom_codec_control(&ctx_, AOME_GET_LAST_QUANTIZER, &qp);
diff --git a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
index ea77e09..96057a0 100644
--- a/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
+++ b/modules/video_coding/codecs/av1/libaom_av1_encoder_unittest.cc
@@ -25,6 +25,7 @@
 namespace {
 
 using ::testing::ElementsAre;
+using ::testing::Field;
 using ::testing::IsEmpty;
 using ::testing::SizeIs;
 
@@ -135,5 +136,36 @@
   EXPECT_THAT(encoder_info.fps_allocation[3], IsEmpty());
 }
 
+TEST(LibaomAv1EncoderTest, PopulatesEncodedFrameSize) {
+  std::unique_ptr<VideoEncoder> encoder = CreateLibaomAv1Encoder();
+  VideoCodec codec_settings = DefaultCodecSettings();
+  ASSERT_GT(codec_settings.width, 4);
+  // Configure encoder with 3 spatial layers.
+  codec_settings.SetScalabilityMode("L3T1");
+  ASSERT_EQ(encoder->InitEncode(&codec_settings, DefaultEncoderSettings()),
+            WEBRTC_VIDEO_CODEC_OK);
+
+  using Frame = EncodedVideoFrameProducer::EncodedFrame;
+  std::vector<Frame> encoded_frames =
+      EncodedVideoFrameProducer(*encoder).SetNumInputFrames(1).Encode();
+  EXPECT_THAT(
+      encoded_frames,
+      ElementsAre(
+          Field(&Frame::encoded_image,
+                AllOf(Field(&EncodedImage::_encodedWidth,
+                            codec_settings.width / 4),
+                      Field(&EncodedImage::_encodedHeight,
+                            codec_settings.height / 4))),
+          Field(&Frame::encoded_image,
+                AllOf(Field(&EncodedImage::_encodedWidth,
+                            codec_settings.width / 2),
+                      Field(&EncodedImage::_encodedHeight,
+                            codec_settings.height / 2))),
+          Field(&Frame::encoded_image,
+                AllOf(Field(&EncodedImage::_encodedWidth, codec_settings.width),
+                      Field(&EncodedImage::_encodedHeight,
+                            codec_settings.height)))));
+}
+
 }  // namespace
 }  // namespace webrtc
diff --git a/modules/video_coding/video_codec_initializer.cc b/modules/video_coding/video_codec_initializer.cc
index 90a02e0..17ea66a 100644
--- a/modules/video_coding/video_codec_initializer.cc
+++ b/modules/video_coding/video_codec_initializer.cc
@@ -262,7 +262,11 @@
       break;
     }
     case kVideoCodecAV1:
-      if (!SetAv1SvcConfig(video_codec)) {
+      if (SetAv1SvcConfig(video_codec)) {
+        for (size_t i = 0; i < config.spatial_layers.size(); ++i) {
+          video_codec.spatialLayers[i].active = config.spatial_layers[i].active;
+        }
+      } else {
         RTC_LOG(LS_WARNING) << "Failed to configure svc bitrates for av1.";
       }
       break;
diff --git a/modules/video_coding/video_codec_initializer_unittest.cc b/modules/video_coding/video_codec_initializer_unittest.cc
index da3d80d..6c1c2e7 100644
--- a/modules/video_coding/video_codec_initializer_unittest.cc
+++ b/modules/video_coding/video_codec_initializer_unittest.cc
@@ -461,4 +461,34 @@
             codec.spatialLayers[1].maxBitrate);
 }
 
+TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersActiveByDefault) {
+  VideoEncoderConfig config;
+  config.codec_type = VideoCodecType::kVideoCodecAV1;
+  std::vector<VideoStream> streams = {DefaultStream()};
+  streams[0].scalability_mode = "L2T2";
+  config.spatial_layers = {};
+
+  VideoCodec codec;
+  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+
+  EXPECT_TRUE(codec.spatialLayers[0].active);
+  EXPECT_TRUE(codec.spatialLayers[1].active);
+}
+
+TEST_F(VideoCodecInitializerTest, Av1TwoSpatialLayersOneDeactivated) {
+  VideoEncoderConfig config;
+  config.codec_type = VideoCodecType::kVideoCodecAV1;
+  std::vector<VideoStream> streams = {DefaultStream()};
+  streams[0].scalability_mode = "L2T2";
+  config.spatial_layers.resize(2);
+  config.spatial_layers[0].active = true;
+  config.spatial_layers[1].active = false;
+
+  VideoCodec codec;
+  EXPECT_TRUE(VideoCodecInitializer::SetupCodec(config, streams, &codec));
+
+  EXPECT_TRUE(codec.spatialLayers[0].active);
+  EXPECT_FALSE(codec.spatialLayers[1].active);
+}
+
 }  // namespace webrtc