diff --git a/media/engine/webrtc_video_engine.cc b/media/engine/webrtc_video_engine.cc index 9c97bd1567..e0018726f1 100644 --- a/media/engine/webrtc_video_engine.cc +++ b/media/engine/webrtc_video_engine.cc @@ -1567,6 +1567,7 @@ WebRtcVideoChannel::WebRtcVideoSendStream::WebRtcVideoSendStream( enable_cpu_overuse_detection_(enable_cpu_overuse_detection), source_(nullptr), stream_(nullptr), + encoder_sink_(nullptr), parameters_(std::move(config), options, max_bitrate_bps, codec_settings), rtp_parameters_(CreateRtpParametersWithEncodings(sp)), sending_(false) { @@ -1662,7 +1663,7 @@ bool WebRtcVideoChannel::WebRtcVideoSendStream::SetVideoSend( // Switch to the new source. source_ = source; if (source && stream_) { - stream_->SetSource(source_, GetDegradationPreference()); + stream_->SetSource(this, GetDegradationPreference()); } return true; } @@ -1842,7 +1843,7 @@ webrtc::RTCError WebRtcVideoChannel::WebRtcVideoSendStream::SetRtpParameters( UpdateSendState(); } if (new_degradation_preference) { - stream_->SetSource(source_, GetDegradationPreference()); + stream_->SetSource(this, GetDegradationPreference()); } return webrtc::RTCError::OK(); } @@ -2023,6 +2024,39 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::SetSend(bool send) { UpdateSendState(); } +void WebRtcVideoChannel::WebRtcVideoSendStream::RemoveSink( + rtc::VideoSinkInterface* sink) { + RTC_DCHECK_RUN_ON(&thread_checker_); + RTC_DCHECK(encoder_sink_ == sink); + encoder_sink_ = nullptr; + source_->RemoveSink(sink); +} + +void WebRtcVideoChannel::WebRtcVideoSendStream::AddOrUpdateSink( + rtc::VideoSinkInterface* sink, + const rtc::VideoSinkWants& wants) { + if (worker_thread_ == rtc::Thread::Current()) { + // AddOrUpdateSink is called on |worker_thread_| if this is the first + // registration of |sink|. + RTC_DCHECK_RUN_ON(&thread_checker_); + encoder_sink_ = sink; + source_->AddOrUpdateSink(encoder_sink_, wants); + } else { + // Subsequent calls to AddOrUpdateSink will happen on the encoder task + // queue. + invoker_.AsyncInvoke( + RTC_FROM_HERE, worker_thread_, [this, sink, wants] { + RTC_DCHECK_RUN_ON(&thread_checker_); + // |sink| may be invalidated after this task was posted since + // RemoveSink is called on the worker thread. + bool encoder_sink_valid = (sink == encoder_sink_); + if (source_ && encoder_sink_valid) { + source_->AddOrUpdateSink(encoder_sink_, wants); + } + }); + } +} + VideoSenderInfo WebRtcVideoChannel::WebRtcVideoSendStream::GetVideoSenderInfo( bool log_stats) { VideoSenderInfo info; @@ -2145,7 +2179,7 @@ void WebRtcVideoChannel::WebRtcVideoSendStream::RecreateWebRtcStream() { parameters_.encoder_config.encoder_specific_settings = NULL; if (source_) { - stream_->SetSource(source_, GetDegradationPreference()); + stream_->SetSource(this, GetDegradationPreference()); } // Call stream_->Start() if necessary conditions are met. diff --git a/media/engine/webrtc_video_engine.h b/media/engine/webrtc_video_engine.h index 464c78f43e..a3d5a2f42b 100644 --- a/media/engine/webrtc_video_engine.h +++ b/media/engine/webrtc_video_engine.h @@ -254,7 +254,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { const std::vector& codecs); // Wrapper for the sender part. - class WebRtcVideoSendStream { + class WebRtcVideoSendStream + : public rtc::VideoSourceInterface { public: WebRtcVideoSendStream( webrtc::Call* call, @@ -275,6 +276,14 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { void SetFrameEncryptor( rtc::scoped_refptr frame_encryptor); + // Implements rtc::VideoSourceInterface. + // WebRtcVideoSendStream acts as a source to the webrtc::VideoSendStream + // in |stream_|. This is done to proxy VideoSinkWants from the encoder to + // the worker thread. + void AddOrUpdateSink(rtc::VideoSinkInterface* sink, + const rtc::VideoSinkWants& wants) override; + void RemoveSink(rtc::VideoSinkInterface* sink) override; + bool SetVideoSend(const VideoOptions* options, rtc::VideoSourceInterface* source); @@ -332,7 +341,8 @@ class WebRtcVideoChannel : public VideoMediaChannel, public webrtc::Transport { RTC_GUARDED_BY(&thread_checker_); webrtc::VideoSendStream* stream_ RTC_GUARDED_BY(&thread_checker_); - + rtc::VideoSinkInterface* encoder_sink_ + RTC_GUARDED_BY(&thread_checker_); // Contains settings that are the same for all streams in the MediaChannel, // such as codecs, header extensions, and the global bitrate limit for the // entire channel.