diff --git a/call/call_perf_tests.cc b/call/call_perf_tests.cc index 486195f3b4..6520e6fcf9 100644 --- a/call/call_perf_tests.cc +++ b/call/call_perf_tests.cc @@ -659,7 +659,6 @@ TEST_F(CallPerfTest, NoPadWithoutMinTransmitBitrate) { TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { static const uint32_t kInitialBitrateKbps = 400; static const uint32_t kReconfigureThresholdKbps = 600; - static const uint32_t kPermittedReconfiguredBitrateDiffKbps = 100; class VideoStreamFactory : public VideoEncoderConfig::VideoStreamFactoryInterface { @@ -710,9 +709,7 @@ TEST_F(CallPerfTest, MAYBE_KeepsHighBitrateWhenReconfiguringSender) { EXPECT_EQ(2 * kDefaultWidth, config->width); EXPECT_EQ(2 * kDefaultHeight, config->height); EXPECT_GE(last_set_bitrate_kbps_, kReconfigureThresholdKbps); - EXPECT_GT( - config->startBitrate, - last_set_bitrate_kbps_ - kPermittedReconfiguredBitrateDiffKbps) + EXPECT_GT(config->startBitrate, kReconfigureThresholdKbps) << "Encoder reconfigured with bitrate too far away from last set."; observation_complete_.Set(); } diff --git a/modules/congestion_controller/goog_cc/probe_controller.cc b/modules/congestion_controller/goog_cc/probe_controller.cc index 44836162f8..66838d3557 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.cc +++ b/modules/congestion_controller/goog_cc/probe_controller.cc @@ -137,8 +137,9 @@ void ProbeController::OnMaxTotalAllocatedBitrate( int64_t at_time_ms) { // TODO(philipel): Should |max_total_allocated_bitrate| be used as a limit for // ALR probing? - if (estimated_bitrate_bps_ != 0 && - estimated_bitrate_bps_ < max_bitrate_bps_ && + if (max_total_allocated_bitrate != max_total_allocated_bitrate_ && + estimated_bitrate_bps_ != 0 && + (max_bitrate_bps_ <= 0 || estimated_bitrate_bps_ < max_bitrate_bps_) && estimated_bitrate_bps_ < max_total_allocated_bitrate) { InitiateProbing(at_time_ms, {max_total_allocated_bitrate}, false); } @@ -256,6 +257,7 @@ void ProbeController::Reset(int64_t at_time_ms) { mid_call_probing_waiting_for_result_ = false; time_of_last_large_drop_ms_ = now_ms; bitrate_before_last_large_drop_bps_ = 0; + max_total_allocated_bitrate_ = 0; } void ProbeController::Process(int64_t at_time_ms) { diff --git a/modules/congestion_controller/goog_cc/probe_controller.h b/modules/congestion_controller/goog_cc/probe_controller.h index 6434b0ec8c..baa37367a1 100644 --- a/modules/congestion_controller/goog_cc/probe_controller.h +++ b/modules/congestion_controller/goog_cc/probe_controller.h @@ -90,6 +90,7 @@ class ProbeController { bool enable_periodic_alr_probing_; int64_t time_of_last_large_drop_ms_; int64_t bitrate_before_last_large_drop_bps_; + int64_t max_total_allocated_bitrate_; bool in_rapid_recovery_experiment_; // For WebRTC.BWE.MidCallProbing.* metric. diff --git a/modules/congestion_controller/probe_controller.cc b/modules/congestion_controller/probe_controller.cc index 381eaa2a0b..6fbe01e92e 100644 --- a/modules/congestion_controller/probe_controller.cc +++ b/modules/congestion_controller/probe_controller.cc @@ -130,9 +130,11 @@ void ProbeController::OnMaxTotalAllocatedBitrate( rtc::CritScope cs(&critsect_); // TODO(philipel): Should |max_total_allocated_bitrate| be used as a limit for // ALR probing? - if (estimated_bitrate_bps_ != 0 && - estimated_bitrate_bps_ < max_bitrate_bps_ && + if (max_total_allocated_bitrate != max_total_allocated_bitrate_ && + estimated_bitrate_bps_ != 0 && + (max_bitrate_bps_ <= 0 || estimated_bitrate_bps_ < max_bitrate_bps_) && estimated_bitrate_bps_ < max_total_allocated_bitrate) { + max_total_allocated_bitrate_ = max_total_allocated_bitrate; InitiateProbing(clock_->TimeInMilliseconds(), {max_total_allocated_bitrate}, false); } @@ -252,6 +254,7 @@ void ProbeController::Reset() { mid_call_probing_waiting_for_result_ = false; time_of_last_large_drop_ms_ = now_ms; bitrate_before_last_large_drop_bps_ = 0; + max_total_allocated_bitrate_ = 0; } void ProbeController::Process() { diff --git a/modules/congestion_controller/probe_controller.h b/modules/congestion_controller/probe_controller.h index 7c64b4ce10..084055bde1 100644 --- a/modules/congestion_controller/probe_controller.h +++ b/modules/congestion_controller/probe_controller.h @@ -83,6 +83,7 @@ class ProbeController { bool enable_periodic_alr_probing_ RTC_GUARDED_BY(critsect_); int64_t time_of_last_large_drop_ms_ RTC_GUARDED_BY(critsect_); int64_t bitrate_before_last_large_drop_bps_ RTC_GUARDED_BY(critsect_); + int64_t max_total_allocated_bitrate_ RTC_GUARDED_BY(critsect_); bool in_rapid_recovery_experiment_ RTC_GUARDED_BY(critsect_); // For WebRTC.BWE.MidCallProbing.* metric. diff --git a/test/encoder_settings.cc b/test/encoder_settings.cc index 665c82b3e7..33e81b0cfc 100644 --- a/test/encoder_settings.cc +++ b/test/encoder_settings.cc @@ -48,10 +48,37 @@ std::vector CreateVideoStreams( stream_settings[i].max_framerate = 30; stream_settings[i].min_bitrate_bps = DefaultVideoStreamFactory::kDefaultMinBitratePerStream[i]; - stream_settings[i].target_bitrate_bps = stream_settings[i].max_bitrate_bps = - std::min(bitrate_left_bps, - DefaultVideoStreamFactory::kMaxBitratePerStream[i]); + + int target_bitrate_bps = -1; + int max_bitrate_bps = -1; + // Use configured values instead of default values if values has been + // configured. + if (i < encoder_config.simulcast_layers.size()) { + const VideoStream& stream = encoder_config.simulcast_layers[i]; + + max_bitrate_bps = + stream.max_bitrate_bps > 0 + ? stream.max_bitrate_bps + : DefaultVideoStreamFactory::kMaxBitratePerStream[i]; + max_bitrate_bps = std::min(bitrate_left_bps, max_bitrate_bps); + + target_bitrate_bps = + stream.target_bitrate_bps > 0 + ? stream.target_bitrate_bps + : DefaultVideoStreamFactory::kMaxBitratePerStream[i]; + target_bitrate_bps = std::min(max_bitrate_bps, target_bitrate_bps); + } else { + max_bitrate_bps = std::min( + bitrate_left_bps, DefaultVideoStreamFactory::kMaxBitratePerStream[i]); + target_bitrate_bps = max_bitrate_bps; + } + + RTC_DCHECK_NE(target_bitrate_bps, -1); + RTC_DCHECK_NE(max_bitrate_bps, -1); + stream_settings[i].target_bitrate_bps = target_bitrate_bps; + stream_settings[i].max_bitrate_bps = max_bitrate_bps; stream_settings[i].max_qp = 56; + if (i < encoder_config.simulcast_layers.size()) { // Higher level controls are setting the active configuration for the // VideoStream. diff --git a/video/end_to_end_tests/probing_tests.cc b/video/end_to_end_tests/probing_tests.cc index db66f6215d..777a346754 100644 --- a/video/end_to_end_tests/probing_tests.cc +++ b/video/end_to_end_tests/probing_tests.cc @@ -188,4 +188,110 @@ TEST_P(ProbingEndToEndTest, TriggerMidCallProbing) { EXPECT_TRUE(success) << "Failed to perform mid call probing (" << kMaxAttempts << " attempts)."; } + +#if defined(MEMORY_SANITIZER) +TEST_P(ProbingEndToEndTest, DISABLED_ProbeOnVideoEncoderReconfiguration) { +#elif defined(TARGET_IPHONE_SIMULATOR) && TARGET_IPHONE_SIMULATOR +TEST_P(ProbingEndToEndTest, DISABLED_ProbeOnVideoEncoderReconfiguration) { +#else +TEST_P(ProbingEndToEndTest, ProbeOnVideoEncoderReconfiguration) { +#endif + + class ReconfigureTest : public ProbingTest { + public: + ReconfigureTest(test::SingleThreadedTaskQueueForTesting* task_queue, + bool* success) + : ProbingTest(50000), task_queue_(task_queue), success_(success) {} + + void ModifyVideoConfigs( + VideoSendStream::Config* send_config, + std::vector* receive_configs, + VideoEncoderConfig* encoder_config) override { + encoder_config_ = encoder_config; + } + + void OnVideoStreamsCreated( + VideoSendStream* send_stream, + const std::vector& receive_streams) override { + send_stream_ = send_stream; + } + + test::PacketTransport* CreateSendTransport( + test::SingleThreadedTaskQueueForTesting* task_queue, + Call* sender_call) override { + send_transport_ = new test::PacketTransport( + task_queue, sender_call, this, test::PacketTransport::kSender, + CallTest::payload_type_map_, FakeNetworkPipe::Config()); + return send_transport_; + } + + void PerformTest() override { + *success_ = false; + int64_t start_time_ms = clock_->TimeInMilliseconds(); + do { + if (clock_->TimeInMilliseconds() - start_time_ms > kTimeoutMs) + break; + + Call::Stats stats = sender_call_->GetStats(); + + switch (state_) { + case 0: + // Wait until initial probing has been completed (6 times start + // bitrate). + if (stats.send_bandwidth_bps >= 250000 && + stats.send_bandwidth_bps <= 350000) { + FakeNetworkPipe::Config config; + config.link_capacity_kbps = 200; + send_transport_->SetConfig(config); + + ++state_; + } + break; + case 1: + if (stats.send_bandwidth_bps <= 210000) { + FakeNetworkPipe::Config config; + config.link_capacity_kbps = 5000; + send_transport_->SetConfig(config); + + encoder_config_->max_bitrate_bps = 2000000; + encoder_config_->simulcast_layers[0].max_bitrate_bps = 1200000; + task_queue_->SendTask([this]() { + send_stream_->ReconfigureVideoEncoder(encoder_config_->Copy()); + }); + + ++state_; + } + break; + case 2: + if (stats.send_bandwidth_bps >= 1000000) { + *success_ = true; + observation_complete_.Set(); + } + break; + } + } while (!observation_complete_.Wait(20)); + } + + private: + const int kTimeoutMs = 3000; + test::SingleThreadedTaskQueueForTesting* const task_queue_; + bool* const success_; + test::PacketTransport* send_transport_; + VideoSendStream* send_stream_; + VideoEncoderConfig* encoder_config_; + }; + + bool success = false; + const int kMaxAttempts = 3; + for (int i = 0; i < kMaxAttempts; ++i) { + ReconfigureTest test(&task_queue_, &success); + RunBaseTest(&test); + if (success) { + return; + } + } + EXPECT_TRUE(success) << "Failed to perform mid call probing (" << kMaxAttempts + << " attempts)."; +} + } // namespace webrtc