OLD | NEW |
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 <string> | 7 #include <string> |
8 | 8 |
| 9 #include "base/bind.h" |
| 10 #include "base/location.h" |
9 #include "base/logging.h" | 11 #include "base/logging.h" |
10 #include "base/strings/utf_string_conversions.h" | 12 #include "base/strings/utf_string_conversions.h" |
| 13 #include "base/thread_task_runner_handle.h" |
11 #include "content/renderer/media/media_stream.h" | 14 #include "content/renderer/media/media_stream.h" |
| 15 #include "content/renderer/media/media_stream_track.h" |
12 #include "content/renderer/media/media_stream_video_track.h" | 16 #include "content/renderer/media/media_stream_video_track.h" |
13 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" | 17 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h" |
14 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" | 18 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
15 #include "third_party/WebKit/public/platform/WebString.h" | 19 #include "third_party/WebKit/public/platform/WebString.h" |
16 | 20 |
17 namespace content { | 21 namespace content { |
18 | |
19 namespace { | 22 namespace { |
20 | 23 |
21 void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track, | 24 template <typename WebRtcTrackVector, typename AdapterType> |
22 blink::WebMediaStreamTrack* webkit_track, | 25 void CreateAdaptersForTracks( |
23 blink::WebMediaStreamSource::Type type) { | 26 const WebRtcTrackVector& tracks, |
24 blink::WebMediaStreamSource webkit_source; | 27 std::vector<scoped_refptr<AdapterType>>* observers, |
25 blink::WebString webkit_track_id(base::UTF8ToUTF16(track->id())); | 28 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread) { |
26 | 29 for (auto& track : tracks) |
27 webkit_source.initialize(webkit_track_id, type, webkit_track_id); | 30 observers->push_back(new AdapterType(main_thread, track)); |
28 webkit_track->initialize(webkit_track_id, webkit_source); | 31 } |
29 | 32 |
30 if (type == blink::WebMediaStreamSource::TypeVideo) { | 33 template<typename VectorType> |
31 MediaStreamRemoteVideoSource* video_source = | 34 bool IsTrackInVector(const VectorType& v, const std::string& id) { |
32 new MediaStreamRemoteVideoSource( | 35 for (const auto& t : v) { |
33 static_cast<webrtc::VideoTrackInterface*>(track)); | 36 if (t->id() == id) |
34 webkit_source.setExtraData(video_source); | 37 return true; |
| 38 } |
| 39 return false; |
| 40 } |
| 41 } // namespace |
| 42 |
| 43 // TODO(tommi): Move this class to a separate set of files. |
| 44 class RemoteMediaStreamAudioTrack : public MediaStreamTrack { |
| 45 public: |
| 46 RemoteMediaStreamAudioTrack( |
| 47 const scoped_refptr<webrtc::AudioTrackInterface>& track, |
| 48 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread) |
| 49 : MediaStreamTrack(false), track_(track), |
| 50 signaling_thread_(signaling_thread) { |
| 51 } |
| 52 |
| 53 ~RemoteMediaStreamAudioTrack() override {} |
| 54 |
| 55 private: |
| 56 void SetEnabled(bool enabled) override { |
| 57 track_->set_enabled(enabled); |
| 58 } |
| 59 |
| 60 void Stop() override { |
| 61 // Stop means that a track should be stopped permanently. But |
| 62 // since there is no proper way of doing that on a remote track, we can |
| 63 // at least disable the track. Blink will not call down to the content layer |
| 64 // after a track has been stopped. |
| 65 SetEnabled(false); |
| 66 } |
| 67 |
| 68 private: |
| 69 const scoped_refptr<webrtc::AudioTrackInterface> track_; |
| 70 const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_; |
| 71 }; |
| 72 |
| 73 // Base class used for mapping between webrtc and blink MediaStream tracks. |
| 74 // An instance of a RemoteMediaStreamTrackAdapter is stored in |
| 75 // RemoteMediaStreamImpl per remote audio and video track. |
| 76 template<typename WebRtcMediaStreamTrackType> |
| 77 class RemoteMediaStreamTrackAdapter |
| 78 : public base::RefCountedThreadSafe< |
| 79 RemoteMediaStreamTrackAdapter<WebRtcMediaStreamTrackType>> { |
| 80 public: |
| 81 RemoteMediaStreamTrackAdapter( |
| 82 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
| 83 WebRtcMediaStreamTrackType* webrtc_track) |
| 84 : main_thread_(main_thread), webrtc_track_(webrtc_track), |
| 85 id_(webrtc_track->id()) { |
| 86 } |
| 87 |
| 88 const scoped_refptr<WebRtcMediaStreamTrackType>& observed_track() { |
| 89 return webrtc_track_; |
| 90 } |
| 91 |
| 92 blink::WebMediaStreamTrack* webkit_track() { |
| 93 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 94 DCHECK(!webkit_track_.isNull()); |
| 95 return &webkit_track_; |
| 96 } |
| 97 |
| 98 const std::string& id() const { return id_; } |
| 99 |
| 100 bool initialized() const { |
| 101 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 102 return !webkit_track_.isNull(); |
| 103 } |
| 104 |
| 105 void Initialize() { |
| 106 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 107 DCHECK(!initialized()); |
| 108 webkit_initialize_.Run(); |
| 109 webkit_initialize_.Reset(); |
| 110 DCHECK(initialized()); |
| 111 } |
| 112 |
| 113 protected: |
| 114 friend class base::RefCountedThreadSafe< |
| 115 RemoteMediaStreamTrackAdapter<WebRtcMediaStreamTrackType>>; |
| 116 |
| 117 virtual ~RemoteMediaStreamTrackAdapter() { |
| 118 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 119 } |
| 120 |
| 121 void InitializeWebkitTrack(blink::WebMediaStreamSource::Type type) { |
| 122 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 123 DCHECK(webkit_track_.isNull()); |
| 124 |
| 125 blink::WebString webkit_track_id(base::UTF8ToUTF16(id_)); |
| 126 blink::WebMediaStreamSource webkit_source; |
| 127 webkit_source.initialize(webkit_track_id, type, webkit_track_id); |
| 128 webkit_track_.initialize(webkit_track_id, webkit_source); |
| 129 DCHECK(!webkit_track_.isNull()); |
| 130 } |
| 131 |
| 132 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_; |
| 133 // This callback will be run when Initialize() is called and then freed. |
| 134 // The callback is used by derived classes to bind objects that need to be |
| 135 // instantiated and initialized on the signaling thread but then moved to |
| 136 // and used on the main thread when initializing the webkit object(s). |
| 137 base::Callback<void()> webkit_initialize_; |
| 138 |
| 139 private: |
| 140 const scoped_refptr<WebRtcMediaStreamTrackType> webrtc_track_; |
| 141 blink::WebMediaStreamTrack webkit_track_; |
| 142 // const copy of the webrtc track id that allows us to check it from both the |
| 143 // main and signaling threads without incurring a synchronous thread hop. |
| 144 const std::string id_; |
| 145 |
| 146 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter); |
| 147 }; |
| 148 |
| 149 class RemoteVideoTrackAdapter |
| 150 : public RemoteMediaStreamTrackAdapter<webrtc::VideoTrackInterface> { |
| 151 public: |
| 152 // Called on the signaling thread |
| 153 RemoteVideoTrackAdapter( |
| 154 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
| 155 webrtc::VideoTrackInterface* webrtc_track) |
| 156 : RemoteMediaStreamTrackAdapter(main_thread, webrtc_track) { |
| 157 scoped_refptr<MediaStreamRemoteVideoSource::Observer> source_observer( |
| 158 new MediaStreamRemoteVideoSource::Observer(main_thread, |
| 159 observed_track().get())); |
| 160 // Here, we use base::Unretained() to avoid a circular reference. |
| 161 webkit_initialize_ = base::Bind( |
| 162 &RemoteVideoTrackAdapter::InitializeWebkitVideoTrack, |
| 163 base::Unretained(this), source_observer, observed_track()->enabled()); |
| 164 } |
| 165 |
| 166 protected: |
| 167 ~RemoteVideoTrackAdapter() override {} |
| 168 |
| 169 private: |
| 170 void InitializeWebkitVideoTrack( |
| 171 const scoped_refptr<MediaStreamRemoteVideoSource::Observer>& observer, |
| 172 bool enabled) { |
| 173 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 174 scoped_ptr<MediaStreamRemoteVideoSource> video_source( |
| 175 new MediaStreamRemoteVideoSource(observer)); |
| 176 InitializeWebkitTrack(blink::WebMediaStreamSource::TypeVideo); |
| 177 webkit_track()->source().setExtraData(video_source.get()); |
35 // Initial constraints must be provided to a MediaStreamVideoTrack. But | 178 // Initial constraints must be provided to a MediaStreamVideoTrack. But |
36 // no constraints are available initially on a remote video track. | 179 // no constraints are available initially on a remote video track. |
37 blink::WebMediaConstraints constraints; | 180 blink::WebMediaConstraints constraints; |
38 constraints.initialize(); | 181 constraints.initialize(); |
39 webkit_track->setExtraData( | 182 MediaStreamVideoTrack* media_stream_track = |
40 new MediaStreamVideoTrack(video_source, constraints, | 183 new MediaStreamVideoTrack(video_source.release(), constraints, |
41 MediaStreamVideoSource::ConstraintsCallback(), | 184 MediaStreamVideoSource::ConstraintsCallback(), enabled); |
42 track->enabled())); | 185 webkit_track()->setExtraData(media_stream_track); |
43 } else { | 186 } |
44 DCHECK(type == blink::WebMediaStreamSource::TypeAudio); | 187 }; |
45 content::PeerConnectionDependencyFactory::AddNativeAudioTrackToBlinkTrack( | 188 |
46 track, *webkit_track, false); | 189 // RemoteAudioTrackAdapter is responsible for listening on state |
47 } | |
48 } | |
49 | |
50 } // namespace | |
51 | |
52 // Base class used for mapping between webrtc and blink MediaStream tracks. | |
53 // An instance of a RemoteMediaStreamTrackAdapter is stored in | |
54 // RemoteMediaStreamImpl per remote audio and video track. | |
55 class RemoteMediaStreamTrackAdapter { | |
56 public: | |
57 RemoteMediaStreamTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track, | |
58 const blink::WebMediaStreamTrack& webkit_track) | |
59 : webrtc_track_(webrtc_track), | |
60 webkit_track_(webkit_track) { | |
61 } | |
62 | |
63 virtual ~RemoteMediaStreamTrackAdapter() { | |
64 } | |
65 | |
66 webrtc::MediaStreamTrackInterface* observed_track() { | |
67 return webrtc_track_.get(); | |
68 } | |
69 | |
70 const blink::WebMediaStreamTrack& webkit_track() { return webkit_track_; } | |
71 | |
72 private: | |
73 scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_; | |
74 blink::WebMediaStreamTrack webkit_track_; | |
75 | |
76 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter); | |
77 }; | |
78 | |
79 static content::RemoteMediaStreamTrackAdapter* FindTrackObserver( | |
80 webrtc::MediaStreamTrackInterface* track, | |
81 const ScopedVector<content::RemoteMediaStreamTrackAdapter>& observers) { | |
82 ScopedVector<content::RemoteMediaStreamTrackAdapter>::const_iterator it = | |
83 observers.begin(); | |
84 for (; it != observers.end(); ++it) { | |
85 if ((*it)->observed_track() == track) | |
86 return *it; | |
87 } | |
88 return NULL; | |
89 } | |
90 | |
91 // RemoteAudioMediaStreamTrackAdapter is responsible for listening on state | |
92 // change notifications on a remote webrtc audio MediaStreamTracks and notify | 190 // change notifications on a remote webrtc audio MediaStreamTracks and notify |
93 // WebKit. | 191 // WebKit. |
94 class RemoteAudioMediaStreamTrackAdapter | 192 class RemoteAudioTrackAdapter |
95 : public RemoteMediaStreamTrackAdapter, | 193 : public RemoteMediaStreamTrackAdapter<webrtc::AudioTrackInterface>, |
96 public webrtc::ObserverInterface, | 194 public webrtc::ObserverInterface { |
97 public base::NonThreadSafe { | 195 public: |
98 public: | 196 RemoteAudioTrackAdapter( |
99 RemoteAudioMediaStreamTrackAdapter( | 197 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
100 webrtc::MediaStreamTrackInterface* webrtc_track, | 198 webrtc::AudioTrackInterface* webrtc_track); |
101 const blink::WebMediaStreamTrack& webkit_track); | 199 |
102 ~RemoteAudioMediaStreamTrackAdapter() override; | 200 protected: |
103 | 201 ~RemoteAudioTrackAdapter() override; |
104 private: | 202 |
| 203 private: |
| 204 void InitializeWebkitAudioTrack( |
| 205 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track); |
| 206 |
105 // webrtc::ObserverInterface implementation. | 207 // webrtc::ObserverInterface implementation. |
106 void OnChanged() override; | 208 void OnChanged() override; |
107 | 209 |
| 210 void OnChangedOnMainThread( |
| 211 webrtc::MediaStreamTrackInterface::TrackState state); |
| 212 |
108 webrtc::MediaStreamTrackInterface::TrackState state_; | 213 webrtc::MediaStreamTrackInterface::TrackState state_; |
109 | 214 |
110 DISALLOW_COPY_AND_ASSIGN(RemoteAudioMediaStreamTrackAdapter); | 215 DISALLOW_COPY_AND_ASSIGN(RemoteAudioTrackAdapter); |
111 }; | 216 }; |
112 | 217 |
113 RemoteAudioMediaStreamTrackAdapter::RemoteAudioMediaStreamTrackAdapter( | 218 // Called on the signaling thread. |
114 webrtc::MediaStreamTrackInterface* webrtc_track, | 219 RemoteAudioTrackAdapter::RemoteAudioTrackAdapter( |
115 const blink::WebMediaStreamTrack& webkit_track) | 220 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
116 : RemoteMediaStreamTrackAdapter(webrtc_track, webkit_track), | 221 webrtc::AudioTrackInterface* webrtc_track) |
| 222 : RemoteMediaStreamTrackAdapter(main_thread, webrtc_track), |
117 state_(observed_track()->state()) { | 223 state_(observed_track()->state()) { |
118 observed_track()->RegisterObserver(this); | 224 observed_track()->RegisterObserver(this); |
119 } | 225 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track( |
120 | 226 new RemoteMediaStreamAudioTrack(observed_track().get(), |
121 RemoteAudioMediaStreamTrackAdapter::~RemoteAudioMediaStreamTrackAdapter() { | 227 base::ThreadTaskRunnerHandle::Get())); |
| 228 // Here, we use base::Unretained() to avoid a circular reference. |
| 229 webkit_initialize_ = base::Bind( |
| 230 &RemoteAudioTrackAdapter::InitializeWebkitAudioTrack, |
| 231 base::Unretained(this), base::Passed(&media_stream_track)); |
| 232 } |
| 233 |
| 234 RemoteAudioTrackAdapter::~RemoteAudioTrackAdapter() { |
122 observed_track()->UnregisterObserver(this); | 235 observed_track()->UnregisterObserver(this); |
123 } | 236 } |
124 | 237 |
125 void RemoteAudioMediaStreamTrackAdapter::OnChanged() { | 238 void RemoteAudioTrackAdapter::InitializeWebkitAudioTrack( |
126 DCHECK(CalledOnValidThread()); | 239 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track) { |
127 | 240 InitializeWebkitTrack(blink::WebMediaStreamSource::TypeAudio); |
128 webrtc::MediaStreamTrackInterface::TrackState state = | 241 webkit_track()->setExtraData(media_stream_track.release()); |
129 observed_track()->state(); | 242 } |
130 if (state == state_) | 243 |
| 244 void RemoteAudioTrackAdapter::OnChanged() { |
| 245 main_thread_->PostTask(FROM_HERE, |
| 246 base::Bind(&RemoteAudioTrackAdapter::OnChangedOnMainThread, |
| 247 this, observed_track()->state())); |
| 248 } |
| 249 |
| 250 void RemoteAudioTrackAdapter::OnChangedOnMainThread( |
| 251 webrtc::MediaStreamTrackInterface::TrackState state) { |
| 252 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 253 |
| 254 if (state == state_ || !initialized()) |
131 return; | 255 return; |
132 | 256 |
133 state_ = state; | 257 state_ = state; |
| 258 |
134 switch (state) { | 259 switch (state) { |
135 case webrtc::MediaStreamTrackInterface::kInitializing: | 260 case webrtc::MediaStreamTrackInterface::kInitializing: |
136 // Ignore the kInitializing state since there is no match in | 261 // Ignore the kInitializing state since there is no match in |
137 // WebMediaStreamSource::ReadyState. | 262 // WebMediaStreamSource::ReadyState. |
138 break; | 263 break; |
139 case webrtc::MediaStreamTrackInterface::kLive: | 264 case webrtc::MediaStreamTrackInterface::kLive: |
140 webkit_track().source().setReadyState( | 265 webkit_track()->source().setReadyState( |
141 blink::WebMediaStreamSource::ReadyStateLive); | 266 blink::WebMediaStreamSource::ReadyStateLive); |
142 break; | 267 break; |
143 case webrtc::MediaStreamTrackInterface::kEnded: | 268 case webrtc::MediaStreamTrackInterface::kEnded: |
144 webkit_track().source().setReadyState( | 269 webkit_track()->source().setReadyState( |
145 blink::WebMediaStreamSource::ReadyStateEnded); | 270 blink::WebMediaStreamSource::ReadyStateEnded); |
146 break; | 271 break; |
147 default: | 272 default: |
148 NOTREACHED(); | 273 NOTREACHED(); |
149 break; | 274 break; |
150 } | 275 } |
151 } | 276 } |
152 | 277 |
| 278 RemoteMediaStreamImpl::Observer::Observer( |
| 279 const base::WeakPtr<RemoteMediaStreamImpl>& media_stream, |
| 280 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
| 281 webrtc::MediaStreamInterface* webrtc_stream) |
| 282 : media_stream_(media_stream), |
| 283 main_thread_(main_thread), |
| 284 webrtc_stream_(webrtc_stream) { |
| 285 webrtc_stream_->RegisterObserver(this); |
| 286 } |
| 287 |
| 288 RemoteMediaStreamImpl::Observer::~Observer() { |
| 289 // Can in theory be destructed either on the signaling or main thread. |
| 290 webrtc_stream_->UnregisterObserver(this); |
| 291 } |
| 292 |
| 293 void RemoteMediaStreamImpl::Observer::InitializeOnMainThread( |
| 294 const std::string& label) { |
| 295 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 296 if (media_stream_) |
| 297 media_stream_->InitializeOnMainThread(label); |
| 298 } |
| 299 |
| 300 void RemoteMediaStreamImpl::Observer::OnChanged() { |
| 301 scoped_ptr<RemoteAudioTrackAdapters> audio(new RemoteAudioTrackAdapters()); |
| 302 scoped_ptr<RemoteVideoTrackAdapters> video(new RemoteVideoTrackAdapters()); |
| 303 |
| 304 CreateAdaptersForTracks( |
| 305 webrtc_stream_->GetAudioTracks(), audio.get(), main_thread_); |
| 306 CreateAdaptersForTracks( |
| 307 webrtc_stream_->GetVideoTracks(), video.get(), main_thread_); |
| 308 |
| 309 main_thread_->PostTask(FROM_HERE, |
| 310 base::Bind(&RemoteMediaStreamImpl::Observer::OnChangedOnMainThread, |
| 311 this, base::Passed(&audio), base::Passed(&video))); |
| 312 } |
| 313 |
| 314 void RemoteMediaStreamImpl::Observer::OnChangedOnMainThread( |
| 315 scoped_ptr<RemoteAudioTrackAdapters> audio_tracks, |
| 316 scoped_ptr<RemoteVideoTrackAdapters> video_tracks) { |
| 317 DCHECK(main_thread_->BelongsToCurrentThread()); |
| 318 if (media_stream_) |
| 319 media_stream_->OnChanged(audio_tracks.Pass(), video_tracks.Pass()); |
| 320 } |
| 321 |
| 322 // Called on the signaling thread. |
153 RemoteMediaStreamImpl::RemoteMediaStreamImpl( | 323 RemoteMediaStreamImpl::RemoteMediaStreamImpl( |
| 324 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread, |
154 webrtc::MediaStreamInterface* webrtc_stream) | 325 webrtc::MediaStreamInterface* webrtc_stream) |
155 : webrtc_stream_(webrtc_stream) { | 326 : signaling_thread_(base::ThreadTaskRunnerHandle::Get()), |
156 webrtc_stream_->RegisterObserver(this); | 327 weak_factory_(this), |
| 328 observer_(new RemoteMediaStreamImpl::Observer(weak_factory_.GetWeakPtr(), |
| 329 main_thread, webrtc_stream)) { |
| 330 CreateAdaptersForTracks(webrtc_stream->GetAudioTracks(), |
| 331 &audio_track_observers_, main_thread); |
| 332 CreateAdaptersForTracks(webrtc_stream->GetVideoTracks(), |
| 333 &video_track_observers_, main_thread); |
157 | 334 |
158 webrtc::AudioTrackVector webrtc_audio_tracks = | 335 main_thread->PostTask(FROM_HERE, |
159 webrtc_stream_->GetAudioTracks(); | 336 base::Bind(&RemoteMediaStreamImpl::Observer::InitializeOnMainThread, |
160 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( | 337 observer_, webrtc_stream->label())); |
161 webrtc_audio_tracks.size()); | |
162 | |
163 // Initialize WebKit audio tracks. | |
164 size_t i = 0; | |
165 for (; i < webrtc_audio_tracks.size(); ++i) { | |
166 webrtc::AudioTrackInterface* audio_track = webrtc_audio_tracks[i]; | |
167 DCHECK(audio_track); | |
168 InitializeWebkitTrack(audio_track, &webkit_audio_tracks[i], | |
169 blink::WebMediaStreamSource::TypeAudio); | |
170 audio_track_observers_.push_back( | |
171 new RemoteAudioMediaStreamTrackAdapter(audio_track, | |
172 webkit_audio_tracks[i])); | |
173 } | |
174 | |
175 // Initialize WebKit video tracks. | |
176 webrtc::VideoTrackVector webrtc_video_tracks = | |
177 webrtc_stream_->GetVideoTracks(); | |
178 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( | |
179 webrtc_video_tracks.size()); | |
180 for (i = 0; i < webrtc_video_tracks.size(); ++i) { | |
181 webrtc::VideoTrackInterface* video_track = webrtc_video_tracks[i]; | |
182 DCHECK(video_track); | |
183 InitializeWebkitTrack(video_track, &webkit_video_tracks[i], | |
184 blink::WebMediaStreamSource::TypeVideo); | |
185 video_track_observers_.push_back( | |
186 new RemoteMediaStreamTrackAdapter(video_track, | |
187 webkit_video_tracks[i])); | |
188 } | |
189 | |
190 webkit_stream_.initialize(base::UTF8ToUTF16(webrtc_stream->label()), | |
191 webkit_audio_tracks, webkit_video_tracks); | |
192 webkit_stream_.setExtraData(new MediaStream(webrtc_stream)); | |
193 } | 338 } |
194 | 339 |
195 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { | 340 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { |
196 webrtc_stream_->UnregisterObserver(this); | 341 DCHECK(observer_->main_thread()->BelongsToCurrentThread()); |
197 } | 342 } |
198 | 343 |
199 void RemoteMediaStreamImpl::OnChanged() { | 344 void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label) { |
200 // Find removed audio tracks. | 345 DCHECK(observer_->main_thread()->BelongsToCurrentThread()); |
201 ScopedVector<RemoteMediaStreamTrackAdapter>::iterator audio_it = | 346 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( |
202 audio_track_observers_.begin(); | 347 audio_track_observers_.size()); |
| 348 for (size_t i = 0; i < audio_track_observers_.size(); ++i) { |
| 349 audio_track_observers_[i]->Initialize(); |
| 350 webkit_audio_tracks[i] = *audio_track_observers_[i]->webkit_track(); |
| 351 } |
| 352 |
| 353 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( |
| 354 video_track_observers_.size()); |
| 355 for (size_t i = 0; i < video_track_observers_.size(); ++i) { |
| 356 video_track_observers_[i]->Initialize(); |
| 357 webkit_video_tracks[i] = *video_track_observers_[i]->webkit_track(); |
| 358 } |
| 359 |
| 360 webkit_stream_.initialize(base::UTF8ToUTF16(label), |
| 361 webkit_audio_tracks, webkit_video_tracks); |
| 362 webkit_stream_.setExtraData(new MediaStream(observer_->stream().get())); |
| 363 } |
| 364 |
| 365 void RemoteMediaStreamImpl::OnChanged( |
| 366 scoped_ptr<RemoteAudioTrackAdapters> audio_tracks, |
| 367 scoped_ptr<RemoteVideoTrackAdapters> video_tracks) { |
| 368 // Find removed tracks. |
| 369 auto audio_it = audio_track_observers_.begin(); |
203 while (audio_it != audio_track_observers_.end()) { | 370 while (audio_it != audio_track_observers_.end()) { |
204 std::string track_id = (*audio_it)->observed_track()->id(); | 371 if (!IsTrackInVector(*audio_tracks.get(), (*audio_it)->id())) { |
205 if (webrtc_stream_->FindAudioTrack(track_id) == NULL) { | 372 webkit_stream_.removeTrack(*(*audio_it)->webkit_track()); |
206 webkit_stream_.removeTrack((*audio_it)->webkit_track()); | |
207 audio_it = audio_track_observers_.erase(audio_it); | 373 audio_it = audio_track_observers_.erase(audio_it); |
208 } else { | 374 } else { |
209 ++audio_it; | 375 ++audio_it; |
210 } | 376 } |
211 } | 377 } |
212 | 378 |
213 // Find removed video tracks. | 379 auto video_it = video_track_observers_.begin(); |
214 ScopedVector<RemoteMediaStreamTrackAdapter>::iterator video_it = | |
215 video_track_observers_.begin(); | |
216 while (video_it != video_track_observers_.end()) { | 380 while (video_it != video_track_observers_.end()) { |
217 std::string track_id = (*video_it)->observed_track()->id(); | 381 if (!IsTrackInVector(*video_tracks.get(), (*video_it)->id())) { |
218 if (webrtc_stream_->FindVideoTrack(track_id) == NULL) { | 382 webkit_stream_.removeTrack(*(*video_it)->webkit_track()); |
219 webkit_stream_.removeTrack((*video_it)->webkit_track()); | |
220 video_it = video_track_observers_.erase(video_it); | 383 video_it = video_track_observers_.erase(video_it); |
221 } else { | 384 } else { |
222 ++video_it; | 385 ++video_it; |
223 } | 386 } |
224 } | 387 } |
225 | 388 |
226 // Find added audio tracks. | 389 // Find added tracks. |
227 webrtc::AudioTrackVector webrtc_audio_tracks = | 390 for (const auto& track : *audio_tracks.get()) { |
228 webrtc_stream_->GetAudioTracks(); | 391 if (!IsTrackInVector(audio_track_observers_, track->id())) { |
229 for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin(); | 392 track->Initialize(); |
230 it != webrtc_audio_tracks.end(); ++it) { | 393 audio_track_observers_.push_back(track); |
231 if (!FindTrackObserver(*it, audio_track_observers_)) { | 394 webkit_stream_.addTrack(*track->webkit_track()); |
232 blink::WebMediaStreamTrack new_track; | |
233 InitializeWebkitTrack(*it, &new_track, | |
234 blink::WebMediaStreamSource::TypeAudio); | |
235 audio_track_observers_.push_back( | |
236 new RemoteAudioMediaStreamTrackAdapter(*it, new_track)); | |
237 webkit_stream_.addTrack(new_track); | |
238 } | 395 } |
239 } | 396 } |
240 | 397 |
241 // Find added video tracks. | 398 // Find added video tracks. |
242 webrtc::VideoTrackVector webrtc_video_tracks = | 399 for (const auto& track : *video_tracks.get()) { |
243 webrtc_stream_->GetVideoTracks(); | 400 if (!IsTrackInVector(video_track_observers_, track->id())) { |
244 for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin(); | 401 track->Initialize(); |
245 it != webrtc_video_tracks.end(); ++it) { | 402 video_track_observers_.push_back(track); |
246 if (!FindTrackObserver(*it, video_track_observers_)) { | 403 webkit_stream_.addTrack(*track->webkit_track()); |
247 blink::WebMediaStreamTrack new_track; | |
248 InitializeWebkitTrack(*it, &new_track, | |
249 blink::WebMediaStreamSource::TypeVideo); | |
250 video_track_observers_.push_back( | |
251 new RemoteMediaStreamTrackAdapter(*it, new_track)); | |
252 webkit_stream_.addTrack(new_track); | |
253 } | 404 } |
254 } | 405 } |
255 } | 406 } |
256 | 407 |
257 } // namespace content | 408 } // namespace content |
OLD | NEW |