/* * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include "modules/video_coding/codecs/av1/av1_svc_config.h" #include "api/video_codecs/video_codec.h" #include "test/gmock.h" #include "test/gtest.h" namespace webrtc { namespace { constexpr int kDontCare = 0; VideoCodec GetDefaultVideoCodec() { VideoCodec video_codec; video_codec.codecType = kVideoCodecAV1; video_codec.width = 1280; video_codec.height = 720; return video_codec; } TEST(Av1SvcConfigTest, TreatsEmptyAsL1T1) { VideoCodec video_codec = GetDefaultVideoCodec(); EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_TRUE(video_codec.spatialLayers[0].active); EXPECT_EQ(video_codec.spatialLayers[0].numberOfTemporalLayers, 1); EXPECT_FALSE(video_codec.spatialLayers[1].active); } TEST(Av1SvcConfigTest, ScalabilityModeFromNumberOfTemporalLayers) { VideoCodec video_codec = GetDefaultVideoCodec(); EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/3, /*num_spatial_layers=*/1)); EXPECT_EQ(video_codec.spatialLayers[0].numberOfTemporalLayers, 3); } TEST(Av1SvcConfigTest, ScalabilityModeFromNumberOfSpatialLayers) { VideoCodec video_codec = GetDefaultVideoCodec(); EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/3, /*num_spatial_layers=*/2)); EXPECT_EQ(video_codec.spatialLayers[0].numberOfTemporalLayers, 3); EXPECT_TRUE(video_codec.spatialLayers[0].active); EXPECT_TRUE(video_codec.spatialLayers[1].active); EXPECT_FALSE(video_codec.spatialLayers[2].active); } TEST(Av1SvcConfigTest, SetsActiveSpatialLayersFromScalabilityMode) { VideoCodec video_codec = GetDefaultVideoCodec(); video_codec.SetScalabilityMode(ScalabilityMode::kL2T1); EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_TRUE(video_codec.spatialLayers[0].active); EXPECT_TRUE(video_codec.spatialLayers[1].active); EXPECT_FALSE(video_codec.spatialLayers[2].active); } TEST(Av1SvcConfigTest, ConfiguresDobuleResolutionRatioFromScalabilityMode) { VideoCodec video_codec; video_codec.codecType = kVideoCodecAV1; video_codec.SetScalabilityMode(ScalabilityMode::kL2T1); video_codec.width = 1200; video_codec.height = 800; EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_EQ(video_codec.spatialLayers[0].width, 600); EXPECT_EQ(video_codec.spatialLayers[0].height, 400); EXPECT_EQ(video_codec.spatialLayers[1].width, 1200); EXPECT_EQ(video_codec.spatialLayers[1].height, 800); } TEST(Av1SvcConfigTest, ConfiguresSmallResolutionRatioFromScalabilityMode) { VideoCodec video_codec; video_codec.codecType = kVideoCodecAV1; // h mode uses 1.5:1 ratio video_codec.SetScalabilityMode(ScalabilityMode::kL2T1h); video_codec.width = 1500; video_codec.height = 900; EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_EQ(video_codec.spatialLayers[0].width, 1000); EXPECT_EQ(video_codec.spatialLayers[0].height, 600); EXPECT_EQ(video_codec.spatialLayers[1].width, 1500); EXPECT_EQ(video_codec.spatialLayers[1].height, 900); } TEST(Av1SvcConfigTest, CopiesFramrate) { VideoCodec video_codec = GetDefaultVideoCodec(); video_codec.SetScalabilityMode(ScalabilityMode::kL2T1); video_codec.maxFramerate = 27; EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_EQ(video_codec.spatialLayers[0].maxFramerate, 27); EXPECT_EQ(video_codec.spatialLayers[1].maxFramerate, 27); } TEST(Av1SvcConfigTest, SetsNumberOfTemporalLayers) { VideoCodec video_codec = GetDefaultVideoCodec(); video_codec.SetScalabilityMode(ScalabilityMode::kL1T3); EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_EQ(video_codec.spatialLayers[0].numberOfTemporalLayers, 3); } TEST(Av1SvcConfigTest, CopiesMinMaxBitrateForSingleSpatialLayer) { VideoCodec video_codec; video_codec.codecType = kVideoCodecAV1; video_codec.SetScalabilityMode(ScalabilityMode::kL1T3); video_codec.minBitrate = 100; video_codec.maxBitrate = 500; EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_EQ(video_codec.spatialLayers[0].minBitrate, 100u); EXPECT_EQ(video_codec.spatialLayers[0].maxBitrate, 500u); EXPECT_LE(video_codec.spatialLayers[0].minBitrate, video_codec.spatialLayers[0].targetBitrate); EXPECT_LE(video_codec.spatialLayers[0].targetBitrate, video_codec.spatialLayers[0].maxBitrate); } TEST(Av1SvcConfigTest, SetsBitratesForMultipleSpatialLayers) { VideoCodec video_codec; video_codec.codecType = kVideoCodecAV1; video_codec.width = 640; video_codec.height = 360; video_codec.SetScalabilityMode(ScalabilityMode::kL2T2); EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_EQ(video_codec.spatialLayers[0].minBitrate, 20u); EXPECT_EQ(video_codec.spatialLayers[0].maxBitrate, 142u); EXPECT_EQ(video_codec.spatialLayers[1].minBitrate, 135u); EXPECT_EQ(video_codec.spatialLayers[1].maxBitrate, 418u); } TEST(Av1SvcConfigTest, ReduceSpatialLayersOnInsufficentInputResolution) { VideoCodec video_codec = GetDefaultVideoCodec(); video_codec.width = 640; video_codec.height = 360; video_codec.SetScalabilityMode(ScalabilityMode::kL3T3); EXPECT_TRUE(SetAv1SvcConfig(video_codec, /*num_temporal_layers=*/kDontCare, /*num_spatial_layers=*/kDontCare)); EXPECT_EQ(*video_codec.GetScalabilityMode(), ScalabilityMode::kL2T3); } } // namespace } // namespace webrtc