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

Side by Side 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 unified diff | Download patch
OLDNEW
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/renderer/media/remote_media_stream_impl.h" 5 #include "content/renderer/media/remote_media_stream_impl.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
11 11
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/location.h" 13 #include "base/location.h"
14 #include "base/logging.h" 14 #include "base/logging.h"
15 #include "base/macros.h" 15 #include "base/macros.h"
16 #include "base/threading/thread_task_runner_handle.h" 16 #include "base/threading/thread_task_runner_handle.h"
17 #include "content/renderer/media/media_stream.h" 17 #include "content/renderer/media/media_stream.h"
18 #include "content/renderer/media/media_stream_track.h" 18 #include "content/renderer/media/media_stream_track.h"
19 #include "content/renderer/media/media_stream_video_track.h" 19 #include "content/renderer/media/media_stream_video_track.h"
20 #include "content/renderer/media/remote_media_stream_track_adapter.h" 20 #include "content/renderer/media/remote_media_stream_track_adapter.h"
21 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" 21 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
22 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 22 #include "third_party/WebKit/public/platform/WebMediaStreamTrack.h"
23 #include "third_party/WebKit/public/platform/WebString.h" 23 #include "third_party/WebKit/public/platform/WebString.h"
24 24
25 namespace content { 25 namespace content {
26
26 namespace { 27 namespace {
27 28
28 template <typename WebRtcTrackVector, typename AdapterType> 29 // Gets the adapters for the tracks that are members of the webrtc stream.
29 void CreateAdaptersForTracks( 30 // Invoke on webrtc signaling thread. New adapters are initialized in a post
30 const WebRtcTrackVector& tracks, 31 // to the main thread after which their |web_track| becomes available.
31 std::vector<scoped_refptr<AdapterType>>* observers, 32 RemoteMediaStreamImpl::AdapterRefMap GetAdapterRefMapFromWebRtcStream(
32 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) { 33 const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
33 for (auto& track : tracks) 34 webrtc::MediaStreamInterface* webrtc_stream) {
34 observers->push_back(new AdapterType(main_thread, track)); 35 RemoteMediaStreamImpl::AdapterRefMap adapter_refs;
36 for (auto& webrtc_audio_track : webrtc_stream->GetAudioTracks()) {
37 adapter_refs.insert(
38 std::make_pair(webrtc_audio_track->id(),
39 track_adapter_map->GetOrCreateRemoteTrackAdapter(
40 webrtc_audio_track.get())));
41 }
42 for (auto& webrtc_video_track : webrtc_stream->GetVideoTracks()) {
43 adapter_refs.insert(
44 std::make_pair(webrtc_video_track->id(),
45 track_adapter_map->GetOrCreateRemoteTrackAdapter(
46 webrtc_video_track.get())));
47 }
48 return adapter_refs;
35 } 49 }
36 50
37 template<typename VectorType>
38 bool IsTrackInVector(const VectorType& v, const std::string& id) {
39 for (const auto& t : v) {
40 if (t->id() == id)
41 return true;
42 }
43 return false;
44 }
45 } // namespace 51 } // namespace
46 52
47 RemoteMediaStreamImpl::Observer::Observer( 53 class RemoteMediaStreamImpl::Observer
48 const base::WeakPtr<RemoteMediaStreamImpl>& media_stream, 54 : NON_EXPORTED_BASE(public webrtc::ObserverInterface),
49 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, 55 public base::RefCountedThreadSafe<Observer> {
50 webrtc::MediaStreamInterface* webrtc_stream) 56 public:
51 : media_stream_(media_stream), 57 Observer(
52 main_thread_(main_thread), 58 const base::WeakPtr<RemoteMediaStreamImpl>& media_stream,
53 webrtc_stream_(webrtc_stream) { 59 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
54 webrtc_stream_->RegisterObserver(this); 60 const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
55 } 61 webrtc::MediaStreamInterface* webrtc_stream)
62 : media_stream_(media_stream),
63 main_thread_(main_thread),
64 track_adapter_map_(track_adapter_map),
65 webrtc_stream_(webrtc_stream) {
66 webrtc_stream_->RegisterObserver(this);
67 }
56 68
57 RemoteMediaStreamImpl::Observer::~Observer() { 69 const scoped_refptr<webrtc::MediaStreamInterface>& stream() const {
58 DCHECK(!webrtc_stream_.get()) << "Unregister hasn't been called"; 70 return webrtc_stream_;
59 } 71 }
60 72
61 void RemoteMediaStreamImpl::Observer::InitializeOnMainThread( 73 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread() const {
62 const std::string& label) { 74 return main_thread_;
63 DCHECK(main_thread_->BelongsToCurrentThread()); 75 }
64 if (media_stream_)
65 media_stream_->InitializeOnMainThread(label);
66 }
67 76
68 void RemoteMediaStreamImpl::Observer::Unregister() { 77 void InitializeOnMainThread(const std::string& label,
69 DCHECK(main_thread_->BelongsToCurrentThread()); 78 AdapterRefMap adapter_refs,
70 webrtc_stream_->UnregisterObserver(this); 79 size_t audio_track_count,
71 // Since we're guaranteed to not get further notifications, it's safe to 80 size_t video_track_count) {
72 // release the webrtc_stream_ here. 81 DCHECK(main_thread_->BelongsToCurrentThread());
73 webrtc_stream_ = nullptr; 82 if (media_stream_) {
74 } 83 media_stream_->InitializeOnMainThread(
84 label, std::move(adapter_refs), audio_track_count, video_track_count);
85 }
86 }
75 87
76 void RemoteMediaStreamImpl::Observer::OnChanged() { 88 // Uninitializes the observer, unregisteres from receiving notifications
77 std::unique_ptr<RemoteAudioTrackAdapters> audio( 89 // and releases the webrtc stream.
78 new RemoteAudioTrackAdapters()); 90 // Note: Must be called from the main thread before releasing the main
79 std::unique_ptr<RemoteVideoTrackAdapters> video( 91 // reference.
80 new RemoteVideoTrackAdapters()); 92 void Unregister() {
93 DCHECK(main_thread_->BelongsToCurrentThread());
94 webrtc_stream_->UnregisterObserver(this);
95 // Since we're guaranteed to not get further notifications, it's safe to
96 // release the webrtc_stream_ here.
97 webrtc_stream_ = nullptr;
98 }
81 99
82 CreateAdaptersForTracks( 100 private:
83 webrtc_stream_->GetAudioTracks(), audio.get(), main_thread_); 101 friend class base::RefCountedThreadSafe<Observer>;
84 CreateAdaptersForTracks(
85 webrtc_stream_->GetVideoTracks(), video.get(), main_thread_);
86 102
87 main_thread_->PostTask(FROM_HERE, 103 ~Observer() override {
88 base::Bind(&RemoteMediaStreamImpl::Observer::OnChangedOnMainThread, 104 DCHECK(!webrtc_stream_.get()) << "Unregister hasn't been called";
89 this, base::Passed(&audio), base::Passed(&video))); 105 }
90 }
91 106
92 void RemoteMediaStreamImpl::Observer::OnChangedOnMainThread( 107 // webrtc::ObserverInterface implementation.
93 std::unique_ptr<RemoteAudioTrackAdapters> audio_tracks, 108 void OnChanged() override {
94 std::unique_ptr<RemoteVideoTrackAdapters> video_tracks) { 109 AdapterRefMap new_adapter_refs = GetAdapterRefMapFromWebRtcStream(
95 DCHECK(main_thread_->BelongsToCurrentThread()); 110 track_adapter_map_, webrtc_stream_.get());
96 if (media_stream_) 111 main_thread_->PostTask(
97 media_stream_->OnChanged(std::move(audio_tracks), std::move(video_tracks)); 112 FROM_HERE,
98 } 113 base::Bind(&RemoteMediaStreamImpl::Observer::OnChangedOnMainThread,
114 this, base::Passed(&new_adapter_refs)));
115 }
116
117 void OnChangedOnMainThread(AdapterRefMap new_adapter_refs) {
118 DCHECK(main_thread_->BelongsToCurrentThread());
119 if (media_stream_)
120 media_stream_->OnChanged(std::move(new_adapter_refs));
121 }
122
123 base::WeakPtr<RemoteMediaStreamImpl> media_stream_;
124 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
125 const scoped_refptr<WebRtcMediaStreamTrackAdapterMap> track_adapter_map_;
126 scoped_refptr<webrtc::MediaStreamInterface> webrtc_stream_;
127 };
99 128
100 // Called on the signaling thread. 129 // Called on the signaling thread.
101 RemoteMediaStreamImpl::RemoteMediaStreamImpl( 130 RemoteMediaStreamImpl::RemoteMediaStreamImpl(
102 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, 131 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
132 const scoped_refptr<WebRtcMediaStreamTrackAdapterMap>& track_adapter_map,
103 webrtc::MediaStreamInterface* webrtc_stream) 133 webrtc::MediaStreamInterface* webrtc_stream)
104 : signaling_thread_(base::ThreadTaskRunnerHandle::Get()), 134 : signaling_thread_(base::ThreadTaskRunnerHandle::Get()),
135 track_adapter_map_(track_adapter_map),
105 weak_factory_(this) { 136 weak_factory_(this) {
137 DCHECK(!main_thread->BelongsToCurrentThread());
138 DCHECK(track_adapter_map_);
106 observer_ = new RemoteMediaStreamImpl::Observer( 139 observer_ = new RemoteMediaStreamImpl::Observer(
107 weak_factory_.GetWeakPtr(), main_thread, webrtc_stream); 140 weak_factory_.GetWeakPtr(), main_thread, track_adapter_map_,
108 CreateAdaptersForTracks(webrtc_stream->GetAudioTracks(), 141 webrtc_stream);
109 &audio_track_observers_, main_thread);
110 CreateAdaptersForTracks(webrtc_stream->GetVideoTracks(),
111 &video_track_observers_, main_thread);
112 142
113 main_thread->PostTask(FROM_HERE, 143 AdapterRefMap adapter_refs =
144 GetAdapterRefMapFromWebRtcStream(track_adapter_map_, webrtc_stream);
145 main_thread->PostTask(
146 FROM_HERE,
114 base::Bind(&RemoteMediaStreamImpl::Observer::InitializeOnMainThread, 147 base::Bind(&RemoteMediaStreamImpl::Observer::InitializeOnMainThread,
115 observer_, webrtc_stream->label())); 148 observer_, webrtc_stream->label(), base::Passed(&adapter_refs),
149 webrtc_stream->GetAudioTracks().size(),
150 webrtc_stream->GetVideoTracks().size()));
116 } 151 }
117 152
118 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { 153 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
119 DCHECK(observer_->main_thread()->BelongsToCurrentThread()); 154 DCHECK(observer_->main_thread()->BelongsToCurrentThread());
120 for (auto& track : audio_track_observers_)
121 track->Unregister();
122 observer_->Unregister(); 155 observer_->Unregister();
156 OnChanged(AdapterRefMap());
123 } 157 }
124 158
125 void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label) { 159 const scoped_refptr<webrtc::MediaStreamInterface>&
160 RemoteMediaStreamImpl::webrtc_stream() {
161 return observer_->stream();
162 }
163
164 void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label,
165 AdapterRefMap adapter_refs,
166 size_t audio_track_count,
167 size_t video_track_count) {
126 DCHECK(observer_->main_thread()->BelongsToCurrentThread()); 168 DCHECK(observer_->main_thread()->BelongsToCurrentThread());
127 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( 169 DCHECK_EQ(audio_track_count + video_track_count, adapter_refs.size());
128 audio_track_observers_.size()); 170
129 for (size_t i = 0; i < audio_track_observers_.size(); ++i) { 171 adapter_refs_ = std::move(adapter_refs);
130 audio_track_observers_[i]->Initialize(); 172 blink::WebVector<blink::WebMediaStreamTrack> web_audio_tracks(
131 webkit_audio_tracks[i] = *audio_track_observers_[i]->web_track(); 173 audio_track_count);
174 blink::WebVector<blink::WebMediaStreamTrack> web_video_tracks(
175 video_track_count);
176 size_t audio_i = 0;
177 size_t video_i = 0;
178 for (const auto& it : adapter_refs_) {
179 const blink::WebMediaStreamTrack& web_track = it.second->web_track();
180 if (web_track.Source().GetType() == blink::WebMediaStreamSource::kTypeAudio)
181 web_audio_tracks[audio_i++] = web_track;
182 else
183 web_video_tracks[video_i++] = web_track;
132 } 184 }
133 185
134 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( 186 webkit_stream_.Initialize(blink::WebString::FromUTF8(label), web_audio_tracks,
135 video_track_observers_.size()); 187 web_video_tracks);
136 for (size_t i = 0; i < video_track_observers_.size(); ++i) {
137 video_track_observers_[i]->Initialize();
138 webkit_video_tracks[i] = *video_track_observers_[i]->web_track();
139 }
140
141 webkit_stream_.Initialize(blink::WebString::FromUTF8(label),
142 webkit_audio_tracks, webkit_video_tracks);
143 webkit_stream_.SetExtraData(new MediaStream()); 188 webkit_stream_.SetExtraData(new MediaStream());
144 } 189 }
145 190
146 void RemoteMediaStreamImpl::OnChanged( 191 void RemoteMediaStreamImpl::OnChanged(AdapterRefMap new_adapter_refs) {
147 std::unique_ptr<RemoteAudioTrackAdapters> audio_tracks, 192 DCHECK(observer_->main_thread()->BelongsToCurrentThread());
148 std::unique_ptr<RemoteVideoTrackAdapters> video_tracks) { 193
149 // Find removed tracks. 194 // Find removed tracks.
150 auto audio_it = audio_track_observers_.begin(); 195 for (auto it = adapter_refs_.begin(); it != adapter_refs_.end();) {
151 while (audio_it != audio_track_observers_.end()) { 196 if (new_adapter_refs.find(it->first) == new_adapter_refs.end()) {
152 if (!IsTrackInVector(*audio_tracks.get(), (*audio_it)->id())) { 197 webkit_stream_.RemoveTrack(it->second->web_track());
153 (*audio_it)->Unregister(); 198 it = adapter_refs_.erase(it);
154 webkit_stream_.RemoveTrack(*(*audio_it)->web_track());
155 audio_it = audio_track_observers_.erase(audio_it);
156 } else { 199 } else {
157 ++audio_it; 200 ++it;
158 } 201 }
159 } 202 }
160 203 // Find added tracks.
161 auto video_it = video_track_observers_.begin(); 204 for (auto& it : new_adapter_refs) {
162 while (video_it != video_track_observers_.end()) { 205 if (adapter_refs_.find(it.first) == adapter_refs_.end()) {
163 if (!IsTrackInVector(*video_tracks.get(), (*video_it)->id())) { 206 webkit_stream_.AddTrack(it.second->web_track());
164 webkit_stream_.RemoveTrack(*(*video_it)->web_track()); 207 adapter_refs_.insert(std::make_pair(it.first, std::move(it.second)));
165 video_it = video_track_observers_.erase(video_it);
166 } else {
167 ++video_it;
168 } 208 }
169 } 209 }
170
171 // Find added tracks.
172 for (auto& track : *audio_tracks.get()) {
173 if (!IsTrackInVector(audio_track_observers_, track->id())) {
174 track->Initialize();
175 audio_track_observers_.push_back(track);
176 webkit_stream_.AddTrack(*track->web_track());
177 // Set the track to null to avoid unregistering it below now that it's
178 // been associated with a media stream.
179 track = nullptr;
180 }
181 }
182
183 // Find added video tracks.
184 for (const auto& track : *video_tracks.get()) {
185 if (!IsTrackInVector(video_track_observers_, track->id())) {
186 track->Initialize();
187 video_track_observers_.push_back(track);
188 webkit_stream_.AddTrack(*track->web_track());
189 }
190 }
191
192 // Unregister all the audio track observers that were not used.
193 // We need to do this before destruction since the observers can't unregister
194 // from within the dtor due to a race.
195 for (auto& track : *audio_tracks.get()) {
196 if (track.get())
197 track->Unregister();
198 }
199 } 210 }
200 211
201 } // namespace content 212 } // namespace content
OLDNEW
« 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