diff --git a/talk/app/webrtc/objc/RTCMediaStreamTrack.mm b/talk/app/webrtc/objc/RTCMediaStreamTrack.mm index e0d5cae9da..616bd36ce1 100644 --- a/talk/app/webrtc/objc/RTCMediaStreamTrack.mm +++ b/talk/app/webrtc/objc/RTCMediaStreamTrack.mm @@ -92,11 +92,6 @@ class RTCMediaStreamTrackObserver : public ObserverInterface { return [RTCEnumConverter convertTrackStateToObjC:self.mediaTrack->state()]; } -- (BOOL)setState:(RTCTrackState)state { - return self.mediaTrack->set_state( - [RTCEnumConverter convertTrackStateToNative:state]); -} - @end @implementation RTCMediaStreamTrack (Internal) diff --git a/talk/app/webrtc/objc/public/RTCMediaStreamTrack.h b/talk/app/webrtc/objc/public/RTCMediaStreamTrack.h index 2b098645ff..052389f128 100644 --- a/talk/app/webrtc/objc/public/RTCMediaStreamTrack.h +++ b/talk/app/webrtc/objc/public/RTCMediaStreamTrack.h @@ -48,7 +48,6 @@ - (BOOL)isEnabled; - (BOOL)setEnabled:(BOOL)enabled; - (RTCTrackState)state; -- (BOOL)setState:(RTCTrackState)state; #ifndef DOXYGEN_SHOULD_SKIP_THIS // Disallow init and don't add to documentation diff --git a/webrtc/api/java/jni/peerconnection_jni.cc b/webrtc/api/java/jni/peerconnection_jni.cc index 1ff471b9bc..d2fe15a0e5 100644 --- a/webrtc/api/java/jni/peerconnection_jni.cc +++ b/webrtc/api/java/jni/peerconnection_jni.cc @@ -1956,14 +1956,6 @@ JOW(jobject, MediaStreamTrack_nativeState)(JNIEnv* jni, jclass, jlong j_p) { reinterpret_cast(j_p)->state()); } -JOW(jboolean, MediaStreamTrack_nativeSetState)( - JNIEnv* jni, jclass, jlong j_p, jint j_new_state) { - MediaStreamTrackInterface::TrackState new_state = - (MediaStreamTrackInterface::TrackState)j_new_state; - return reinterpret_cast(j_p) - ->set_state(new_state); -} - JOW(jboolean, MediaStreamTrack_nativeSetEnabled)( JNIEnv* jni, jclass, jlong j_p, jboolean enabled) { return reinterpret_cast(j_p) diff --git a/webrtc/api/java/src/org/webrtc/MediaStreamTrack.java b/webrtc/api/java/src/org/webrtc/MediaStreamTrack.java index a0063fbd51..49b2210cf9 100644 --- a/webrtc/api/java/src/org/webrtc/MediaStreamTrack.java +++ b/webrtc/api/java/src/org/webrtc/MediaStreamTrack.java @@ -41,10 +41,6 @@ public class MediaStreamTrack { return nativeState(nativeTrack); } - public boolean setState(State newState) { - return nativeSetState(nativeTrack, newState.ordinal()); - } - public void dispose() { free(nativeTrack); } @@ -60,8 +56,5 @@ public class MediaStreamTrack { private static native State nativeState(long nativeTrack); - private static native boolean nativeSetState( - long nativeTrack, int newState); - private static native void free(long nativeTrack); } diff --git a/webrtc/api/mediastream_unittest.cc b/webrtc/api/mediastream_unittest.cc index 7d9c60de65..dd63356e92 100644 --- a/webrtc/api/mediastream_unittest.cc +++ b/webrtc/api/mediastream_unittest.cc @@ -80,11 +80,6 @@ class MediaStreamTest: public testing::Test { .Times(Exactly(1)); track->set_enabled(false); EXPECT_FALSE(track->enabled()); - - EXPECT_CALL(observer, OnChanged()) - .Times(Exactly(1)); - track->set_state(MediaStreamTrackInterface::kEnded); - EXPECT_EQ(MediaStreamTrackInterface::kEnded, track->state()); } scoped_refptr stream_; diff --git a/webrtc/api/mediastreaminterface.h b/webrtc/api/mediastreaminterface.h index 47460b4421..3e79b94f9e 100644 --- a/webrtc/api/mediastreaminterface.h +++ b/webrtc/api/mediastreaminterface.h @@ -92,8 +92,6 @@ class MediaStreamTrackInterface : public rtc::RefCountInterface, virtual bool enabled() const = 0; virtual TrackState state() const = 0; virtual bool set_enabled(bool enable) = 0; - // These methods should be called by implementation only. - virtual bool set_state(TrackState new_state) = 0; protected: virtual ~MediaStreamTrackInterface() {} diff --git a/webrtc/api/mediastreamtrack.h b/webrtc/api/mediastreamtrack.h index e6f02e58fb..9ba042010f 100644 --- a/webrtc/api/mediastreamtrack.h +++ b/webrtc/api/mediastreamtrack.h @@ -25,12 +25,12 @@ class MediaStreamTrack : public Notifier { public: typedef typename T::TrackState TypedTrackState; - virtual std::string id() const { return id_; } - virtual MediaStreamTrackInterface::TrackState state() const { + std::string id() const override { return id_; } + MediaStreamTrackInterface::TrackState state() const override { return state_; } - virtual bool enabled() const { return enabled_; } - virtual bool set_enabled(bool enable) { + bool enabled() const override { return enabled_; } + bool set_enabled(bool enable) override { bool fire_on_change = (enable != enabled_); enabled_ = enable; if (fire_on_change) { @@ -38,7 +38,12 @@ class MediaStreamTrack : public Notifier { } return fire_on_change; } - virtual bool set_state(MediaStreamTrackInterface::TrackState new_state) { + + protected: + explicit MediaStreamTrack(const std::string& id) + : enabled_(true), id_(id), state_(MediaStreamTrackInterface::kLive) {} + + bool set_state(MediaStreamTrackInterface::TrackState new_state) { bool fire_on_change = (state_ != new_state); state_ = new_state; if (fire_on_change) @@ -46,10 +51,6 @@ class MediaStreamTrack : public Notifier { return true; } - protected: - explicit MediaStreamTrack(const std::string& id) - : enabled_(true), id_(id), state_(MediaStreamTrackInterface::kLive) {} - private: bool enabled_; std::string id_; diff --git a/webrtc/api/mediastreamtrackproxy.h b/webrtc/api/mediastreamtrackproxy.h index 7b059b17bf..f68773223b 100644 --- a/webrtc/api/mediastreamtrackproxy.h +++ b/webrtc/api/mediastreamtrackproxy.h @@ -30,10 +30,7 @@ BEGIN_PROXY_MAP(AudioTrack) PROXY_METHOD1(bool, GetSignalLevel, int*) PROXY_METHOD0(rtc::scoped_refptr, GetAudioProcessor) - PROXY_METHOD1(bool, set_enabled, bool) - PROXY_METHOD1(bool, set_state, TrackState) - PROXY_METHOD1(void, RegisterObserver, ObserverInterface*) PROXY_METHOD1(void, UnregisterObserver, ObserverInterface*) END_PROXY() @@ -44,8 +41,6 @@ BEGIN_PROXY_MAP(VideoTrack) PROXY_CONSTMETHOD0(TrackState, state) PROXY_CONSTMETHOD0(bool, enabled) PROXY_METHOD1(bool, set_enabled, bool) - PROXY_METHOD1(bool, set_state, TrackState) - PROXY_METHOD2(void, AddOrUpdateSink, rtc::VideoSinkInterface*, diff --git a/webrtc/api/peerconnection.cc b/webrtc/api/peerconnection.cc index 691a512b6a..b2b8062ca8 100644 --- a/webrtc/api/peerconnection.cc +++ b/webrtc/api/peerconnection.cc @@ -377,43 +377,6 @@ void AddSendStreams( namespace webrtc { -// Factory class for creating remote MediaStreams and MediaStreamTracks. -class RemoteMediaStreamFactory { - public: - explicit RemoteMediaStreamFactory(rtc::Thread* signaling_thread) - : signaling_thread_(signaling_thread) {} - - rtc::scoped_refptr CreateMediaStream( - const std::string& stream_label) { - return MediaStreamProxy::Create(signaling_thread_, - MediaStream::Create(stream_label)); - } - - AudioTrackInterface* AddAudioTrack(uint32_t ssrc, - AudioProviderInterface* provider, - webrtc::MediaStreamInterface* stream, - const std::string& track_id) { - return AddTrack( - stream, track_id, RemoteAudioSource::Create(ssrc, provider)); - } - - private: - template - TI* AddTrack(MediaStreamInterface* stream, - const std::string& track_id, - const S& source) { - rtc::scoped_refptr track( - TP::Create(signaling_thread_, T::Create(track_id, source))); - track->set_state(webrtc::MediaStreamTrackInterface::kLive); - if (stream->AddTrack(track)) { - return track; - } - return nullptr; - } - - rtc::Thread* signaling_thread_; -}; - bool ExtractMediaSessionOptions( const PeerConnectionInterface::RTCOfferAnswerOptions& rtc_options, bool is_offer, @@ -608,9 +571,6 @@ bool PeerConnection::Initialize( media_controller_.reset(factory_->CreateMediaController(media_config)); - remote_stream_factory_.reset( - new RemoteMediaStreamFactory(factory_->signaling_thread())); - session_.reset( new WebRtcSession(media_controller_.get(), factory_->signaling_thread(), factory_->worker_thread(), port_allocator_.get())); @@ -1320,29 +1280,28 @@ void PeerConnection::OnMessage(rtc::Message* msg) { } void PeerConnection::CreateAudioReceiver(MediaStreamInterface* stream, - AudioTrackInterface* audio_track, + const std::string& track_id, uint32_t ssrc) { receivers_.push_back(RtpReceiverProxy::Create( signaling_thread(), - new AudioRtpReceiver(audio_track, ssrc, session_.get()))); + new AudioRtpReceiver(stream, track_id, ssrc, session_.get()))); } void PeerConnection::CreateVideoReceiver(MediaStreamInterface* stream, const std::string& track_id, uint32_t ssrc) { - VideoRtpReceiver* video_receiver = new VideoRtpReceiver( - stream, track_id, factory_->worker_thread(), ssrc, session_.get()); - receivers_.push_back( - RtpReceiverProxy::Create(signaling_thread(), video_receiver)); + receivers_.push_back(RtpReceiverProxy::Create( + signaling_thread(), + new VideoRtpReceiver(stream, track_id, factory_->worker_thread(), ssrc, + session_.get()))); } // TODO(deadbeef): Keep RtpReceivers around even if track goes away in remote // description. -void PeerConnection::DestroyAudioReceiver(MediaStreamInterface* stream, - AudioTrackInterface* audio_track) { - auto it = FindReceiverForTrack(audio_track); +void PeerConnection::DestroyReceiver(const std::string& track_id) { + auto it = FindReceiverForTrack(track_id); if (it == receivers_.end()) { - LOG(LS_WARNING) << "RtpReceiver for track with id " << audio_track->id() + LOG(LS_WARNING) << "RtpReceiver for track with id " << track_id << " doesn't exist."; } else { (*it)->Stop(); @@ -1350,15 +1309,16 @@ void PeerConnection::DestroyAudioReceiver(MediaStreamInterface* stream, } } -void PeerConnection::DestroyVideoReceiver(MediaStreamInterface* stream, - VideoTrackInterface* video_track) { - auto it = FindReceiverForTrack(video_track); - if (it == receivers_.end()) { - LOG(LS_WARNING) << "RtpReceiver for track with id " << video_track->id() - << " doesn't exist."; - } else { - (*it)->Stop(); - receivers_.erase(it); +void PeerConnection::StopReceivers(cricket::MediaType media_type) { + TrackInfos* current_tracks = GetRemoteTracks(media_type); + for (const auto& track_info : *current_tracks) { + auto it = FindReceiverForTrack(track_info.track_id); + if (it == receivers_.end()) { + LOG(LS_WARNING) << "RtpReceiver for track with id " << track_info.track_id + << " doesn't exist."; + } else { + (*it)->Stop(); + } } } @@ -1639,7 +1599,8 @@ void PeerConnection::UpdateRemoteStreamsList( remote_streams_->find(stream_label); if (!stream) { // This is a new MediaStream. Create a new remote MediaStream. - stream = remote_stream_factory_->CreateMediaStream(stream_label); + stream = MediaStreamProxy::Create(rtc::Thread::Current(), + MediaStream::Create(stream_label)); remote_streams_->AddStream(stream); new_streams->AddStream(stream); } @@ -1658,8 +1619,8 @@ void PeerConnection::UpdateRemoteStreamsList( remote_streams_->find(kDefaultStreamLabel); if (!default_stream) { // Create the new default MediaStream. - default_stream = - remote_stream_factory_->CreateMediaStream(kDefaultStreamLabel); + default_stream = MediaStreamProxy::Create( + rtc::Thread::Current(), MediaStream::Create(kDefaultStreamLabel)); remote_streams_->AddStream(default_stream); new_streams->AddStream(default_stream); } @@ -1683,9 +1644,7 @@ void PeerConnection::OnRemoteTrackSeen(const std::string& stream_label, MediaStreamInterface* stream = remote_streams_->find(stream_label); if (media_type == cricket::MEDIA_TYPE_AUDIO) { - AudioTrackInterface* audio_track = remote_stream_factory_->AddAudioTrack( - ssrc, session_.get(), stream, track_id); - CreateAudioReceiver(stream, audio_track, ssrc); + CreateAudioReceiver(stream, track_id, ssrc); } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { CreateVideoReceiver(stream, track_id, ssrc); } else { @@ -1699,21 +1658,24 @@ void PeerConnection::OnRemoteTrackRemoved(const std::string& stream_label, MediaStreamInterface* stream = remote_streams_->find(stream_label); if (media_type == cricket::MEDIA_TYPE_AUDIO) { + // When the MediaEngine audio channel is destroyed, the RemoteAudioSource + // will be notified which will end the AudioRtpReceiver::track(). + DestroyReceiver(track_id); rtc::scoped_refptr audio_track = stream->FindAudioTrack(track_id); if (audio_track) { - audio_track->set_state(webrtc::MediaStreamTrackInterface::kEnded); stream->RemoveTrack(audio_track); - DestroyAudioReceiver(stream, audio_track); } } else if (media_type == cricket::MEDIA_TYPE_VIDEO) { + // Stopping or destroying a VideoRtpReceiver will end the + // VideoRtpReceiver::track(). + DestroyReceiver(track_id); rtc::scoped_refptr video_track = stream->FindVideoTrack(track_id); if (video_track) { + // There's no guarantee the track is still available, e.g. the track may + // have been removed from the stream by an application. stream->RemoveTrack(video_track); - // Stopping or destroying a VideoRtpReceiver will end the - // VideoRtpReceiver::track(). - DestroyVideoReceiver(stream, video_track); } } else { ASSERT(false && "Invalid media type"); @@ -1735,31 +1697,6 @@ void PeerConnection::UpdateEndedRemoteMediaStreams() { } } -void PeerConnection::EndRemoteTracks(cricket::MediaType media_type) { - TrackInfos* current_tracks = GetRemoteTracks(media_type); - for (TrackInfos::iterator track_it = current_tracks->begin(); - track_it != current_tracks->end(); ++track_it) { - const TrackInfo& info = *track_it; - MediaStreamInterface* stream = remote_streams_->find(info.stream_label); - if (media_type == cricket::MEDIA_TYPE_AUDIO) { - AudioTrackInterface* track = stream->FindAudioTrack(info.track_id); - // There's no guarantee the track is still available, e.g. the track may - // have been removed from the stream by javascript. - if (track) { - track->set_state(webrtc::MediaStreamTrackInterface::kEnded); - } - } - if (media_type == cricket::MEDIA_TYPE_VIDEO) { - VideoTrackInterface* track = stream->FindVideoTrack(info.track_id); - // There's no guarantee the track is still available, e.g. the track may - // have been removed from the stream by javascript. - if (track) { - track->set_state(webrtc::MediaStreamTrackInterface::kEnded); - } - } - } -} - void PeerConnection::UpdateLocalTracks( const std::vector& streams, cricket::MediaType media_type) { @@ -2019,11 +1956,11 @@ void PeerConnection::OnSctpDataChannelClosed(DataChannel* channel) { } void PeerConnection::OnVoiceChannelDestroyed() { - EndRemoteTracks(cricket::MEDIA_TYPE_AUDIO); + StopReceivers(cricket::MEDIA_TYPE_AUDIO); } void PeerConnection::OnVideoChannelDestroyed() { - EndRemoteTracks(cricket::MEDIA_TYPE_VIDEO); + StopReceivers(cricket::MEDIA_TYPE_VIDEO); } void PeerConnection::OnDataChannelCreated() { @@ -2081,11 +2018,11 @@ PeerConnection::FindSenderForTrack(MediaStreamTrackInterface* track) { } std::vector>::iterator -PeerConnection::FindReceiverForTrack(MediaStreamTrackInterface* track) { +PeerConnection::FindReceiverForTrack(const std::string& track_id) { return std::find_if( receivers_.begin(), receivers_.end(), - [track](const rtc::scoped_refptr& receiver) { - return receiver->track() == track; + [track_id](const rtc::scoped_refptr& receiver) { + return receiver->id() == track_id; }); } diff --git a/webrtc/api/peerconnection.h b/webrtc/api/peerconnection.h index d715ecdf73..d1676733d5 100644 --- a/webrtc/api/peerconnection.h +++ b/webrtc/api/peerconnection.h @@ -12,6 +12,8 @@ #define WEBRTC_API_PEERCONNECTION_H_ #include +#include +#include #include "webrtc/api/dtlsidentitystore.h" #include "webrtc/api/peerconnectionfactory.h" @@ -26,7 +28,6 @@ namespace webrtc { class MediaStreamObserver; -class RemoteMediaStreamFactory; class VideoRtpReceiver; // Populates |session_options| from |rtc_options|, and returns true if options @@ -143,7 +144,7 @@ class PeerConnection : public PeerConnectionInterface, virtual const std::vector>& sctp_data_channels() const { return sctp_data_channels_; - }; + } protected: ~PeerConnection() override; @@ -169,16 +170,14 @@ class PeerConnection : public PeerConnectionInterface, void OnMessage(rtc::Message* msg) override; void CreateAudioReceiver(MediaStreamInterface* stream, - AudioTrackInterface* audio_track, + const std::string& track_id, uint32_t ssrc); void CreateVideoReceiver(MediaStreamInterface* stream, const std::string& track_id, uint32_t ssrc); - void DestroyAudioReceiver(MediaStreamInterface* stream, - AudioTrackInterface* audio_track); - void DestroyVideoReceiver(MediaStreamInterface* stream, - VideoTrackInterface* video_track); + void StopReceivers(cricket::MediaType media_type); + void DestroyReceiver(const std::string& track_id); void DestroyAudioSender(MediaStreamInterface* stream, AudioTrackInterface* audio_track, uint32_t ssrc); @@ -278,10 +277,6 @@ class PeerConnection : public PeerConnectionInterface, // exist. void UpdateEndedRemoteMediaStreams(); - // Set the MediaStreamTrackInterface::TrackState to |kEnded| on all remote - // tracks of type |media_type|. - void EndRemoteTracks(cricket::MediaType media_type); - // Loops through the vector of |streams| and finds added and removed // StreamParams since last time this method was called. // For each new or removed StreamParam, OnLocalTrackSeen or @@ -344,7 +339,7 @@ class PeerConnection : public PeerConnectionInterface, std::vector>::iterator FindSenderForTrack(MediaStreamTrackInterface* track); std::vector>::iterator - FindReceiverForTrack(MediaStreamTrackInterface* track); + FindReceiverForTrack(const std::string& track_id); TrackInfos* GetRemoteTracks(cricket::MediaType media_type); TrackInfos* GetLocalTracks(cricket::MediaType media_type); @@ -394,7 +389,6 @@ class PeerConnection : public PeerConnectionInterface, std::vector> sctp_data_channels_to_free_; bool remote_peer_supports_msid_ = false; - rtc::scoped_ptr remote_stream_factory_; std::vector> senders_; std::vector> receivers_; diff --git a/webrtc/api/peerconnectioninterface_unittest.cc b/webrtc/api/peerconnectioninterface_unittest.cc index 4d5eb966f5..76f9c5defa 100644 --- a/webrtc/api/peerconnectioninterface_unittest.cc +++ b/webrtc/api/peerconnectioninterface_unittest.cc @@ -11,6 +11,7 @@ #include #include +#include "testing/gmock/include/gmock/gmock.h" #include "webrtc/api/audiotrack.h" #include "webrtc/api/jsepsessiondescription.h" #include "webrtc/api/mediastream.h" @@ -240,6 +241,7 @@ static const char kSdpStringMs1Video1[] = using rtc::scoped_ptr; using rtc::scoped_refptr; +using ::testing::Exactly; using webrtc::AudioSourceInterface; using webrtc::AudioTrack; using webrtc::AudioTrackInterface; @@ -255,6 +257,8 @@ using webrtc::MockCreateSessionDescriptionObserver; using webrtc::MockDataChannelObserver; using webrtc::MockSetSessionDescriptionObserver; using webrtc::MockStatsObserver; +using webrtc::NotifierInterface; +using webrtc::ObserverInterface; using webrtc::PeerConnectionInterface; using webrtc::PeerConnectionObserver; using webrtc::RtpReceiverInterface; @@ -387,6 +391,29 @@ bool CompareStreamCollections(StreamCollectionInterface* s1, return true; } +// Helper class to test Observer. +class MockTrackObserver : public ObserverInterface { + public: + explicit MockTrackObserver(NotifierInterface* notifier) + : notifier_(notifier) { + notifier_->RegisterObserver(this); + } + + ~MockTrackObserver() { Unregister(); } + + void Unregister() { + if (notifier_) { + notifier_->UnregisterObserver(this); + notifier_ = nullptr; + } + } + + MOCK_METHOD0(OnChanged, void()); + + private: + NotifierInterface* notifier_; +}; + class MockPeerConnectionObserver : public PeerConnectionObserver { public: MockPeerConnectionObserver() : remote_streams_(StreamCollection::Create()) {} @@ -1843,8 +1870,9 @@ TEST_F(PeerConnectionInterfaceTest, CloseAndTestStreamsAndStates) { pc_->remote_streams()->at(0); EXPECT_EQ(MediaStreamTrackInterface::kEnded, remote_stream->GetVideoTracks()[0]->state()); - EXPECT_EQ(MediaStreamTrackInterface::kEnded, - remote_stream->GetAudioTracks()[0]->state()); + // Audio source state changes are posted. + EXPECT_EQ_WAIT(MediaStreamTrackInterface::kEnded, + remote_stream->GetAudioTracks()[0]->state(), 1); } // Test that PeerConnection methods fails gracefully after @@ -1949,13 +1977,28 @@ TEST_F(PeerConnectionInterfaceTest, EXPECT_TRUE(DoSetRemoteDescription(desc_ms1_two_tracks.release())); EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), reference_collection_)); + scoped_refptr audio_track2 = + observer_.remote_streams()->at(0)->GetAudioTracks()[1]; + EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, audio_track2->state()); + scoped_refptr video_track2 = + observer_.remote_streams()->at(0)->GetVideoTracks()[1]; + EXPECT_EQ(webrtc::MediaStreamTrackInterface::kLive, video_track2->state()); // Remove the extra audio and video tracks. rtc::scoped_ptr desc_ms2 = CreateSessionDescriptionAndReference(1, 1); + MockTrackObserver audio_track_observer(audio_track2); + MockTrackObserver video_track_observer(video_track2); + + EXPECT_CALL(audio_track_observer, OnChanged()).Times(Exactly(1)); + EXPECT_CALL(video_track_observer, OnChanged()).Times(Exactly(1)); EXPECT_TRUE(DoSetRemoteDescription(desc_ms2.release())); EXPECT_TRUE(CompareStreamCollections(observer_.remote_streams(), reference_collection_)); + // Audio source state changes are posted. + EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded, + audio_track2->state(), 1); + EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, video_track2->state()); } // This tests that remote tracks are ended if a local session description is set @@ -2001,7 +2044,9 @@ TEST_F(PeerConnectionInterfaceTest, RejectMediaContent) { audio_info->rejected = true; EXPECT_TRUE(DoSetLocalDescription(local_offer.release())); EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_video->state()); - EXPECT_EQ(webrtc::MediaStreamTrackInterface::kEnded, remote_audio->state()); + // Audio source state changes are posted. + EXPECT_EQ_WAIT(webrtc::MediaStreamTrackInterface::kEnded, + remote_audio->state(), 1); } // This tests that we won't crash if the remote track has been removed outside diff --git a/webrtc/api/rtpreceiver.cc b/webrtc/api/rtpreceiver.cc index f8b505781a..0150dfd546 100644 --- a/webrtc/api/rtpreceiver.cc +++ b/webrtc/api/rtpreceiver.cc @@ -11,22 +11,28 @@ #include "webrtc/api/rtpreceiver.h" #include "webrtc/api/mediastreamtrackproxy.h" +#include "webrtc/api/audiotrack.h" #include "webrtc/api/videotrack.h" namespace webrtc { -AudioRtpReceiver::AudioRtpReceiver(AudioTrackInterface* track, +AudioRtpReceiver::AudioRtpReceiver(MediaStreamInterface* stream, + const std::string& track_id, uint32_t ssrc, AudioProviderInterface* provider) - : id_(track->id()), - track_(track), + : id_(track_id), ssrc_(ssrc), provider_(provider), - cached_track_enabled_(track->enabled()) { + track_(AudioTrackProxy::Create( + rtc::Thread::Current(), + AudioTrack::Create(track_id, + RemoteAudioSource::Create(ssrc, provider)))), + cached_track_enabled_(track_->enabled()) { RTC_DCHECK(track_->GetSource()->remote()); track_->RegisterObserver(this); track_->GetSource()->RegisterAudioObserver(this); Reconfigure(); + stream->AddTrack(track_); } AudioRtpReceiver::~AudioRtpReceiver() { diff --git a/webrtc/api/rtpreceiver.h b/webrtc/api/rtpreceiver.h index a62ed19dbf..b5818573da 100644 --- a/webrtc/api/rtpreceiver.h +++ b/webrtc/api/rtpreceiver.h @@ -19,6 +19,7 @@ #include "webrtc/api/mediastreamprovider.h" #include "webrtc/api/rtpreceiverinterface.h" +#include "webrtc/api/remoteaudiosource.h" #include "webrtc/api/videotracksource.h" #include "webrtc/base/basictypes.h" #include "webrtc/media/base/videobroadcaster.h" @@ -29,7 +30,8 @@ class AudioRtpReceiver : public ObserverInterface, public AudioSourceInterface::AudioObserver, public rtc::RefCountedObject { public: - AudioRtpReceiver(AudioTrackInterface* track, + AudioRtpReceiver(MediaStreamInterface* stream, + const std::string& track_id, uint32_t ssrc, AudioProviderInterface* provider); @@ -41,6 +43,10 @@ class AudioRtpReceiver : public ObserverInterface, // AudioSourceInterface::AudioObserver implementation void OnSetVolume(double volume) override; + rtc::scoped_refptr audio_track() const { + return track_.get(); + } + // RtpReceiverInterface implementation rtc::scoped_refptr track() const override { return track_.get(); @@ -54,9 +60,9 @@ class AudioRtpReceiver : public ObserverInterface, void Reconfigure(); const std::string id_; - const rtc::scoped_refptr track_; const uint32_t ssrc_; AudioProviderInterface* provider_; // Set to null in Stop(). + const rtc::scoped_refptr track_; bool cached_track_enabled_; }; diff --git a/webrtc/api/rtpsenderreceiver_unittest.cc b/webrtc/api/rtpsenderreceiver_unittest.cc index fd1c1f33b1..7f32f29bc4 100644 --- a/webrtc/api/rtpsenderreceiver_unittest.cc +++ b/webrtc/api/rtpsenderreceiver_unittest.cc @@ -137,8 +137,9 @@ class RtpSenderReceiverTest : public testing::Test { kAudioTrackId, RemoteAudioSource::Create(kAudioSsrc, NULL)); EXPECT_TRUE(stream_->AddTrack(audio_track_)); EXPECT_CALL(audio_provider_, SetAudioPlayout(kAudioSsrc, true)); - audio_rtp_receiver_ = new AudioRtpReceiver(stream_->GetAudioTracks()[0], + audio_rtp_receiver_ = new AudioRtpReceiver(stream_, kAudioTrackId, kAudioSsrc, &audio_provider_); + audio_track_ = audio_rtp_receiver_->audio_track(); } void CreateVideoRtpReceiver() {