diff --git a/webrtc/api/mediastreaminterface.h b/webrtc/api/mediastreaminterface.h index cc660e1be2..aaf5b62aa4 100644 --- a/webrtc/api/mediastreaminterface.h +++ b/webrtc/api/mediastreaminterface.h @@ -111,6 +111,11 @@ class MediaStreamTrackInterface : public rtc::RefCountInterface, // VideoTrackSourceInterface is a reference counted source used for // VideoTracks. The same source can be used by multiple VideoTracks. +// VideoTrackSourceInterface is designed to be invoked on the signaling thread +// except for rtc::VideoSourceInterface methods that will be invoked +// on the worker thread via a VideoTrack. A custom implementation of a source +// can inherit AdaptedVideoTrackSource instead of directly implementing this +// interface. class VideoTrackSourceInterface : public MediaSourceInterface, public rtc::VideoSourceInterface { @@ -145,6 +150,12 @@ class VideoTrackSourceInterface virtual ~VideoTrackSourceInterface() {} }; +// VideoTrackInterface is designed to be invoked on the signaling thread except +// for rtc::VideoSourceInterface methods that must be invoked +// on the worker thread. +// PeerConnectionFactory::CreateVideoTrack can be used for creating a VideoTrack +// that ensures thread safety and that all methods are called on the right +// thread. class VideoTrackInterface : public MediaStreamTrackInterface, public rtc::VideoSourceInterface { diff --git a/webrtc/ortc/ortcfactory.cc b/webrtc/ortc/ortcfactory.cc index 1d968738cd..be1c4c7a76 100644 --- a/webrtc/ortc/ortcfactory.cc +++ b/webrtc/ortc/ortcfactory.cc @@ -479,7 +479,8 @@ rtc::scoped_refptr OrtcFactory::CreateVideoTrack( const std::string& id, VideoTrackSourceInterface* source) { RTC_DCHECK_RUN_ON(signaling_thread_); - rtc::scoped_refptr track(VideoTrack::Create(id, source)); + rtc::scoped_refptr track( + VideoTrack::Create(id, source, worker_thread_.get())); return VideoTrackProxy::Create(signaling_thread_, worker_thread_.get(), track); } diff --git a/webrtc/pc/mediastream_unittest.cc b/webrtc/pc/mediastream_unittest.cc index 01a547bbc5..1a96a56f97 100644 --- a/webrtc/pc/mediastream_unittest.cc +++ b/webrtc/pc/mediastream_unittest.cc @@ -56,8 +56,8 @@ class MediaStreamTest: public testing::Test { stream_ = MediaStream::Create(kStreamLabel1); ASSERT_TRUE(stream_.get() != NULL); - video_track_ = - VideoTrack::Create(kVideoTrackId, FakeVideoTrackSource::Create()); + video_track_ = VideoTrack::Create( + kVideoTrackId, FakeVideoTrackSource::Create(), rtc::Thread::Current()); ASSERT_TRUE(video_track_.get() != NULL); EXPECT_EQ(MediaStreamTrackInterface::kLive, video_track_->state()); diff --git a/webrtc/pc/peerconnectionfactory.cc b/webrtc/pc/peerconnectionfactory.cc index 15e36f094a..be083c26b7 100644 --- a/webrtc/pc/peerconnectionfactory.cc +++ b/webrtc/pc/peerconnectionfactory.cc @@ -292,7 +292,7 @@ rtc::scoped_refptr PeerConnectionFactory::CreateVideoTrack( VideoTrackSourceInterface* source) { RTC_DCHECK(signaling_thread_->IsCurrent()); rtc::scoped_refptr track( - VideoTrack::Create(id, source)); + VideoTrack::Create(id, source, worker_thread_)); return VideoTrackProxy::Create(signaling_thread_, worker_thread_, track); } diff --git a/webrtc/pc/peerconnectioninterface_unittest.cc b/webrtc/pc/peerconnectioninterface_unittest.cc index 114ffd75e2..0e52c200d4 100644 --- a/webrtc/pc/peerconnectioninterface_unittest.cc +++ b/webrtc/pc/peerconnectioninterface_unittest.cc @@ -460,7 +460,8 @@ rtc::scoped_refptr CreateStreamCollection( // Add a local video track. rtc::scoped_refptr video_track( webrtc::VideoTrack::Create(kVideoTracks[i * tracks_per_stream + j], - webrtc::FakeVideoTrackSource::Create())); + webrtc::FakeVideoTrackSource::Create(), + rtc::Thread::Current())); stream->AddTrack(video_track); } @@ -1150,7 +1151,8 @@ class PeerConnectionInterfaceTest : public testing::Test { MediaStreamInterface* stream) { rtc::scoped_refptr video_track( webrtc::VideoTrack::Create(track_id, - webrtc::FakeVideoTrackSource::Create())); + webrtc::FakeVideoTrackSource::Create(), + rtc::Thread::Current())); ASSERT_TRUE(stream->AddTrack(video_track)); } diff --git a/webrtc/pc/rtcstatscollector_unittest.cc b/webrtc/pc/rtcstatscollector_unittest.cc index 8dc4a9702c..f6591c0d66 100644 --- a/webrtc/pc/rtcstatscollector_unittest.cc +++ b/webrtc/pc/rtcstatscollector_unittest.cc @@ -218,6 +218,11 @@ class FakeVideoTrackForStats std::string kind() const override { return MediaStreamTrackInterface::kVideoKind; } + + void AddOrUpdateSink(rtc::VideoSinkInterface* sink, + const rtc::VideoSinkWants& wants) override{}; + void RemoveSink(rtc::VideoSinkInterface* sink) override{}; + VideoTrackSourceInterface* GetSource() const override { return nullptr; } }; diff --git a/webrtc/pc/rtpreceiver.cc b/webrtc/pc/rtpreceiver.cc index f3eef5a9a9..c6a2128dfb 100644 --- a/webrtc/pc/rtpreceiver.cc +++ b/webrtc/pc/rtpreceiver.cc @@ -155,7 +155,8 @@ VideoRtpReceiver::VideoRtpReceiver(const std::string& track_id, track_id, VideoTrackSourceProxy::Create(rtc::Thread::Current(), worker_thread, - source_)))) { + source_), + worker_thread))) { source_->SetState(MediaSourceInterface::kLive); if (!channel_) { LOG(LS_ERROR) diff --git a/webrtc/pc/rtpsenderreceiver_unittest.cc b/webrtc/pc/rtpsenderreceiver_unittest.cc index bf413e411d..9779eb6f56 100644 --- a/webrtc/pc/rtpsenderreceiver_unittest.cc +++ b/webrtc/pc/rtpsenderreceiver_unittest.cc @@ -124,7 +124,8 @@ class RtpSenderReceiverTest : public testing::Test, void AddVideoTrack(bool is_screencast) { rtc::scoped_refptr source( FakeVideoTrackSource::Create(is_screencast)); - video_track_ = VideoTrack::Create(kVideoTrackId, source); + video_track_ = + VideoTrack::Create(kVideoTrackId, source, rtc::Thread::Current()); EXPECT_TRUE(local_stream_->AddTrack(video_track_)); } diff --git a/webrtc/pc/statscollector_unittest.cc b/webrtc/pc/statscollector_unittest.cc index 9b62b81d33..0fad6adead 100644 --- a/webrtc/pc/statscollector_unittest.cc +++ b/webrtc/pc/statscollector_unittest.cc @@ -545,7 +545,8 @@ class StatsCollectorTest : public testing::Test { void AddOutgoingVideoTrackStats() { stream_ = webrtc::MediaStream::Create("streamlabel"); track_ = webrtc::VideoTrack::Create(kLocalTrackId, - webrtc::FakeVideoTrackSource::Create()); + webrtc::FakeVideoTrackSource::Create(), + rtc::Thread::Current()); stream_->AddTrack(track_); EXPECT_CALL(session_, GetLocalTrackIdBySsrc(kSsrcOfTrack, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(kLocalTrackId), Return(true))); @@ -555,7 +556,8 @@ class StatsCollectorTest : public testing::Test { void AddIncomingVideoTrackStats() { stream_ = webrtc::MediaStream::Create("streamlabel"); track_ = webrtc::VideoTrack::Create(kRemoteTrackId, - webrtc::FakeVideoTrackSource::Create()); + webrtc::FakeVideoTrackSource::Create(), + rtc::Thread::Current()); stream_->AddTrack(track_); EXPECT_CALL(session_, GetRemoteTrackIdBySsrc(kSsrcOfTrack, _)) .WillRepeatedly(DoAll(SetArgPointee<1>(kRemoteTrackId), Return(true))); diff --git a/webrtc/pc/trackmediainfomap_unittest.cc b/webrtc/pc/trackmediainfomap_unittest.cc index b380cc4184..f0a3f1ad73 100644 --- a/webrtc/pc/trackmediainfomap_unittest.cc +++ b/webrtc/pc/trackmediainfomap_unittest.cc @@ -85,10 +85,12 @@ class TrackMediaInfoMapTest : public testing::Test { remote_audio_track_(AudioTrack::Create("RemoteAudioTrack", nullptr)), local_video_track_( VideoTrack::Create("LocalVideoTrack", - FakeVideoTrackSource::Create(false))), + FakeVideoTrackSource::Create(false), + rtc::Thread::Current())), remote_video_track_( VideoTrack::Create("RemoteVideoTrack", - FakeVideoTrackSource::Create(false))) {} + FakeVideoTrackSource::Create(false), + rtc::Thread::Current())) {} ~TrackMediaInfoMapTest() { // If we have a map the ownership has been passed to the map, only delete if diff --git a/webrtc/pc/videotrack.cc b/webrtc/pc/videotrack.cc index 494d728b1e..f106460164 100644 --- a/webrtc/pc/videotrack.cc +++ b/webrtc/pc/videotrack.cc @@ -15,11 +15,12 @@ namespace webrtc { VideoTrack::VideoTrack(const std::string& label, - VideoTrackSourceInterface* video_source) + VideoTrackSourceInterface* video_source, + rtc::Thread* worker_thread) : MediaStreamTrack(label), + worker_thread_(worker_thread), video_source_(video_source), content_hint_(ContentHint::kNone) { - worker_thread_checker_.DetachFromThread(); video_source_->RegisterObserver(this); } @@ -35,7 +36,7 @@ std::string VideoTrack::kind() const { // thread. void VideoTrack::AddOrUpdateSink(rtc::VideoSinkInterface* sink, const rtc::VideoSinkWants& wants) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + RTC_DCHECK(worker_thread_->IsCurrent()); VideoSourceBase::AddOrUpdateSink(sink, wants); rtc::VideoSinkWants modified_wants = wants; modified_wants.black_frames = !enabled(); @@ -43,7 +44,7 @@ void VideoTrack::AddOrUpdateSink(rtc::VideoSinkInterface* sink, } void VideoTrack::RemoveSink(rtc::VideoSinkInterface* sink) { - RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + RTC_DCHECK(worker_thread_->IsCurrent()); VideoSourceBase::RemoveSink(sink); video_source_->RemoveSink(sink); } @@ -63,13 +64,14 @@ void VideoTrack::set_content_hint(ContentHint hint) { bool VideoTrack::set_enabled(bool enable) { RTC_DCHECK(signaling_thread_checker_.CalledOnValidThread()); - for (auto& sink_pair : sink_pairs()) { - rtc::VideoSinkWants modified_wants = sink_pair.wants; - modified_wants.black_frames = !enable; - // video_source_ is a proxy object, marshalling the call to the - // worker thread. - video_source_->AddOrUpdateSink(sink_pair.sink, modified_wants); - } + worker_thread_->Invoke(RTC_FROM_HERE, [enable, this] { + RTC_DCHECK(worker_thread_->IsCurrent()); + for (auto& sink_pair : sink_pairs()) { + rtc::VideoSinkWants modified_wants = sink_pair.wants; + modified_wants.black_frames = !enable; + video_source_->AddOrUpdateSink(sink_pair.sink, modified_wants); + } + }); return MediaStreamTrack::set_enabled(enable); } @@ -84,9 +86,10 @@ void VideoTrack::OnChanged() { rtc::scoped_refptr VideoTrack::Create( const std::string& id, - VideoTrackSourceInterface* source) { + VideoTrackSourceInterface* source, + rtc::Thread* worker_thread) { rtc::RefCountedObject* track = - new rtc::RefCountedObject(id, source); + new rtc::RefCountedObject(id, source, worker_thread); return track; } diff --git a/webrtc/pc/videotrack.h b/webrtc/pc/videotrack.h index f251797155..6e20e978b9 100644 --- a/webrtc/pc/videotrack.h +++ b/webrtc/pc/videotrack.h @@ -27,7 +27,8 @@ class VideoTrack : public MediaStreamTrack, public: static rtc::scoped_refptr Create( const std::string& label, - VideoTrackSourceInterface* source); + VideoTrackSourceInterface* source, + rtc::Thread* worker_thread); void AddOrUpdateSink(rtc::VideoSinkInterface* sink, const rtc::VideoSinkWants& wants) override; @@ -42,15 +43,17 @@ class VideoTrack : public MediaStreamTrack, std::string kind() const override; protected: - VideoTrack(const std::string& id, VideoTrackSourceInterface* video_source); + VideoTrack(const std::string& id, + VideoTrackSourceInterface* video_source, + rtc::Thread* worker_thread); ~VideoTrack(); private: // Implements ObserverInterface. Observes |video_source_| state. void OnChanged() override; + rtc::Thread* const worker_thread_; rtc::ThreadChecker signaling_thread_checker_; - rtc::ThreadChecker worker_thread_checker_; rtc::scoped_refptr video_source_; ContentHint content_hint_ GUARDED_BY(signaling_thread_checker_); }; diff --git a/webrtc/pc/videotrack_unittest.cc b/webrtc/pc/videotrack_unittest.cc index d033efe632..1f569ebd59 100644 --- a/webrtc/pc/videotrack_unittest.cc +++ b/webrtc/pc/videotrack_unittest.cc @@ -31,7 +31,8 @@ class VideoTrackTest : public testing::Test { static const char kVideoTrackId[] = "track_id"; video_track_source_ = new rtc::RefCountedObject( &capturer_, true /* remote */); - video_track_ = VideoTrack::Create(kVideoTrackId, video_track_source_); + video_track_ = VideoTrack::Create(kVideoTrackId, video_track_source_, + rtc::Thread::Current()); capturer_.Start( cricket::VideoFormat(640, 480, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_I420));