Reconfigure encoders or source change
This is done in case the new source has a different clock source which
might be out of sync with the previous one, leading to timestamp
conflicts.
Bug: b/340198307
Change-Id: Id1a82823ca85e03d99dad31b7ce9f19f09447755
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/350560
Reviewed-by: Ilya Nikolaevskiy <ilnik@webrtc.org>
Commit-Queue: Erik Språng <sprang@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#42312}
diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc
index 7a10bf1..e985d29 100644
--- a/media/engine/webrtc_video_engine.cc
+++ b/media/engine/webrtc_video_engine.cc
@@ -1786,6 +1786,7 @@
TRACE_EVENT0("webrtc", "WebRtcVideoSendStream::SetVideoSend");
RTC_DCHECK_RUN_ON(&thread_checker_);
+ bool reconfiguration_needed = false;
if (options) {
VideoOptions old_options = parameters_.options;
parameters_.options.SetAll(*options);
@@ -1801,13 +1802,21 @@
old_options.is_screencast = options->is_screencast;
}
if (parameters_.options != old_options) {
- ReconfigureEncoder(nullptr);
+ reconfiguration_needed = true;
}
}
if (source_ && stream_) {
stream_->SetSource(nullptr, webrtc::DegradationPreference::DISABLED);
+ if (source && source != source_) {
+ reconfiguration_needed = true;
+ }
}
+
+ if (reconfiguration_needed) {
+ ReconfigureEncoder(nullptr);
+ }
+
// Switch to the new source.
source_ = source;
if (source && stream_) {
diff --git a/media/engine/webrtc_video_engine_unittest.cc b/media/engine/webrtc_video_engine_unittest.cc
index 6debc13..3ab079c 100644
--- a/media/engine/webrtc_video_engine_unittest.cc
+++ b/media/engine/webrtc_video_engine_unittest.cc
@@ -3691,6 +3691,39 @@
// Expect 1 reconfigurations at this point from the initial configuration.
EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
+ webrtc::test::FrameForwarder new_frame_forwarder;
+
+ // Set the options one more time but with a new source instance, expect
+ // one additional reconfiguration.
+ EXPECT_TRUE(
+ send_channel_->SetVideoSend(last_ssrc_, &options, &new_frame_forwarder));
+ new_frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
+ EXPECT_EQ(2, send_stream->num_encoder_reconfigurations());
+
+ EXPECT_TRUE(send_channel_->SetVideoSend(last_ssrc_, nullptr, nullptr));
+}
+
+// Test that if a new source is set, we reconfigure the encoder even if the
+// same options are used.
+TEST_F(WebRtcVideoChannelTest,
+ SetNewSourceWithIdenticalOptionsReconfiguresEncoder) {
+ VideoOptions options;
+ webrtc::test::FrameForwarder frame_forwarder;
+
+ AddSendStream();
+ cricket::VideoSenderParameters parameters;
+ parameters.codecs.push_back(GetEngineCodec("VP8"));
+ ASSERT_TRUE(send_channel_->SetSenderParameters(parameters));
+ FakeVideoSendStream* send_stream = fake_call_->GetVideoSendStreams().front();
+
+ EXPECT_TRUE(
+ send_channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
+ EXPECT_TRUE(
+ send_channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));
+ frame_forwarder.IncomingCapturedFrame(frame_source_.GetFrame());
+ // Expect 1 reconfigurations at this point from the initial configuration.
+ EXPECT_EQ(1, send_stream->num_encoder_reconfigurations());
+
// Set the options one more time and expect no additional reconfigurations.
EXPECT_TRUE(
send_channel_->SetVideoSend(last_ssrc_, &options, &frame_forwarder));