diff --git a/call/video_send_stream.h b/call/video_send_stream.h index 65c2aba328..487f3042a8 100644 --- a/call/video_send_stream.h +++ b/call/video_send_stream.h @@ -218,6 +218,15 @@ class VideoSendStream { // When a stream is stopped, it can't receive, process or deliver packets. virtual void Stop() = 0; + // Accessor for determining if the stream is active. This is an inexpensive + // call that must be made on the same thread as `Start()` and `Stop()` methods + // are called on and will return `true` iff activity has been started either + // via `Start()` or `UpdateActiveSimulcastLayers()`. If activity is either + // stopped or is in the process of being stopped as a result of a call to + // either `Stop()` or `UpdateActiveSimulcastLayers()` where all layers were + // deactivated, the return value will be `false`. + virtual bool started() = 0; + // If the resource is overusing, the VideoSendStream will try to reduce // resolution or frame rate until no resource is overusing. // TODO(https://crbug.com/webrtc/11565): When the ResourceAdaptationProcessor diff --git a/media/engine/fake_webrtc_call.h b/media/engine/fake_webrtc_call.h index 20e65d45f4..aeef95477e 100644 --- a/media/engine/fake_webrtc_call.h +++ b/media/engine/fake_webrtc_call.h @@ -196,6 +196,7 @@ class FakeVideoSendStream final const std::vector active_layers) override; void Start() override; void Stop() override; + bool started() override { return IsSending(); } void AddAdaptationResource( rtc::scoped_refptr resource) override; std::vector> GetAdaptationResources() diff --git a/video/video_send_stream.cc b/video/video_send_stream.cc index 46bf0dbc67..a947af9068 100644 --- a/video/video_send_stream.cc +++ b/video/video_send_stream.cc @@ -186,10 +186,16 @@ void VideoSendStream::UpdateActiveSimulcastLayers( const std::vector active_layers) { RTC_DCHECK_RUN_ON(&thread_checker_); + // Keep our `running_` flag expected state in sync with active layers since + // the `send_stream_` will be implicitly stopped/started depending on the + // state of the layers. + bool running = false; + rtc::StringBuilder active_layers_string; active_layers_string << "{"; for (size_t i = 0; i < active_layers.size(); ++i) { if (active_layers[i]) { + running = true; active_layers_string << "1"; } else { active_layers_string << "0"; @@ -202,10 +208,17 @@ void VideoSendStream::UpdateActiveSimulcastLayers( RTC_LOG(LS_INFO) << "UpdateActiveSimulcastLayers: " << active_layers_string.str(); - rtp_transport_queue_->PostTask( - ToQueuedTask(transport_queue_safety_, [this, active_layers] { + rtp_transport_queue_->PostTask(ToQueuedTask( + transport_queue_safety_, [this, active_layers, was_running = running_] { send_stream_.UpdateActiveSimulcastLayers(active_layers); + const bool running = rtp_video_sender_->IsActive(); + if (was_running != running) { + running ? transport_queue_safety_->SetAlive() + : transport_queue_safety_->SetNotAlive(); + } })); + + running_ = running; } void VideoSendStream::Start() { @@ -241,6 +254,11 @@ void VideoSendStream::Stop() { })); } +bool VideoSendStream::started() { + RTC_DCHECK_RUN_ON(&thread_checker_); + return running_; +} + void VideoSendStream::AddAdaptationResource( rtc::scoped_refptr resource) { RTC_DCHECK_RUN_ON(&thread_checker_); diff --git a/video/video_send_stream.h b/video/video_send_stream.h index b52871c6e1..0d132dd666 100644 --- a/video/video_send_stream.h +++ b/video/video_send_stream.h @@ -78,6 +78,7 @@ class VideoSendStream : public webrtc::VideoSendStream { const std::vector active_layers) override; void Start() override; void Stop() override; + bool started() override; void AddAdaptationResource(rtc::scoped_refptr resource) override; std::vector> GetAdaptationResources() override; @@ -94,8 +95,6 @@ class VideoSendStream : public webrtc::VideoSendStream { private: friend class test::VideoSendStreamPeer; - class ConstructionTask; - absl::optional GetPacingFactorOverride() const; RTC_NO_UNIQUE_ADDRESS SequenceChecker thread_checker_; @@ -110,7 +109,7 @@ class VideoSendStream : public webrtc::VideoSendStream { const VideoEncoderConfig::ContentType content_type_; std::unique_ptr video_stream_encoder_; EncoderRtcpFeedback encoder_feedback_; - RtpVideoSenderInterface* const rtp_video_sender_ = nullptr; + RtpVideoSenderInterface* const rtp_video_sender_; VideoSendStreamImpl send_stream_; bool running_ RTC_GUARDED_BY(thread_checker_) = false; }; diff --git a/video/video_send_stream_tests.cc b/video/video_send_stream_tests.cc index 5703f15ebc..85dbbafcec 100644 --- a/video/video_send_stream_tests.cc +++ b/video/video_send_stream_tests.cc @@ -2251,6 +2251,8 @@ TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) { CreateVideoStreams(); + EXPECT_FALSE(GetVideoSendStream()->started()); + // Inject a frame, to force encoder creation. GetVideoSendStream()->Start(); GetVideoSendStream()->SetSource(&forwarder, @@ -2264,6 +2266,7 @@ TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) { // which in turn updates the VideoEncoder's bitrate. SendTask(RTC_FROM_HERE, task_queue(), [this]() { GetVideoSendStream()->UpdateActiveSimulcastLayers({true, true}); + EXPECT_TRUE(GetVideoSendStream()->started()); }); EXPECT_TRUE(encoder.WaitBitrateChanged(true)); @@ -2280,6 +2283,7 @@ TEST_F(VideoSendStreamTest, VideoSendStreamUpdateActiveSimulcastLayers) { GetVideoEncoderConfig()->simulcast_layers[1].active = false; SendTask(RTC_FROM_HERE, task_queue(), [this]() { GetVideoSendStream()->UpdateActiveSimulcastLayers({false, false}); + EXPECT_FALSE(GetVideoSendStream()->started()); }); EXPECT_TRUE(encoder.WaitBitrateChanged(false));