Ensure BitrateAllocator is updated with stream max bitrate after codec change
Bug: webrtc:341803760
Change-Id: I4453cf98fa98068aa94b3e091f03304d5cd4e6dc
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/351142
Reviewed-by: Erik Språng <sprang@webrtc.org>
Commit-Queue: Per Kjellander <perkj@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42361}
diff --git a/video/video_send_stream_impl.cc b/video/video_send_stream_impl.cc
index 682183e..b42c577 100644
--- a/video/video_send_stream_impl.cc
+++ b/video/video_send_stream_impl.cc
@@ -806,13 +806,12 @@
? experimental_min_bitrate->bps()
: std::max(streams[0].min_bitrate_bps,
GetDefaultMinVideoBitrateBps(codec_type));
-
- encoder_max_bitrate_bps_ = 0;
double stream_bitrate_priority_sum = 0;
+ uint32_t encoder_max_bitrate_bps = 0;
for (const auto& stream : streams) {
// We don't want to allocate more bitrate than needed to inactive streams.
if (stream.active) {
- encoder_max_bitrate_bps_ += stream.max_bitrate_bps;
+ encoder_max_bitrate_bps += stream.max_bitrate_bps;
}
if (stream.bitrate_priority) {
RTC_DCHECK_GT(*stream.bitrate_priority, 0);
@@ -821,9 +820,11 @@
}
RTC_DCHECK_GT(stream_bitrate_priority_sum, 0);
encoder_bitrate_priority_ = stream_bitrate_priority_sum;
- encoder_max_bitrate_bps_ =
- std::max(static_cast<uint32_t>(encoder_min_bitrate_bps_),
- encoder_max_bitrate_bps_);
+ if (encoder_max_bitrate_bps > 0) {
+ encoder_max_bitrate_bps_ =
+ std::max(static_cast<uint32_t>(encoder_min_bitrate_bps_),
+ encoder_max_bitrate_bps);
+ }
// TODO(bugs.webrtc.org/10266): Query the VideoBitrateAllocator instead.
max_padding_bitrate_ = CalculateMaxPadBitrateBps(
diff --git a/video/video_send_stream_impl_unittest.cc b/video/video_send_stream_impl_unittest.cc
index 548a6f6..29ac08e 100644
--- a/video/video_send_stream_impl_unittest.cc
+++ b/video/video_send_stream_impl_unittest.cc
@@ -73,12 +73,15 @@
using ::testing::_;
using ::testing::AllOf;
using ::testing::AnyNumber;
+using ::testing::Eq;
using ::testing::Field;
using ::testing::Invoke;
using ::testing::Mock;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::SaveArg;
+using ::testing::Sequence;
+using ::testing::SizeIs;
constexpr int64_t kDefaultInitialBitrateBps = 333000;
const double kDefaultBitratePriority = 0.5;
@@ -180,6 +183,7 @@
encoder_config.content_type = content_type;
encoder_config.simulcast_layers.push_back(VideoStream());
encoder_config.simulcast_layers.back().active = true;
+ encoder_config.simulcast_layers.back().bitrate_priority = 1.0;
return encoder_config;
}
@@ -275,6 +279,59 @@
}
TEST_F(VideoSendStreamImplTest,
+ MaxBitrateCorrectIfActiveEncodingUpdatedAfterCreation) {
+ VideoEncoderConfig one_active_encoding = TestVideoEncoderConfig();
+ ASSERT_THAT(one_active_encoding.simulcast_layers, SizeIs(1));
+ one_active_encoding.max_bitrate_bps = 10'000'000;
+ one_active_encoding.simulcast_layers[0].max_bitrate_bps = 2'000'000;
+ VideoEncoderConfig no_active_encodings = one_active_encoding.Copy();
+ no_active_encodings.simulcast_layers[0].active = false;
+ auto vss_impl = CreateVideoSendStreamImpl(no_active_encodings.Copy());
+
+ encoder_queue_->PostTask([&] {
+ static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
+ ->OnEncoderConfigurationChanged(
+ no_active_encodings.simulcast_layers, false,
+ VideoEncoderConfig::ContentType::kRealtimeVideo,
+ /*min_transmit_bitrate_bps*/ 30000);
+ });
+ time_controller_.AdvanceTime(TimeDelta::Zero());
+
+ Sequence s;
+ // Expect codec max bitrate as max needed bitrate before the encoder has
+ // notifed about the actual send streams.
+ EXPECT_CALL(bitrate_allocator_,
+ AddObserver(vss_impl.get(),
+ Field(&MediaStreamAllocationConfig::max_bitrate_bps,
+ Eq(one_active_encoding.max_bitrate_bps))))
+ .InSequence(s);
+
+ // Expect the sum of active encodings as max needed bitrate after
+ // ->OnEncoderConfigurationChanged.
+ EXPECT_CALL(
+ bitrate_allocator_,
+ AddObserver(
+ vss_impl.get(),
+ Field(&MediaStreamAllocationConfig::max_bitrate_bps,
+ Eq(one_active_encoding.simulcast_layers[0].max_bitrate_bps))))
+ .InSequence(s);
+ vss_impl->Start();
+ // Enable encoding of a stream.
+ vss_impl->ReconfigureVideoEncoder(one_active_encoding.Copy());
+ encoder_queue_->PostTask([&] {
+ static_cast<VideoStreamEncoderInterface::EncoderSink*>(vss_impl.get())
+ ->OnEncoderConfigurationChanged(
+ one_active_encoding.simulcast_layers, false,
+ VideoEncoderConfig::ContentType::kRealtimeVideo,
+ /*min_transmit_bitrate_bps*/ 30000);
+ });
+ time_controller_.AdvanceTime(TimeDelta::Zero());
+
+ EXPECT_CALL(bitrate_allocator_, RemoveObserver(vss_impl.get())).InSequence(s);
+ vss_impl->Stop();
+}
+
+TEST_F(VideoSendStreamImplTest,
DoNotRegistersAsBitrateObserverOnStrayEncodedImage) {
auto vss_impl = CreateVideoSendStreamImpl(TestVideoEncoderConfig());