diff --git a/webrtc/media/base/mediachannel.h b/webrtc/media/base/mediachannel.h index 6a56bcdb02..424572de2f 100644 --- a/webrtc/media/base/mediachannel.h +++ b/webrtc/media/base/mediachannel.h @@ -188,6 +188,7 @@ struct AudioOptions { playout_sample_rate == o.playout_sample_rate && combined_audio_video_bwe == o.combined_audio_video_bwe; } + bool operator!=(const AudioOptions& o) const { return !(*this == o); } std::string ToString() const { std::ostringstream ost; @@ -279,6 +280,7 @@ struct VideoOptions { screencast_min_bitrate_kbps == o.screencast_min_bitrate_kbps && is_screencast == o.is_screencast; } + bool operator!=(const VideoOptions& o) const { return !(*this == o); } std::string ToString() const { std::ostringstream ost; diff --git a/webrtc/media/engine/fakewebrtccall.cc b/webrtc/media/engine/fakewebrtccall.cc index 2da9e0c3f0..8eff0ebcf8 100644 --- a/webrtc/media/engine/fakewebrtccall.cc +++ b/webrtc/media/engine/fakewebrtccall.cc @@ -183,6 +183,7 @@ void FakeVideoSendStream::ReconfigureVideoEncoder( } } codec_settings_set_ = config.encoder_specific_settings != NULL; + ++num_encoder_reconfigurations_; } webrtc::VideoCaptureInput* FakeVideoSendStream::Input() { diff --git a/webrtc/media/engine/fakewebrtccall.h b/webrtc/media/engine/fakewebrtccall.h index b1e20ce4c0..9caa02a9b7 100644 --- a/webrtc/media/engine/fakewebrtccall.h +++ b/webrtc/media/engine/fakewebrtccall.h @@ -119,6 +119,9 @@ class FakeVideoSendStream final : public webrtc::VideoSendStream, int GetLastHeight() const; int64_t GetLastTimestamp() const; void SetStats(const webrtc::VideoSendStream::Stats& stats); + int num_encoder_reconfigurations() const { + return num_encoder_reconfigurations_; + } private: void IncomingCapturedFrame(const webrtc::VideoFrame& frame) override; @@ -148,6 +151,7 @@ class FakeVideoSendStream final : public webrtc::VideoSendStream, int num_swapped_frames_; webrtc::VideoFrame last_frame_; webrtc::VideoSendStream::Stats stats_; + int num_encoder_reconfigurations_ = 0; }; class FakeVideoReceiveStream final : public webrtc::VideoReceiveStream { diff --git a/webrtc/media/engine/webrtcvideoengine2.cc b/webrtc/media/engine/webrtcvideoengine2.cc index 2440fce642..a65f799bd6 100644 --- a/webrtc/media/engine/webrtcvideoengine2.cc +++ b/webrtc/media/engine/webrtcvideoengine2.cc @@ -1693,10 +1693,13 @@ void WebRtcVideoChannel2::WebRtcVideoSendStream::SetOptions( const VideoOptions& options) { rtc::CritScope cs(&lock_); + VideoOptions old_options = parameters_.options; parameters_.options.SetAll(options); // Reconfigure encoder settings on the next frame or stream - // recreation. - pending_encoder_reconfiguration_ = true; + // recreation if the options changed. + if (parameters_.options != old_options) { + pending_encoder_reconfiguration_ = true; + } } webrtc::VideoCodecType CodecTypeFromName(const std::string& name) { diff --git a/webrtc/media/engine/webrtcvideoengine2_unittest.cc b/webrtc/media/engine/webrtcvideoengine2_unittest.cc index a8d743e1d5..2f5ad6dd2a 100644 --- a/webrtc/media/engine/webrtcvideoengine2_unittest.cc +++ b/webrtc/media/engine/webrtcvideoengine2_unittest.cc @@ -1812,6 +1812,30 @@ TEST_F(WebRtcVideoChannel2Test, VerifyVp8SpecificSettings) { EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, NULL)); } +// Test that setting the same options doesn't result in the encoder being +// reconfigured. +TEST_F(WebRtcVideoChannel2Test, SetIdenticalOptionsDoesntReconfigureEncoder) { + VideoOptions options; + cricket::FakeVideoCapturer capturer; + + FakeVideoSendStream* send_stream = AddSendStream(); + EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, &capturer)); + EXPECT_EQ(cricket::CS_RUNNING, + capturer.Start(capturer.GetSupportedFormats()->front())); + EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options)); + EXPECT_TRUE(capturer.CaptureFrame()); + // Expect 2 reconfigurations at this point, from the initial configuration + // and from the dimensions of the first frame. + EXPECT_EQ(2, send_stream->num_encoder_reconfigurations()); + + // Set the options one more time and expect no additional reconfigurations. + EXPECT_TRUE(channel_->SetVideoSend(last_ssrc_, true, &options)); + EXPECT_TRUE(capturer.CaptureFrame()); + EXPECT_EQ(2, send_stream->num_encoder_reconfigurations()); + + EXPECT_TRUE(channel_->SetCapturer(last_ssrc_, nullptr)); +} + class Vp9SettingsTest : public WebRtcVideoChannel2Test { public: Vp9SettingsTest() : Vp9SettingsTest("") {}