Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7888)

Unified Diff: content/renderer/media/remote_media_stream_impl.cc

Issue 2902733003: RemoteMediaStreamImpl using WebRtcMediaStreamTrackMap. (Closed)
Patch Set: "Must be invoked on the main thread." Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/renderer/media/remote_media_stream_impl.cc
diff --git a/content/renderer/media/remote_media_stream_impl.cc b/content/renderer/media/remote_media_stream_impl.cc
index 14966e488d5ce48b51f4eb34d36db858aecc9b9a..3404923bde52d73dd74d2531de88d5941cd9a300 100644
--- a/content/renderer/media/remote_media_stream_impl.cc
+++ b/content/renderer/media/remote_media_stream_impl.cc
@@ -23,179 +23,190 @@
#include "third_party/WebKit/public/platform/WebString.h"
namespace content {
-namespace {
-template <typename WebRtcTrackVector, typename AdapterType>
-void CreateAdaptersForTracks(
- const WebRtcTrackVector& tracks,
- std::vector<scoped_refptr<AdapterType>>* observers,
- const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) {
- for (auto& track : tracks)
- observers->push_back(new AdapterType(main_thread, track));
-}
+namespace {
-template<typename VectorType>
-bool IsTrackInVector(const VectorType& v, const std::string& id) {
- for (const auto& t : v) {
- if (t->id() == id)
- return true;
+// Gets the adapters for the tracks that are members of the webrtc stream.
+// Invoke on webrtc signaling thread. New adapters are initialized in a post
+// to the main thread after which their |web_track| becomes available.
+RemoteMediaStreamImpl::AdapterRefMap GetAdapterRefMapFromWebRtcStream(
+ const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
+ webrtc::MediaStreamInterface* webrtc_stream) {
+ RemoteMediaStreamImpl::AdapterRefMap adapter_refs;
+ for (auto& webrtc_audio_track : webrtc_stream->GetAudioTracks()) {
+ adapter_refs.insert(
+ std::make_pair(webrtc_audio_track->id(),
+ track_adapter_map->GetOrCreateRemoteTrackAdapter(
+ webrtc_audio_track.get())));
}
- return false;
+ for (auto& webrtc_video_track : webrtc_stream->GetVideoTracks()) {
+ adapter_refs.insert(
+ std::make_pair(webrtc_video_track->id(),
+ track_adapter_map->GetOrCreateRemoteTrackAdapter(
+ webrtc_video_track.get())));
+ }
+ return adapter_refs;
}
+
} // namespace
-RemoteMediaStreamImpl::Observer::Observer(
- const base::WeakPtr<RemoteMediaStreamImpl>& media_stream,
- const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
- webrtc::MediaStreamInterface* webrtc_stream)
- : media_stream_(media_stream),
- main_thread_(main_thread),
- webrtc_stream_(webrtc_stream) {
- webrtc_stream_->RegisterObserver(this);
-}
+class RemoteMediaStreamImpl::Observer
+ : NON_EXPORTED_BASE(public webrtc::ObserverInterface),
+ public base::RefCountedThreadSafe<Observer> {
+ public:
+ Observer(
+ const base::WeakPtr<RemoteMediaStreamImpl>& media_stream,
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
+ const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
+ webrtc::MediaStreamInterface* webrtc_stream)
+ : media_stream_(media_stream),
+ main_thread_(main_thread),
+ track_adapter_map_(track_adapter_map),
+ webrtc_stream_(webrtc_stream) {
+ webrtc_stream_->RegisterObserver(this);
+ }
-RemoteMediaStreamImpl::Observer::~Observer() {
- DCHECK(!webrtc_stream_.get()) << "Unregister hasn't been called";
-}
+ const scoped_refptr<webrtc::MediaStreamInterface>& stream() const {
+ return webrtc_stream_;
+ }
-void RemoteMediaStreamImpl::Observer::InitializeOnMainThread(
- const std::string& label) {
- DCHECK(main_thread_->BelongsToCurrentThread());
- if (media_stream_)
- media_stream_->InitializeOnMainThread(label);
-}
+ const scoped_refptr<base::SingleThreadTaskRunner>& main_thread() const {
+ return main_thread_;
+ }
-void RemoteMediaStreamImpl::Observer::Unregister() {
- DCHECK(main_thread_->BelongsToCurrentThread());
- webrtc_stream_->UnregisterObserver(this);
- // Since we're guaranteed to not get further notifications, it's safe to
- // release the webrtc_stream_ here.
- webrtc_stream_ = nullptr;
-}
+ void InitializeOnMainThread(const std::string& label,
+ AdapterRefMap adapter_refs,
+ size_t audio_track_count,
+ size_t video_track_count) {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ if (media_stream_) {
+ media_stream_->InitializeOnMainThread(
+ label, std::move(adapter_refs), audio_track_count, video_track_count);
+ }
+ }
-void RemoteMediaStreamImpl::Observer::OnChanged() {
- std::unique_ptr<RemoteAudioTrackAdapters> audio(
- new RemoteAudioTrackAdapters());
- std::unique_ptr<RemoteVideoTrackAdapters> video(
- new RemoteVideoTrackAdapters());
+ // Uninitializes the observer, unregisteres from receiving notifications
+ // and releases the webrtc stream.
+ // Note: Must be called from the main thread before releasing the main
+ // reference.
+ void Unregister() {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ webrtc_stream_->UnregisterObserver(this);
+ // Since we're guaranteed to not get further notifications, it's safe to
+ // release the webrtc_stream_ here.
+ webrtc_stream_ = nullptr;
+ }
- CreateAdaptersForTracks(
- webrtc_stream_->GetAudioTracks(), audio.get(), main_thread_);
- CreateAdaptersForTracks(
- webrtc_stream_->GetVideoTracks(), video.get(), main_thread_);
+ private:
+ friend class base::RefCountedThreadSafe<Observer>;
- main_thread_->PostTask(FROM_HERE,
- base::Bind(&RemoteMediaStreamImpl::Observer::OnChangedOnMainThread,
- this, base::Passed(&audio), base::Passed(&video)));
-}
+ ~Observer() override {
+ DCHECK(!webrtc_stream_.get()) << "Unregister hasn't been called";
+ }
-void RemoteMediaStreamImpl::Observer::OnChangedOnMainThread(
- std::unique_ptr<RemoteAudioTrackAdapters> audio_tracks,
- std::unique_ptr<RemoteVideoTrackAdapters> video_tracks) {
- DCHECK(main_thread_->BelongsToCurrentThread());
- if (media_stream_)
- media_stream_->OnChanged(std::move(audio_tracks), std::move(video_tracks));
-}
+ // webrtc::ObserverInterface implementation.
+ void OnChanged() override {
+ AdapterRefMap new_adapter_refs = GetAdapterRefMapFromWebRtcStream(
+ track_adapter_map_, webrtc_stream_.get());
+ main_thread_->PostTask(
+ FROM_HERE,
+ base::Bind(&RemoteMediaStreamImpl::Observer::OnChangedOnMainThread,
+ this, base::Passed(&new_adapter_refs)));
+ }
+
+ void OnChangedOnMainThread(AdapterRefMap new_adapter_refs) {
+ DCHECK(main_thread_->BelongsToCurrentThread());
+ if (media_stream_)
+ media_stream_->OnChanged(std::move(new_adapter_refs));
+ }
+
+ base::WeakPtr<RemoteMediaStreamImpl> media_stream_;
+ const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
+ const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
+ scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream_;
+};
// Called on the signaling thread.
RemoteMediaStreamImpl::RemoteMediaStreamImpl(
const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
+ const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
webrtc::MediaStreamInterface* webrtc_stream)
: signaling_thread_(base::ThreadTaskRunnerHandle::Get()),
+ track_adapter_map_(track_adapter_map),
weak_factory_(this) {
+ DCHECK(!main_thread->BelongsToCurrentThread());
+ DCHECK(track_adapter_map_);
observer_ = new RemoteMediaStreamImpl::Observer(
- weak_factory_.GetWeakPtr(), main_thread, webrtc_stream);
- CreateAdaptersForTracks(webrtc_stream->GetAudioTracks(),
- &audio_track_observers_, main_thread);
- CreateAdaptersForTracks(webrtc_stream->GetVideoTracks(),
- &video_track_observers_, main_thread);
+ weak_factory_.GetWeakPtr(), main_thread, track_adapter_map_,
+ webrtc_stream);
- main_thread->PostTask(FROM_HERE,
+ AdapterRefMap adapter_refs =
+ GetAdapterRefMapFromWebRtcStream(track_adapter_map_, webrtc_stream);
+ main_thread->PostTask(
+ FROM_HERE,
base::Bind(&RemoteMediaStreamImpl::Observer::InitializeOnMainThread,
- observer_, webrtc_stream->label()));
+ observer_, webrtc_stream->label(), base::Passed(&adapter_refs),
+ webrtc_stream->GetAudioTracks().size(),
+ webrtc_stream->GetVideoTracks().size()));
}
RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
DCHECK(observer_->main_thread()->BelongsToCurrentThread());
- for (auto& track : audio_track_observers_)
- track->Unregister();
observer_->Unregister();
+ OnChanged(AdapterRefMap());
}
-void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label) {
- DCHECK(observer_->main_thread()->BelongsToCurrentThread());
- blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks(
- audio_track_observers_.size());
- for (size_t i = 0; i < audio_track_observers_.size(); ++i) {
- audio_track_observers_[i]->Initialize();
- webkit_audio_tracks[i] = *audio_track_observers_[i]->web_track();
- }
+const scoped_refptr<webrtc::MediaStreamInterface>&
+RemoteMediaStreamImpl::webrtc_stream() {
+ return observer_->stream();
+}
- blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks(
- video_track_observers_.size());
- for (size_t i = 0; i < video_track_observers_.size(); ++i) {
- video_track_observers_[i]->Initialize();
- webkit_video_tracks[i] = *video_track_observers_[i]->web_track();
+void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label,
+ AdapterRefMap adapter_refs,
+ size_t audio_track_count,
+ size_t video_track_count) {
+ DCHECK(observer_->main_thread()->BelongsToCurrentThread());
+ DCHECK_EQ(audio_track_count + video_track_count, adapter_refs.size());
+
+ adapter_refs_ = std::move(adapter_refs);
+ blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks(
+ audio_track_count);
+ blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks(
+ video_track_count);
+ size_t audio_i = 0;
+ size_t video_i = 0;
+ for (const auto& it : adapter_refs_) {
+ const blink::WebMediaStreamTrack& web_track = it.second->web_track();
+ if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio)
+ web_audio_tracks[audio_i++] = web_track;
+ else
+ web_video_tracks[video_i++] = web_track;
}
- webkit_stream_.Initialize(blink::WebString::FromUTF8(label),
- webkit_audio_tracks, webkit_video_tracks);
+ webkit_stream_.Initialize(blink::WebString::FromUTF8(label), web_audio_tracks,
+ web_video_tracks);
webkit_stream_.SetExtraData(new MediaStream());
}
-void RemoteMediaStreamImpl::OnChanged(
- std::unique_ptr<RemoteAudioTrackAdapters> audio_tracks,
- std::unique_ptr<RemoteVideoTrackAdapters> video_tracks) {
- // Find removed tracks.
- auto audio_it = audio_track_observers_.begin();
- while (audio_it != audio_track_observers_.end()) {
- if (!IsTrackInVector(*audio_tracks.get(), (*audio_it)->id())) {
- (*audio_it)->Unregister();
- webkit_stream_.RemoveTrack(*(*audio_it)->web_track());
- audio_it = audio_track_observers_.erase(audio_it);
- } else {
- ++audio_it;
- }
- }
+void RemoteMediaStreamImpl::OnChanged(AdapterRefMap new_adapter_refs) {
+ DCHECK(observer_->main_thread()->BelongsToCurrentThread());
- auto video_it = video_track_observers_.begin();
- while (video_it != video_track_observers_.end()) {
- if (!IsTrackInVector(*video_tracks.get(), (*video_it)->id())) {
- webkit_stream_.RemoveTrack(*(*video_it)->web_track());
- video_it = video_track_observers_.erase(video_it);
+ // Find removed tracks.
+ for (auto it = adapter_refs_.begin(); it != adapter_refs_.end();) {
+ if (new_adapter_refs.find(it->first) == new_adapter_refs.end()) {
+ webkit_stream_.RemoveTrack(it->second->web_track());
+ it = adapter_refs_.erase(it);
} else {
- ++video_it;
+ ++it;
}
}
-
// Find added tracks.
- for (auto& track : *audio_tracks.get()) {
- if (!IsTrackInVector(audio_track_observers_, track->id())) {
- track->Initialize();
- audio_track_observers_.push_back(track);
- webkit_stream_.AddTrack(*track->web_track());
- // Set the track to null to avoid unregistering it below now that it's
- // been associated with a media stream.
- track = nullptr;
+ for (auto& it : new_adapter_refs) {
+ if (adapter_refs_.find(it.first) == adapter_refs_.end()) {
+ webkit_stream_.AddTrack(it.second->web_track());
+ adapter_refs_.insert(std::make_pair(it.first, std::move(it.second)));
}
}
-
- // Find added video tracks.
- for (const auto& track : *video_tracks.get()) {
- if (!IsTrackInVector(video_track_observers_, track->id())) {
- track->Initialize();
- video_track_observers_.push_back(track);
- webkit_stream_.AddTrack(*track->web_track());
- }
- }
-
- // Unregister all the audio track observers that were not used.
- // We need to do this before destruction since the observers can't unregister
- // from within the dtor due to a race.
- for (auto& track : *audio_tracks.get()) {
- if (track.get())
- track->Unregister();
- }
}
} // namespace content
« no previous file with comments | « content/renderer/media/remote_media_stream_impl.h ('k') | content/renderer/media/rtc_peer_connection_handler.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698