diff --git a/test/fake_encoder.cc b/test/fake_encoder.cc index 4736870d98..aca3453869 100644 --- a/test/fake_encoder.cc +++ b/test/fake_encoder.cc @@ -65,6 +65,7 @@ void FakeEncoder::SetMaxBitrate(int max_kbps) { RTC_DCHECK_GE(max_kbps, -1); // max_kbps == -1 disables it. rtc::CritScope cs(&crit_sect_); max_target_bitrate_kbps_ = max_kbps; + SetRateAllocation(target_bitrate_, configured_input_framerate_); } int32_t FakeEncoder::InitEncode(const VideoCodec* config, diff --git a/test/scenario/scenario_config.h b/test/scenario/scenario_config.h index 02cd21ece6..88fdb8af01 100644 --- a/test/scenario/scenario_config.h +++ b/test/scenario/scenario_config.h @@ -111,6 +111,7 @@ struct VideoStreamConfig { absl::optional key_frame_interval = 3000; absl::optional max_data_rate; + absl::optional max_framerate; size_t num_simulcast_streams = 1; using DegradationPreference = DegradationPreference; DegradationPreference degradation_preference = diff --git a/test/scenario/video_stream.cc b/test/scenario/video_stream.cc index 77dff147c6..9a5d4619fb 100644 --- a/test/scenario/video_stream.cc +++ b/test/scenario/video_stream.cc @@ -163,6 +163,12 @@ VideoEncoderConfig CreateVideoEncoderConfig(VideoStreamConfig config) { } encoder_config.encoder_specific_settings = CreateEncoderSpecificSettings(config); + if (config.encoder.max_framerate) { + for (auto& layer : encoder_config.simulcast_layers) { + layer.max_framerate = *config.encoder.max_framerate; + } + } + return encoder_config; } } // namespace @@ -203,11 +209,13 @@ SendVideoStream::SendVideoStream(CallClient* sender, case Encoder::Implementation::kFake: if (config.encoder.codec == Codec::kVideoCodecGeneric) { encoder_factory_ = - absl::make_unique([this, config]() { + absl::make_unique([this]() { + rtc::CritScope cs(&crit_); auto encoder = absl::make_unique(sender_->clock_); - if (config.encoder.fake.max_rate.IsFinite()) - encoder->SetMaxBitrate(config.encoder.fake.max_rate.kbps()); + fake_encoders_.push_back(encoder.get()); + if (config_.encoder.fake.max_rate.IsFinite()) + encoder->SetMaxBitrate(config_.encoder.fake.max_rate.kbps()); return encoder; }); } else { @@ -250,17 +258,31 @@ void SendVideoStream::Start() { video_capturer_->Start(); } +void SendVideoStream::UpdateConfig( + std::function modifier) { + rtc::CritScope cs(&crit_); + VideoStreamConfig prior_config = config_; + modifier(&config_); + if (prior_config.encoder.fake.max_rate != config_.encoder.fake.max_rate) { + for (auto* encoder : fake_encoders_) { + encoder->SetMaxBitrate(config_.encoder.fake.max_rate.kbps()); + } + } + // TODO(srte): Add more conditions that should cause reconfiguration. + if (prior_config.encoder.max_framerate != config_.encoder.max_framerate) { + VideoEncoderConfig encoder_config = CreateVideoEncoderConfig(config_); + send_stream_->ReconfigureVideoEncoder(std::move(encoder_config)); + } + if (prior_config.source.framerate != config_.source.framerate) { + SetCaptureFramerate(config_.source.framerate); + } +} + void SendVideoStream::SetCaptureFramerate(int framerate) { RTC_CHECK(frame_generator_) << "Framerate change only implemented for generators"; frame_generator_->ChangeFramerate(framerate); -} -void SendVideoStream::SetMaxFramerate(absl::optional max_framerate) { - VideoEncoderConfig encoder_config = CreateVideoEncoderConfig(config_); - RTC_DCHECK_EQ(encoder_config.simulcast_layers.size(), 1); - encoder_config.simulcast_layers[0].max_framerate = max_framerate.value_or(-1); - send_stream_->ReconfigureVideoEncoder(std::move(encoder_config)); } VideoSendStream::Stats SendVideoStream::GetStats() const { @@ -290,9 +312,7 @@ ReceiveVideoStream::ReceiveVideoStream(CallClient* receiver, SendVideoStream* send_stream, size_t chosen_stream, Transport* feedback_transport) - : receiver_(receiver), - config_(config), - decoder_factory_(absl::make_unique()) { + : receiver_(receiver), config_(config) { renderer_ = absl::make_unique(); VideoReceiveStream::Config recv_config(feedback_transport); recv_config.rtp.remb = !config.stream.packet_feedback; @@ -317,6 +337,13 @@ ReceiveVideoStream::ReceiveVideoStream(CallClient* receiver, VideoReceiveStream::Decoder decoder = CreateMatchingDecoder(CodecTypeToPayloadType(config.encoder.codec), CodecTypeToPayloadString(config.encoder.codec)); + if (config.encoder.codec == + VideoStreamConfig::Encoder::Codec::kVideoCodecGeneric) { + decoder_factory_ = absl::make_unique( + []() { return absl::make_unique(); }); + } else { + decoder_factory_ = absl::make_unique(); + } decoder.decoder_factory = decoder_factory_.get(); recv_config.decoders.push_back(decoder); diff --git a/test/scenario/video_stream.h b/test/scenario/video_stream.h index e984a075dd..a68dbf6c8a 100644 --- a/test/scenario/video_stream.h +++ b/test/scenario/video_stream.h @@ -14,6 +14,7 @@ #include #include "rtc_base/constructormagic.h" +#include "test/fake_encoder.h" #include "test/frame_generator_capturer.h" #include "test/scenario/call_client.h" #include "test/scenario/column_printer.h" @@ -30,10 +31,10 @@ class SendVideoStream { RTC_DISALLOW_COPY_AND_ASSIGN(SendVideoStream); ~SendVideoStream(); void SetCaptureFramerate(int framerate); - void SetMaxFramerate(absl::optional max_framerate); VideoSendStream::Stats GetStats() const; ColumnPrinter StatsPrinter(); void Start(); + void UpdateConfig(std::function modifier); private: friend class Scenario; @@ -44,12 +45,14 @@ class SendVideoStream { VideoStreamConfig config, Transport* send_transport); + rtc::CriticalSection crit_; std::vector ssrcs_; std::vector rtx_ssrcs_; VideoSendStream* send_stream_ = nullptr; CallClient* const sender_; - const VideoStreamConfig config_; + VideoStreamConfig config_ RTC_GUARDED_BY(crit_); std::unique_ptr encoder_factory_; + std::vector fake_encoders_ RTC_GUARDED_BY(crit_); std::unique_ptr bitrate_allocator_factory_; std::unique_ptr video_capturer_; FrameGeneratorCapturer* frame_generator_ = nullptr;