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

Side by Side Diff: content/renderer/media/remote_media_stream_impl.cc

Issue 675013005: Split libjingle's signaling thread from the UI thread (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase Created 6 years, 1 month 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 <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::MediaStreamTrackInterface>& track,
perkj_chrome 2014/10/31 08:37:25 This can be webrtc::AudioTrackInterface instead of
tommi (sloooow) - chröme 2014/10/31 10:06:32 Done.
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 if (!track_.get())
58 return;
59
60 // Due to a discrepancy in libjingle, we have to post to the signaling
61 // thread. Usually we get a proxy object, but in the case of audio tracks,
62 // we get a direct pointer to the object.
perkj_chrome 2014/10/31 08:37:24 I don't think this is true for remote audio tracks
tommi (sloooow) - chröme 2014/10/31 10:06:32 Yes, you're right. The code is bit by bit becoming
63 signaling_thread_->PostTask(FROM_HERE, base::Bind(
64 base::IgnoreResult(&webrtc::MediaStreamTrackInterface::set_enabled),
65 track_, enabled));
66 }
67
68 void Stop() override {
69 // Stop means that a track should be stopped permanently. But
70 // since there is no proper way of doing that on a remote track, we can
71 // at least disable the track. Blink will not call down to the content layer
72 // after a track has been stopped.
73 SetEnabled(false);
74 }
75
76 webrtc::AudioTrackInterface* GetAudioAdapter() override {
perkj_chrome 2014/10/31 08:37:24 This method is really weird. I see its being used
tommi (sloooow) - chröme 2014/10/31 10:06:33 Yes, DTMFSender only works for local audio tracks.
perkj_chrome 2014/10/31 10:24:26 My point is, if this should never be used on remot
tommi (sloooow) - chröme 2014/10/31 13:20:41 Yes, you're right (and reading my comment I guess
77 // Since the object pointed to by |track_| is not a proxy object but
78 // actually a pointer to a single threaded object that lives on the
79 // signaling thread, we need to make sure we're on the right thread.
80 // However, today (Oct 2014), I'm not aware of any callers to this method
81 // for remote audio tracks.
82 DCHECK(signaling_thread_->BelongsToCurrentThread());
83 DCHECK_EQ(track_->kind(), "audio");
84 return static_cast<webrtc::AudioTrackInterface*>(track_.get());
85 }
86
87 private:
88 const scoped_refptr<webrtc::MediaStreamTrackInterface> track_;
89 const scoped_refptr<base::SingleThreadTaskRunner> signaling_thread_;
90 };
91
92 // Base class used for mapping between webrtc and blink MediaStream tracks.
93 // An instance of a RemoteMediaStreamAudioTrackAdapter is stored in
94 // RemoteMediaStreamImpl per remote audio and video track.
95 template<typename WebRtcMediaStreamTrackType>
96 class RemoteMediaStreamAudioTrackAdapter
perkj_chrome 2014/10/31 08:37:25 This looks like a search and replace error. You di
tommi (sloooow) - chröme 2014/10/31 10:06:33 Doh, thanks.
97 : public base::RefCountedThreadSafe<
98 RemoteMediaStreamAudioTrackAdapter<WebRtcMediaStreamTrackType>> {
99 public:
100 RemoteMediaStreamAudioTrackAdapter(
101 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
102 WebRtcMediaStreamTrackType* webrtc_track)
103 : main_thread_(main_thread), webrtc_track_(webrtc_track),
104 id_(webrtc_track->id()) {
105 }
106
107 const scoped_refptr<WebRtcMediaStreamTrackType>& observed_track() {
108 return webrtc_track_;
109 }
110
111 blink::WebMediaStreamTrack* webkit_track() {
112 DCHECK(main_thread_->BelongsToCurrentThread());
113 DCHECK(!webkit_track_.isNull());
114 return &webkit_track_;
115 }
116
117 const std::string& id() const { return id_; }
118
119 bool initialized() const {
120 DCHECK(main_thread_->BelongsToCurrentThread());
121 return !webkit_track_.isNull();
122 }
123
124 void Initialize() {
125 DCHECK(main_thread_->BelongsToCurrentThread());
126 DCHECK(!initialized());
127 webkit_initialize_.Run();
128 webkit_initialize_.Reset();
129 DCHECK(initialized());
130 }
131
132 protected:
133 friend class base::RefCountedThreadSafe<
134 RemoteMediaStreamAudioTrackAdapter<WebRtcMediaStreamTrackType>>;
135
136 virtual ~RemoteMediaStreamAudioTrackAdapter() {
137 DCHECK(main_thread_->BelongsToCurrentThread());
138 }
139
140 void InitializeWebkitTrack(blink::WebMediaStreamSource::Type type) {
141 DCHECK(main_thread_->BelongsToCurrentThread());
142 DCHECK(webkit_track_.isNull());
143
144 blink::WebString webkit_track_id(base::UTF8ToUTF16(id_));
145 blink::WebMediaStreamSource webkit_source;
146 webkit_source.initialize(webkit_track_id, type, webkit_track_id);
147 webkit_track_.initialize(webkit_track_id, webkit_source);
148 DCHECK(!webkit_track_.isNull());
149 }
150
151 const scoped_refptr<base::SingleThreadTaskRunner> main_thread_;
152 // This callback will be run when Initialize() is called and then freed.
153 // The callback is used by derived classes to bind objects that need to be
154 // instantiated and initialized on the signaling thread but then moved to
155 // and used on the main thread when initializing the webkit object(s).
156 base::Callback<void()> webkit_initialize_;
157
158 private:
159 const scoped_refptr<WebRtcMediaStreamTrackType> webrtc_track_;
160 blink::WebMediaStreamTrack webkit_track_;
161 // const copy of the webrtc track id that allows us to check it from both the
162 // main and signaling threads without incurring a synchronous thread hop.
163 const std::string id_;
164
165 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamAudioTrackAdapter);
166 };
167
168 class RemoteVideoTrackAdapter
169 : public RemoteMediaStreamAudioTrackAdapter<webrtc::VideoTrackInterface> {
perkj_chrome 2014/10/31 08:37:24 Weird name of baseclass...
tommi (sloooow) - chröme 2014/10/31 10:06:33 Acknowledged.
170 public:
171 // Called on the signaling thread
172 RemoteVideoTrackAdapter(
173 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
174 webrtc::VideoTrackInterface* webrtc_track)
175 : RemoteMediaStreamAudioTrackAdapter(main_thread, webrtc_track) {
176 scoped_refptr<MediaStreamRemoteVideoSource::Observer> source_observer(
177 new MediaStreamRemoteVideoSource::Observer(main_thread,
178 observed_track().get()));
179 webkit_initialize_ = base::Bind(
180 &RemoteVideoTrackAdapter::InitializeWebkitVideoTrack,
181 this, source_observer, observed_track()->enabled());
182 }
183
184 protected:
185 ~RemoteVideoTrackAdapter() override {}
186
187 private:
188 void InitializeWebkitVideoTrack(
189 const scoped_refptr<MediaStreamRemoteVideoSource::Observer>& observer,
190 bool enabled) {
191 DCHECK(main_thread_->BelongsToCurrentThread());
192 scoped_ptr<MediaStreamRemoteVideoSource> video_source(
193 new MediaStreamRemoteVideoSource(observer));
194 InitializeWebkitTrack(blink::WebMediaStreamSource::TypeVideo);
195 webkit_track()->source().setExtraData(video_source.get());
35 // Initial constraints must be provided to a MediaStreamVideoTrack. But 196 // Initial constraints must be provided to a MediaStreamVideoTrack. But
36 // no constraints are available initially on a remote video track. 197 // no constraints are available initially on a remote video track.
37 blink::WebMediaConstraints constraints; 198 blink::WebMediaConstraints constraints;
38 constraints.initialize(); 199 constraints.initialize();
39 webkit_track->setExtraData( 200 MediaStreamVideoTrack* media_stream_track =
40 new MediaStreamVideoTrack(video_source, constraints, 201 new MediaStreamVideoTrack(video_source.release(), constraints,
41 MediaStreamVideoSource::ConstraintsCallback(), 202 MediaStreamVideoSource::ConstraintsCallback(), enabled);
42 track->enabled())); 203 webkit_track()->setExtraData(media_stream_track);
43 } else { 204 }
44 DCHECK(type == blink::WebMediaStreamSource::TypeAudio); 205 };
45 content::PeerConnectionDependencyFactory::AddNativeAudioTrackToBlinkTrack( 206
46 track, *webkit_track, false); 207 // 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 208 // change notifications on a remote webrtc audio MediaStreamTracks and notify
93 // WebKit. 209 // WebKit.
94 class RemoteAudioMediaStreamTrackAdapter 210 class RemoteAudioTrackAdapter
95 : public RemoteMediaStreamTrackAdapter, 211 : public RemoteMediaStreamAudioTrackAdapter<webrtc::AudioTrackInterface>,
96 public webrtc::ObserverInterface, 212 public webrtc::ObserverInterface {
97 public base::NonThreadSafe { 213 public:
98 public: 214 RemoteAudioTrackAdapter(
99 RemoteAudioMediaStreamTrackAdapter( 215 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
100 webrtc::MediaStreamTrackInterface* webrtc_track, 216 webrtc::AudioTrackInterface* webrtc_track);
101 const blink::WebMediaStreamTrack& webkit_track); 217
102 ~RemoteAudioMediaStreamTrackAdapter() override; 218 protected:
103 219 ~RemoteAudioTrackAdapter() override;
104 private: 220
221 private:
222 void InitializeWebkitAudioTrack(
223 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track);
224
105 // webrtc::ObserverInterface implementation. 225 // webrtc::ObserverInterface implementation.
106 void OnChanged() override; 226 void OnChanged() override;
107 227
228 void OnChangedOnMainThread(
229 webrtc::MediaStreamTrackInterface::TrackState state);
230
108 webrtc::MediaStreamTrackInterface::TrackState state_; 231 webrtc::MediaStreamTrackInterface::TrackState state_;
109 232
110 DISALLOW_COPY_AND_ASSIGN(RemoteAudioMediaStreamTrackAdapter); 233 DISALLOW_COPY_AND_ASSIGN(RemoteAudioTrackAdapter);
111 }; 234 };
112 235
113 RemoteAudioMediaStreamTrackAdapter::RemoteAudioMediaStreamTrackAdapter( 236 // Called on the signaling thread.
114 webrtc::MediaStreamTrackInterface* webrtc_track, 237 RemoteAudioTrackAdapter::RemoteAudioTrackAdapter(
115 const blink::WebMediaStreamTrack& webkit_track) 238 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
116 : RemoteMediaStreamTrackAdapter(webrtc_track, webkit_track), 239 webrtc::AudioTrackInterface* webrtc_track)
240 : RemoteMediaStreamAudioTrackAdapter(main_thread, webrtc_track),
117 state_(observed_track()->state()) { 241 state_(observed_track()->state()) {
118 observed_track()->RegisterObserver(this); 242 observed_track()->RegisterObserver(this);
119 } 243 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track(
120 244 new RemoteMediaStreamAudioTrack(observed_track().get(),
121 RemoteAudioMediaStreamTrackAdapter::~RemoteAudioMediaStreamTrackAdapter() { 245 base::ThreadTaskRunnerHandle::Get()));
246 webkit_initialize_ = base::Bind(
247 &RemoteAudioTrackAdapter::InitializeWebkitAudioTrack,
248 this, base::Passed(&media_stream_track));
249 }
250
251 RemoteAudioTrackAdapter::~RemoteAudioTrackAdapter() {
122 observed_track()->UnregisterObserver(this); 252 observed_track()->UnregisterObserver(this);
123 } 253 }
124 254
125 void RemoteAudioMediaStreamTrackAdapter::OnChanged() { 255 void RemoteAudioTrackAdapter::InitializeWebkitAudioTrack(
126 DCHECK(CalledOnValidThread()); 256 scoped_ptr<RemoteMediaStreamAudioTrack> media_stream_track) {
127 257 InitializeWebkitTrack(blink::WebMediaStreamSource::TypeAudio);
128 webrtc::MediaStreamTrackInterface::TrackState state = 258 webkit_track()->setExtraData(media_stream_track.release());
129 observed_track()->state(); 259 }
130 if (state == state_) 260
261 void RemoteAudioTrackAdapter::OnChanged() {
262 main_thread_->PostTask(FROM_HERE,
263 base::Bind(&RemoteAudioTrackAdapter::OnChangedOnMainThread,
264 this, observed_track()->state()));
265 }
266
267 void RemoteAudioTrackAdapter::OnChangedOnMainThread(
268 webrtc::MediaStreamTrackInterface::TrackState state) {
269 DCHECK(main_thread_->BelongsToCurrentThread());
270
271 if (state == state_ || !initialized())
131 return; 272 return;
132 273
133 state_ = state; 274 state_ = state;
275
134 switch (state) { 276 switch (state) {
135 case webrtc::MediaStreamTrackInterface::kInitializing: 277 case webrtc::MediaStreamTrackInterface::kInitializing:
136 // Ignore the kInitializing state since there is no match in 278 // Ignore the kInitializing state since there is no match in
137 // WebMediaStreamSource::ReadyState. 279 // WebMediaStreamSource::ReadyState.
138 break; 280 break;
139 case webrtc::MediaStreamTrackInterface::kLive: 281 case webrtc::MediaStreamTrackInterface::kLive:
140 webkit_track().source().setReadyState( 282 webkit_track()->source().setReadyState(
141 blink::WebMediaStreamSource::ReadyStateLive); 283 blink::WebMediaStreamSource::ReadyStateLive);
142 break; 284 break;
143 case webrtc::MediaStreamTrackInterface::kEnded: 285 case webrtc::MediaStreamTrackInterface::kEnded:
144 webkit_track().source().setReadyState( 286 webkit_track()->source().setReadyState(
145 blink::WebMediaStreamSource::ReadyStateEnded); 287 blink::WebMediaStreamSource::ReadyStateEnded);
146 break; 288 break;
147 default: 289 default:
148 NOTREACHED(); 290 NOTREACHED();
149 break; 291 break;
150 } 292 }
151 } 293 }
152 294
295 // Called on the signaling thread.
153 RemoteMediaStreamImpl::RemoteMediaStreamImpl( 296 RemoteMediaStreamImpl::RemoteMediaStreamImpl(
297 const scoped_refptr<base::SingleThreadTaskRunner>& main_thread,
154 webrtc::MediaStreamInterface* webrtc_stream) 298 webrtc::MediaStreamInterface* webrtc_stream)
155 : webrtc_stream_(webrtc_stream) { 299 : main_thread_(main_thread),
300 signaling_thread_(base::ThreadTaskRunnerHandle::Get()),
301 webrtc_stream_(webrtc_stream) {
156 webrtc_stream_->RegisterObserver(this); 302 webrtc_stream_->RegisterObserver(this);
157 303
158 webrtc::AudioTrackVector webrtc_audio_tracks = 304 CreateAdaptersForTracks(webrtc_stream_->GetAudioTracks(),
159 webrtc_stream_->GetAudioTracks(); 305 &audio_track_observers_, main_thread);
160 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( 306 CreateAdaptersForTracks(webrtc_stream_->GetVideoTracks(),
161 webrtc_audio_tracks.size()); 307 &video_track_observers_, main_thread);
162 308
163 // Initialize WebKit audio tracks. 309 main_thread_->PostTask(FROM_HERE,
164 size_t i = 0; 310 base::Bind(&RemoteMediaStreamImpl::InitializeOnMainThread,
165 for (; i < webrtc_audio_tracks.size(); ++i) { 311 base::Unretained(this), webrtc_stream_->label()));
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 } 312 }
194 313
195 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { 314 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
315 DCHECK(main_thread_->BelongsToCurrentThread());
196 webrtc_stream_->UnregisterObserver(this); 316 webrtc_stream_->UnregisterObserver(this);
197 } 317 }
198 318
319 void RemoteMediaStreamImpl::InitializeOnMainThread(const std::string& label) {
320 DCHECK(main_thread_->BelongsToCurrentThread());
321 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks(
322 audio_track_observers_.size());
323 for (size_t i = 0; i < audio_track_observers_.size(); ++i) {
324 audio_track_observers_[i]->Initialize();
325 webkit_audio_tracks[i] = *audio_track_observers_[i]->webkit_track();
326 }
327
328 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks(
329 video_track_observers_.size());
330 for (size_t i = 0; i < video_track_observers_.size(); ++i) {
331 video_track_observers_[i]->Initialize();
332 webkit_video_tracks[i] = *video_track_observers_[i]->webkit_track();
333 }
334
335 webkit_stream_.initialize(base::UTF8ToUTF16(label),
336 webkit_audio_tracks, webkit_video_tracks);
337 webkit_stream_.setExtraData(new MediaStream(webrtc_stream_.get()));
338 }
339
199 void RemoteMediaStreamImpl::OnChanged() { 340 void RemoteMediaStreamImpl::OnChanged() {
200 // Find removed audio tracks. 341 scoped_ptr<RemoteAudioTrackAdapters> audio(new RemoteAudioTrackAdapters());
201 ScopedVector<RemoteMediaStreamTrackAdapter>::iterator audio_it = 342 scoped_ptr<RemoteVideoTrackAdapters> video(new RemoteVideoTrackAdapters());
202 audio_track_observers_.begin(); 343
344 CreateAdaptersForTracks(
345 webrtc_stream_->GetAudioTracks(), audio.get(), main_thread_);
346 CreateAdaptersForTracks(
347 webrtc_stream_->GetVideoTracks(), video.get(), main_thread_);
348
349 // TODO(tommi): Unretained safe?
perkj_chrome 2014/10/31 08:37:24 We must figure that out. OnChanged here is called
tommi (sloooow) - chröme 2014/10/31 10:06:32 I'll implement an observer pattern like I did else
350 main_thread_->PostTask(FROM_HERE,
351 base::Bind(&RemoteMediaStreamImpl::OnChangedOnMainThread,
352 base::Unretained(this), base::Passed(&audio), base::Passed(&video)));
353 }
354
355 void RemoteMediaStreamImpl::OnChangedOnMainThread(
356 scoped_ptr<RemoteAudioTrackAdapters> audio_tracks,
357 scoped_ptr<RemoteVideoTrackAdapters> video_tracks) {
358 // Find removed tracks.
359 auto audio_it = audio_track_observers_.begin();
203 while (audio_it != audio_track_observers_.end()) { 360 while (audio_it != audio_track_observers_.end()) {
204 std::string track_id = (*audio_it)->observed_track()->id(); 361 if (!IsTrackInVector(*audio_tracks.get(), (*audio_it)->id())) {
205 if (webrtc_stream_->FindAudioTrack(track_id) == NULL) { 362 webkit_stream_.removeTrack(*(*audio_it)->webkit_track());
206 webkit_stream_.removeTrack((*audio_it)->webkit_track());
207 audio_it = audio_track_observers_.erase(audio_it); 363 audio_it = audio_track_observers_.erase(audio_it);
208 } else { 364 } else {
209 ++audio_it; 365 ++audio_it;
210 } 366 }
211 } 367 }
212 368
213 // Find removed video tracks. 369 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()) { 370 while (video_it != video_track_observers_.end()) {
217 std::string track_id = (*video_it)->observed_track()->id(); 371 if (!IsTrackInVector(*video_tracks.get(), (*video_it)->id())) {
218 if (webrtc_stream_->FindVideoTrack(track_id) == NULL) { 372 webkit_stream_.removeTrack(*(*video_it)->webkit_track());
219 webkit_stream_.removeTrack((*video_it)->webkit_track());
220 video_it = video_track_observers_.erase(video_it); 373 video_it = video_track_observers_.erase(video_it);
221 } else { 374 } else {
222 ++video_it; 375 ++video_it;
223 } 376 }
224 } 377 }
225 378
226 // Find added audio tracks. 379 // Find added tracks.
227 webrtc::AudioTrackVector webrtc_audio_tracks = 380 for (const auto& track : *audio_tracks.get()) {
228 webrtc_stream_->GetAudioTracks(); 381 if (!IsTrackInVector(audio_track_observers_, track->id())) {
229 for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin(); 382 track->Initialize();
230 it != webrtc_audio_tracks.end(); ++it) { 383 audio_track_observers_.push_back(track);
231 if (!FindTrackObserver(*it, audio_track_observers_)) { 384 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 } 385 }
239 } 386 }
240 387
241 // Find added video tracks. 388 // Find added video tracks.
242 webrtc::VideoTrackVector webrtc_video_tracks = 389 for (const auto& track : *video_tracks.get()) {
243 webrtc_stream_->GetVideoTracks(); 390 if (!IsTrackInVector(video_track_observers_, track->id())) {
244 for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin(); 391 track->Initialize();
245 it != webrtc_video_tracks.end(); ++it) { 392 video_track_observers_.push_back(track);
246 if (!FindTrackObserver(*it, video_track_observers_)) { 393 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 } 394 }
254 } 395 }
255 } 396 }
256 397
257 } // namespace content 398 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698