Change VideoStreamConfig to use vector of scalability modes.
Each entry represents one simulcast stream.
Bug: webrtc:11607
Change-Id: If78ff334fdb99322deded57f0cbe7ebad7de5abc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/265960
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Artem Titov <titovartem@webrtc.org>
Reviewed-by: Florent Castelli <orphis@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#37272}
diff --git a/test/scenario/BUILD.gn b/test/scenario/BUILD.gn
index ddcce69..dc38247 100644
--- a/test/scenario/BUILD.gn
+++ b/test/scenario/BUILD.gn
@@ -97,6 +97,7 @@
"../../api/video:builtin_video_bitrate_allocator_factory",
"../../api/video:video_frame",
"../../api/video:video_rtp_headers",
+ "../../api/video_codecs:scalability_mode",
"../../api/video_codecs:video_codecs_api",
"../../audio",
"../../call",
@@ -123,6 +124,7 @@
"../../modules/video_coding:webrtc_multiplex",
"../../modules/video_coding:webrtc_vp8",
"../../modules/video_coding:webrtc_vp9",
+ "../../modules/video_coding/svc:scalability_mode_util",
"../../rtc_base",
"../../rtc_base:checks",
"../../rtc_base:copy_on_write_buffer",
diff --git a/test/scenario/probing_test.cc b/test/scenario/probing_test.cc
index f08a003..74b68fc 100644
--- a/test/scenario/probing_test.cc
+++ b/test/scenario/probing_test.cc
@@ -86,7 +86,9 @@
VideoStreamConfig video_config;
video_config.encoder.codec =
VideoStreamConfig::Encoder::Codec::kVideoCodecVP8;
- video_config.encoder.layers.spatial = 3;
+ video_config.encoder.simulcast_streams = {webrtc::ScalabilityMode::kL1T3,
+ webrtc::ScalabilityMode::kL1T3,
+ webrtc::ScalabilityMode::kL1T3};
video_config.source.generator.width = 1280;
video_config.source.generator.height = 720;
diff --git a/test/scenario/scenario_config.h b/test/scenario/scenario_config.h
index c0dcd65..5ff622f 100644
--- a/test/scenario/scenario_config.h
+++ b/test/scenario/scenario_config.h
@@ -23,6 +23,7 @@
#include "api/units/data_size.h"
#include "api/units/time_delta.h"
#include "api/video/video_codec_type.h"
+#include "api/video_codecs/scalability_mode.h"
#include "test/scenario/performance_stats.h"
namespace webrtc {
@@ -138,15 +139,8 @@
bool denoising = true;
bool automatic_scaling = true;
} single;
- struct Layers {
- int temporal = 1;
- int spatial = 1;
- enum class Prediction {
- kTemporalOnly,
- kSpatialOnKey,
- kFull,
- } prediction = Prediction::kFull;
- } layers;
+ std::vector<webrtc::ScalabilityMode> simulcast_streams = {
+ webrtc::ScalabilityMode::kL1T1};
DegradationPreference degradation_preference =
DegradationPreference::MAINTAIN_FRAMERATE;
diff --git a/test/scenario/video_stream.cc b/test/scenario/video_stream.cc
index 3fcef57..3d1253a 100644
--- a/test/scenario/video_stream.cc
+++ b/test/scenario/video_stream.cc
@@ -22,6 +22,7 @@
#include "media/engine/internal_decoder_factory.h"
#include "media/engine/internal_encoder_factory.h"
#include "media/engine/webrtc_video_engine.h"
+#include "modules/video_coding/svc/scalability_mode_util.h"
#include "test/call_test.h"
#include "test/fake_encoder.h"
#include "test/scenario/hardware_codecs.h"
@@ -77,18 +78,7 @@
return VideoEncoderConfig::ContentType::kScreen;
}
}
-InterLayerPredMode ToInterLayerPredMode(
- VideoStreamConfig::Encoder::Layers::Prediction value) {
- using Pred = VideoStreamConfig::Encoder::Layers::Prediction;
- switch (value) {
- case Pred::kTemporalOnly:
- return InterLayerPredMode::kOff;
- case Pred::kSpatialOnKey:
- return InterLayerPredMode::kOnKeyPic;
- case Pred::kFull:
- return InterLayerPredMode::kOn;
- }
-}
+
std::vector<RtpExtension> GetVideoRtpExtensions(
const VideoStreamConfig config) {
std::vector<RtpExtension> res = {
@@ -155,18 +145,23 @@
constexpr auto kScreen = VideoStreamConfig::Encoder::ContentType::kScreen;
VideoStreamConfig::Encoder conf = video_config.encoder;
VideoCodecVP9 vp9 = VideoEncoder::GetDefaultVp9Settings();
+ // TODO(bugs.webrtc.org/11607): Support separate scalability mode per
+ // simulcast stream.
+ ScalabilityMode scalability_mode = conf.simulcast_streams[0];
vp9.keyFrameInterval = conf.key_frame_interval.value_or(0);
- vp9.numberOfTemporalLayers = static_cast<uint8_t>(conf.layers.temporal);
- vp9.numberOfSpatialLayers = static_cast<uint8_t>(conf.layers.spatial);
- vp9.interLayerPred = ToInterLayerPredMode(conf.layers.prediction);
+ vp9.numberOfTemporalLayers =
+ ScalabilityModeToNumTemporalLayers(scalability_mode);
+ vp9.numberOfSpatialLayers =
+ ScalabilityModeToNumSpatialLayers(scalability_mode);
+ vp9.interLayerPred = ScalabilityModeToInterLayerPredMode(scalability_mode);
if (conf.content_type == kScreen &&
- (video_config.source.framerate > 5 || conf.layers.spatial >= 3)) {
+ (video_config.source.framerate > 5 || vp9.numberOfSpatialLayers >= 3)) {
vp9.flexibleMode = true;
}
- if (conf.content_type == kScreen ||
- conf.layers.temporal * conf.layers.spatial) {
+ if (conf.content_type == kScreen || vp9.numberOfTemporalLayers > 1 ||
+ vp9.numberOfSpatialLayers > 1) {
vp9.automaticResizeOn = false;
vp9.denoisingOn = false;
} else {
@@ -181,8 +176,13 @@
CreateVp8SpecificSettings(VideoStreamConfig config) {
VideoCodecVP8 vp8_settings = VideoEncoder::GetDefaultVp8Settings();
vp8_settings.keyFrameInterval = config.encoder.key_frame_interval.value_or(0);
- vp8_settings.numberOfTemporalLayers = config.encoder.layers.temporal;
- if (config.encoder.layers.spatial * config.encoder.layers.temporal > 1) {
+ // TODO(bugs.webrtc.org/11607): Support separate scalability mode per
+ // simulcast stream.
+ ScalabilityMode scalability_mode = config.encoder.simulcast_streams[0];
+ vp8_settings.numberOfTemporalLayers =
+ ScalabilityModeToNumTemporalLayers(scalability_mode);
+ if (vp8_settings.numberOfTemporalLayers > 1 ||
+ config.encoder.simulcast_streams.size() > 1) {
vp8_settings.automaticResizeOn = false;
vp8_settings.denoisingOn = false;
} else {
@@ -195,9 +195,8 @@
rtc::scoped_refptr<VideoEncoderConfig::EncoderSpecificSettings>
CreateH264SpecificSettings(VideoStreamConfig config) {
- RTC_DCHECK_EQ(config.encoder.layers.temporal, 1);
- RTC_DCHECK_EQ(config.encoder.layers.spatial, 1);
-
+ RTC_DCHECK_EQ(config.encoder.simulcast_streams.size(), 1);
+ RTC_DCHECK(config.encoder.simulcast_streams[0] == ScalabilityMode::kL1T1);
// TODO(bugs.webrtc.org/6883): Set a key frame interval as a setting that
// isn't codec specific.
RTC_CHECK_EQ(0, config.encoder.key_frame_interval.value_or(0));
@@ -230,12 +229,9 @@
encoder_config.video_format =
SdpVideoFormat(CodecTypeToPayloadString(config.encoder.codec), {});
- encoder_config.number_of_streams = 1;
- if (config.encoder.codec == VideoStreamConfig::Encoder::Codec::kVideoCodecVP8)
- encoder_config.number_of_streams =
- static_cast<size_t>(config.encoder.layers.spatial);
+ encoder_config.number_of_streams = config.encoder.simulcast_streams.size();
encoder_config.simulcast_layers =
- std::vector<VideoStream>(config.encoder.layers.spatial);
+ std::vector<VideoStream>(encoder_config.number_of_streams);
encoder_config.min_transmit_bitrate_bps = config.stream.pad_to_rate.bps();
std::string cricket_codec = CodecTypeToCodecName(config.encoder.codec);
@@ -258,11 +254,14 @@
encoder_config.frame_drop_enabled = config.encoder.frame_dropping;
encoder_config.encoder_specific_settings =
CreateEncoderSpecificSettings(config);
- if (config.encoder.max_framerate) {
- for (auto& layer : encoder_config.simulcast_layers) {
+
+ for (size_t i = 0; i < encoder_config.number_of_streams; ++i) {
+ auto& layer = encoder_config.simulcast_layers[i];
+ if (config.encoder.max_framerate) {
layer.max_framerate = *config.encoder.max_framerate;
layer.min_bitrate_bps = config.encoder.min_data_rate->bps_or(-1);
}
+ layer.scalability_mode = config.encoder.simulcast_streams[i];
}
return encoder_config;
@@ -549,9 +548,7 @@
VideoReceiveStreamInterface::Decoder decoder =
CreateMatchingDecoder(CodecTypeToPayloadType(config.encoder.codec),
CodecTypeToPayloadString(config.encoder.codec));
- size_t num_streams = 1;
- if (config.encoder.codec == VideoStreamConfig::Encoder::Codec::kVideoCodecVP8)
- num_streams = config.encoder.layers.spatial;
+ size_t num_streams = config.encoder.simulcast_streams.size();
for (size_t i = 0; i < num_streams; ++i) {
rtc::VideoSinkInterface<VideoFrame>* renderer = &fake_renderer_;
if (matcher->Active()) {
diff --git a/test/scenario/video_stream_unittest.cc b/test/scenario/video_stream_unittest.cc
index b37530d..e53af4e 100644
--- a/test/scenario/video_stream_unittest.cc
+++ b/test/scenario/video_stream_unittest.cc
@@ -102,8 +102,11 @@
c->source.generator.height = 768;
c->encoder.implementation = CodecImpl::kSoftware;
c->encoder.codec = Codec::kVideoCodecVP8;
- // By enabling multiple spatial layers, simulcast will be enabled for VP8.
- c->encoder.layers.spatial = 3;
+ // Enable simulcast.
+ c->encoder.simulcast_streams = {webrtc::ScalabilityMode::kL1T1,
+ webrtc::ScalabilityMode::kL1T1,
+ webrtc::ScalabilityMode::kL1T1};
+
});
s.RunFor(kRunTime);
}
@@ -213,7 +216,7 @@
c->encoder.implementation = CodecImpl::kSoftware;
c->encoder.codec = Codec::kVideoCodecVP9;
// Enable SVC.
- c->encoder.layers.spatial = 2;
+ c->encoder.simulcast_streams = {webrtc::ScalabilityMode::kL2T1};
});
// Run for a few seconds, until streams have stabilized,