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

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

Issue 201583003: Implement a source for remote video tracks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 | Annotate | Revision Log
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/logging.h" 9 #include "base/logging.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
11 #include "content/common/media/media_stream_track_metrics_host_messages.h" 11 #include "content/common/media/media_stream_track_metrics_host_messages.h"
12 #include "content/renderer/media/media_stream.h" 12 #include "content/renderer/media/media_stream.h"
13 #include "content/renderer/media/media_stream_dependency_factory.h" 13 #include "content/renderer/media/media_stream_dependency_factory.h"
14 #include "content/renderer/media/media_stream_video_track.h"
15 #include "content/renderer/media/webrtc/media_stream_remote_video_source.h"
14 #include "content/renderer/render_thread_impl.h" 16 #include "content/renderer/render_thread_impl.h"
15 #include "third_party/WebKit/public/platform/WebString.h" 17 #include "third_party/WebKit/public/platform/WebString.h"
16 18
17 namespace content { 19 namespace content {
18 20
19 // RemoteMediaStreamTrackObserver is responsible for listening on change 21 namespace {
20 // notification on a remote webrtc MediaStreamTrack and notify WebKit.
21 class RemoteMediaStreamTrackObserver
22 : NON_EXPORTED_BASE(public webrtc::ObserverInterface),
23 NON_EXPORTED_BASE(public base::NonThreadSafe) {
24 public:
25 RemoteMediaStreamTrackObserver(
26 webrtc::MediaStreamTrackInterface* webrtc_track,
27 const blink::WebMediaStreamTrack& webkit_track);
28 virtual ~RemoteMediaStreamTrackObserver();
29
30 webrtc::MediaStreamTrackInterface* observered_track() {
31 return webrtc_track_.get();
32 }
33 const blink::WebMediaStreamTrack& webkit_track() { return webkit_track_; }
34
35 private:
36 // webrtc::ObserverInterface implementation.
37 virtual void OnChanged() OVERRIDE;
38
39 // May be overridden by unit tests to avoid sending IPC messages.
40 virtual void SendLifetimeMessage(bool creation);
41
42 webrtc::MediaStreamTrackInterface::TrackState state_;
43 scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_;
44 blink::WebMediaStreamTrack webkit_track_;
45 bool sent_ended_message_;
46
47 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackObserver);
48 };
49 22
50 // We need an ID that is unique for this observer, within the current 23 // We need an ID that is unique for this observer, within the current
51 // renderer process, for the lifetime of the observer object. The 24 // renderer process, for the lifetime of the observer object. The
52 // simplest approach is to just use the object's pointer value. We 25 // simplest approach is to just use the object's pointer value. We
53 // store it in a uint64 which will be large enough regardless of 26 // store it in a uint64 which will be large enough regardless of
54 // platform. 27 // platform.
55 uint64 MakeUniqueId(RemoteMediaStreamTrackObserver* observer) { 28 uint64 MakeUniqueId(RemoteMediaStreamTrackAdapter* observer) {
56 return reinterpret_cast<uint64>(reinterpret_cast<void*>(observer)); 29 return reinterpret_cast<uint64>(reinterpret_cast<void*>(observer));
57 } 30 }
58 31
59 } // namespace content
60
61 namespace {
62
63 void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track, 32 void InitializeWebkitTrack(webrtc::MediaStreamTrackInterface* track,
64 blink::WebMediaStreamTrack* webkit_track, 33 blink::WebMediaStreamTrack* webkit_track,
65 blink::WebMediaStreamSource::Type type) { 34 blink::WebMediaStreamSource::Type type) {
66 blink::WebMediaStreamSource webkit_source; 35 blink::WebMediaStreamSource webkit_source;
67 blink::WebString webkit_track_id(base::UTF8ToUTF16(track->id())); 36 blink::WebString webkit_track_id(base::UTF8ToUTF16(track->id()));
68 37
69 webkit_source.initialize(webkit_track_id, type, webkit_track_id); 38 webkit_source.initialize(webkit_track_id, type, webkit_track_id);
70 webkit_track->initialize(webkit_track_id, webkit_source); 39 webkit_track->initialize(webkit_track_id, webkit_source);
71 content::MediaStreamDependencyFactory::AddNativeTrackToBlinkTrack( 40
72 track, *webkit_track, false); 41 MediaStreamDependencyFactory* factory = NULL;
42 // RenderThreadImpl::current() may be NULL in unit tests.
43 RenderThreadImpl* render_thread = RenderThreadImpl::current();
44 if (render_thread)
45 factory = render_thread->GetMediaStreamDependencyFactory();
46
47 if (type == blink::WebMediaStreamSource::TypeVideo) {
48 MediaStreamRemoteVideoSource* video_source =
49 new MediaStreamRemoteVideoSource(
50 static_cast<webrtc::VideoTrackInterface*>(track));
51 webkit_source.setExtraData(video_source);
52 // Initial constraints must be provided to a MediaStreamVideoTrack. But
53 // no constraints are available initially on a remote video track.
54 blink::WebMediaConstraints constraints;
55 constraints.initialize();
56 webkit_track->setExtraData(
57 new MediaStreamVideoTrack(video_source, constraints,
58 MediaStreamVideoSource::ConstraintsCallback(),
59 track->enabled(), factory));
60 } else {
61 DCHECK(type == blink::WebMediaStreamSource::TypeAudio);
62 content::MediaStreamDependencyFactory::AddNativeTrackToBlinkTrack(
63 track, *webkit_track, false);
64 }
73 } 65 }
74 66
75 content::RemoteMediaStreamTrackObserver* FindTrackObserver( 67 } // namespace
76 webrtc::MediaStreamTrackInterface* track, 68
77 const ScopedVector<content::RemoteMediaStreamTrackObserver>& observers) { 69 // Base class used for mapping between webrtc and blink MediaStream tracks.
78 ScopedVector<content::RemoteMediaStreamTrackObserver>::const_iterator it = 70 // An instance of a RemoteMediaStreamTrackAdapter is stored in
71 // RemoteMediaStreamImpl per remote audio and video track.
72 class RemoteMediaStreamTrackAdapter {
73 public:
74 RemoteMediaStreamTrackAdapter(webrtc::MediaStreamTrackInterface* webrtc_track,
Ronghua Wu (Left Chromium) 2014/03/17 22:45:35 should this be called native_track? webrtc is too
perkj_chrome 2014/03/19 16:34:48 I did a code search and it seems we have been fair
Ronghua Wu (Left Chromium) 2014/03/20 21:55:50 In that case keep it as it's then.
75 const blink::WebMediaStreamTrack& webkit_track)
76 : webrtc_track_(webrtc_track),
77 webkit_track_(webkit_track) {
78 SendLifetimeMessage(true);
79 }
80
81 virtual ~RemoteMediaStreamTrackAdapter() {
82 // We send the lifetime-ended message here (it will only get sent if
83 // not previously sent) in case we never received a kEnded state
84 // change.
85 SendLifetimeMessage(false);
86 }
87
88 webrtc::MediaStreamTrackInterface* observed_track() {
89 return webrtc_track_.get();
90 }
91
92 const blink::WebMediaStreamTrack& webkit_track() { return webkit_track_; }
93
94 protected:
95 virtual void SendLifetimeMessage(bool creation) {
96 // We need to mirror the lifetime state for tracks to the browser
97 // process so that the duration of tracks can be accurately
98 // reported, because of RenderProcessHost::FastShutdownIfPossible,
99 // which in many cases will simply kill the renderer process.
100 //
101 // RenderThreadImpl::current() may be NULL in unit tests.
102 RenderThreadImpl* render_thread = RenderThreadImpl::current();
103 if (render_thread) {
104 if (creation) {
105 RenderThreadImpl::current()->Send(
106 new MediaStreamTrackMetricsHost_AddTrack(
107 MakeUniqueId(this),
108 webkit_track_.source().type() ==
109 blink::WebMediaStreamSource::TypeAudio,
110 true));
111 } else {
112 if (!sent_ended_message_) {
113 sent_ended_message_ = true;
114 RenderThreadImpl::current()->Send(
115 new MediaStreamTrackMetricsHost_RemoveTrack(MakeUniqueId(this)));
116 }
117 }
118 }
119 }
120
121 private:
122 scoped_refptr<webrtc::MediaStreamTrackInterface> webrtc_track_;
123 blink::WebMediaStreamTrack webkit_track_;
124 bool sent_ended_message_;
125
126 DISALLOW_COPY_AND_ASSIGN(RemoteMediaStreamTrackAdapter);
127 };
128
129 static content::RemoteMediaStreamTrackAdapter* FindTrackObserver(
130 webrtc::MediaStreamTrackInterface* track,
131 const ScopedVector<content::RemoteMediaStreamTrackAdapter>& observers) {
132 ScopedVector<content::RemoteMediaStreamTrackAdapter>::const_iterator it =
79 observers.begin(); 133 observers.begin();
80 for (; it != observers.end(); ++it) { 134 for (; it != observers.end(); ++it) {
81 if ((*it)->observered_track() == track) 135 if ((*it)->observed_track() == track)
82 return *it; 136 return *it;
83 } 137 }
84 return NULL; 138 return NULL;
85 } 139 }
86 140
87 } // namespace anonymous 141 // RemoteAudioMediaStreamTrackAdapter is responsible for listening on state
142 // change notifications on a remote webrtc audio MediaStreamTracks and notify
143 // WebKit.
144 class RemoteAudioMediaStreamTrackAdapter
145 : public RemoteMediaStreamTrackAdapter,
146 public webrtc::ObserverInterface,
147 public base::NonThreadSafe {
148 public:
149 RemoteAudioMediaStreamTrackAdapter(
150 webrtc::MediaStreamTrackInterface* webrtc_track,
151 const blink::WebMediaStreamTrack& webkit_track);
152 virtual ~RemoteAudioMediaStreamTrackAdapter();
88 153
89 namespace content { 154 private:
155 // webrtc::ObserverInterface implementation.
156 virtual void OnChanged() OVERRIDE;
90 157
91 RemoteMediaStreamTrackObserver::RemoteMediaStreamTrackObserver( 158 webrtc::MediaStreamTrackInterface::TrackState state_;
159
160 DISALLOW_COPY_AND_ASSIGN(RemoteAudioMediaStreamTrackAdapter);
161 };
162
163 RemoteAudioMediaStreamTrackAdapter::RemoteAudioMediaStreamTrackAdapter(
92 webrtc::MediaStreamTrackInterface* webrtc_track, 164 webrtc::MediaStreamTrackInterface* webrtc_track,
93 const blink::WebMediaStreamTrack& webkit_track) 165 const blink::WebMediaStreamTrack& webkit_track)
94 : state_(webrtc_track->state()), 166 : RemoteMediaStreamTrackAdapter(webrtc_track, webkit_track),
95 webrtc_track_(webrtc_track), 167 state_(observed_track()->state()) {
96 webkit_track_(webkit_track), 168 observed_track()->RegisterObserver(this);
97 sent_ended_message_(false) {
98 webrtc_track->RegisterObserver(this);
99
100 SendLifetimeMessage(true);
101 } 169 }
102 170
103 RemoteMediaStreamTrackObserver::~RemoteMediaStreamTrackObserver() { 171 RemoteAudioMediaStreamTrackAdapter::~RemoteAudioMediaStreamTrackAdapter() {
104 // We send the lifetime-ended message here (it will only get sent if 172 observed_track()->UnregisterObserver(this);
105 // not previously sent) in case we never received a kEnded state
106 // change.
107 SendLifetimeMessage(false);
108
109 webrtc_track_->UnregisterObserver(this);
110 } 173 }
111 174
112 void RemoteMediaStreamTrackObserver::OnChanged() { 175 void RemoteAudioMediaStreamTrackAdapter::OnChanged() {
113 DCHECK(CalledOnValidThread()); 176 DCHECK(CalledOnValidThread());
114 177
115 webrtc::MediaStreamTrackInterface::TrackState state = webrtc_track_->state(); 178 webrtc::MediaStreamTrackInterface::TrackState state =
179 observed_track()->state();
116 if (state == state_) 180 if (state == state_)
117 return; 181 return;
118 182
119 state_ = state; 183 state_ = state;
120 switch (state) { 184 switch (state) {
121 case webrtc::MediaStreamTrackInterface::kInitializing: 185 case webrtc::MediaStreamTrackInterface::kInitializing:
122 // Ignore the kInitializing state since there is no match in 186 // Ignore the kInitializing state since there is no match in
123 // WebMediaStreamSource::ReadyState. 187 // WebMediaStreamSource::ReadyState.
124 break; 188 break;
125 case webrtc::MediaStreamTrackInterface::kLive: 189 case webrtc::MediaStreamTrackInterface::kLive:
126 webkit_track_.source().setReadyState( 190 webkit_track().source().setReadyState(
127 blink::WebMediaStreamSource::ReadyStateLive); 191 blink::WebMediaStreamSource::ReadyStateLive);
128 break; 192 break;
129 case webrtc::MediaStreamTrackInterface::kEnded: 193 case webrtc::MediaStreamTrackInterface::kEnded:
130 // This is a more reliable signal to use for duration, as 194 // This is a more reliable signal to use for duration, as
131 // destruction of this object might not happen until 195 // destruction of this object might not happen until
132 // considerably later. 196 // considerably later.
133 SendLifetimeMessage(false); 197 SendLifetimeMessage(false);
134 webkit_track_.source().setReadyState( 198 webkit_track().source().setReadyState(
135 blink::WebMediaStreamSource::ReadyStateEnded); 199 blink::WebMediaStreamSource::ReadyStateEnded);
136 break; 200 break;
137 default: 201 default:
138 NOTREACHED(); 202 NOTREACHED();
139 break; 203 break;
140 } 204 }
141 } 205 }
142 206
143 void RemoteMediaStreamTrackObserver::SendLifetimeMessage(bool creation) {
144 // We need to mirror the lifetime state for tracks to the browser
145 // process so that the duration of tracks can be accurately
146 // reported, because of RenderProcessHost::FastShutdownIfPossible,
147 // which in many cases will simply kill the renderer process.
148 //
149 // RenderThreadImpl::current() may be NULL in unit tests.
150 RenderThreadImpl* render_thread = RenderThreadImpl::current();
151 if (render_thread) {
152 if (creation) {
153 RenderThreadImpl::current()->Send(
154 new MediaStreamTrackMetricsHost_AddTrack(
155 MakeUniqueId(this),
156 webkit_track_.source().type() ==
157 blink::WebMediaStreamSource::TypeAudio,
158 true));
159 } else {
160 if (!sent_ended_message_) {
161 sent_ended_message_ = true;
162 RenderThreadImpl::current()->Send(
163 new MediaStreamTrackMetricsHost_RemoveTrack(MakeUniqueId(this)));
164 }
165 }
166 }
167 }
168
169 RemoteMediaStreamImpl::RemoteMediaStreamImpl( 207 RemoteMediaStreamImpl::RemoteMediaStreamImpl(
170 webrtc::MediaStreamInterface* webrtc_stream) 208 webrtc::MediaStreamInterface* webrtc_stream)
171 : webrtc_stream_(webrtc_stream) { 209 : webrtc_stream_(webrtc_stream) {
172 webrtc_stream_->RegisterObserver(this); 210 webrtc_stream_->RegisterObserver(this);
173 211
174 webrtc::AudioTrackVector webrtc_audio_tracks = 212 webrtc::AudioTrackVector webrtc_audio_tracks =
175 webrtc_stream_->GetAudioTracks(); 213 webrtc_stream_->GetAudioTracks();
176 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks( 214 blink::WebVector<blink::WebMediaStreamTrack> webkit_audio_tracks(
177 webrtc_audio_tracks.size()); 215 webrtc_audio_tracks.size());
178 216
179 // Initialize WebKit audio tracks. 217 // Initialize WebKit audio tracks.
180 size_t i = 0; 218 size_t i = 0;
181 for (; i < webrtc_audio_tracks.size(); ++i) { 219 for (; i < webrtc_audio_tracks.size(); ++i) {
182 webrtc::AudioTrackInterface* audio_track = webrtc_audio_tracks[i]; 220 webrtc::AudioTrackInterface* audio_track = webrtc_audio_tracks[i];
183 DCHECK(audio_track); 221 DCHECK(audio_track);
184 InitializeWebkitTrack(audio_track, &webkit_audio_tracks[i], 222 InitializeWebkitTrack(audio_track, &webkit_audio_tracks[i],
185 blink::WebMediaStreamSource::TypeAudio); 223 blink::WebMediaStreamSource::TypeAudio);
186 audio_track_observers_.push_back( 224 audio_track_observers_.push_back(
187 new RemoteMediaStreamTrackObserver(audio_track, 225 new RemoteAudioMediaStreamTrackAdapter(audio_track,
188 webkit_audio_tracks[i])); 226 webkit_audio_tracks[i]));
189 } 227 }
190 228
191 // Initialize WebKit video tracks. 229 // Initialize WebKit video tracks.
192 webrtc::VideoTrackVector webrtc_video_tracks = 230 webrtc::VideoTrackVector webrtc_video_tracks =
193 webrtc_stream_->GetVideoTracks(); 231 webrtc_stream_->GetVideoTracks();
194 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks( 232 blink::WebVector<blink::WebMediaStreamTrack> webkit_video_tracks(
195 webrtc_video_tracks.size()); 233 webrtc_video_tracks.size());
196 for (i = 0; i < webrtc_video_tracks.size(); ++i) { 234 for (i = 0; i < webrtc_video_tracks.size(); ++i) {
197 webrtc::VideoTrackInterface* video_track = webrtc_video_tracks[i]; 235 webrtc::VideoTrackInterface* video_track = webrtc_video_tracks[i];
198 DCHECK(video_track); 236 DCHECK(video_track);
199 InitializeWebkitTrack(video_track, &webkit_video_tracks[i], 237 InitializeWebkitTrack(video_track, &webkit_video_tracks[i],
200 blink::WebMediaStreamSource::TypeVideo); 238 blink::WebMediaStreamSource::TypeVideo);
201 video_track_observers_.push_back( 239 video_track_observers_.push_back(
202 new RemoteMediaStreamTrackObserver(video_track, 240 new RemoteMediaStreamTrackAdapter(video_track,
203 webkit_video_tracks[i])); 241 webkit_video_tracks[i]));
204 } 242 }
205 243
206 webkit_stream_.initialize(base::UTF8ToUTF16(webrtc_stream->label()), 244 webkit_stream_.initialize(base::UTF8ToUTF16(webrtc_stream->label()),
207 webkit_audio_tracks, webkit_video_tracks); 245 webkit_audio_tracks, webkit_video_tracks);
208 webkit_stream_.setExtraData(new MediaStream(webrtc_stream)); 246 webkit_stream_.setExtraData(new MediaStream(webrtc_stream));
209 } 247 }
210 248
211 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() { 249 RemoteMediaStreamImpl::~RemoteMediaStreamImpl() {
212 webrtc_stream_->UnregisterObserver(this); 250 webrtc_stream_->UnregisterObserver(this);
213 } 251 }
214 252
215 void RemoteMediaStreamImpl::OnChanged() { 253 void RemoteMediaStreamImpl::OnChanged() {
216 // Find removed audio tracks. 254 // Find removed audio tracks.
217 ScopedVector<RemoteMediaStreamTrackObserver>::iterator audio_it = 255 ScopedVector<RemoteMediaStreamTrackAdapter>::iterator audio_it =
218 audio_track_observers_.begin(); 256 audio_track_observers_.begin();
219 while (audio_it != audio_track_observers_.end()) { 257 while (audio_it != audio_track_observers_.end()) {
220 std::string track_id = (*audio_it)->observered_track()->id(); 258 std::string track_id = (*audio_it)->observed_track()->id();
221 if (webrtc_stream_->FindAudioTrack(track_id) == NULL) { 259 if (webrtc_stream_->FindAudioTrack(track_id) == NULL) {
222 webkit_stream_.removeTrack((*audio_it)->webkit_track()); 260 webkit_stream_.removeTrack((*audio_it)->webkit_track());
223 audio_it = audio_track_observers_.erase(audio_it); 261 audio_it = audio_track_observers_.erase(audio_it);
224 } else { 262 } else {
225 ++audio_it; 263 ++audio_it;
226 } 264 }
227 } 265 }
228 266
229 // Find removed video tracks. 267 // Find removed video tracks.
230 ScopedVector<RemoteMediaStreamTrackObserver>::iterator video_it = 268 ScopedVector<RemoteMediaStreamTrackAdapter>::iterator video_it =
231 video_track_observers_.begin(); 269 video_track_observers_.begin();
232 while (video_it != video_track_observers_.end()) { 270 while (video_it != video_track_observers_.end()) {
233 std::string track_id = (*video_it)->observered_track()->id(); 271 std::string track_id = (*video_it)->observed_track()->id();
234 if (webrtc_stream_->FindVideoTrack(track_id) == NULL) { 272 if (webrtc_stream_->FindVideoTrack(track_id) == NULL) {
235 webkit_stream_.removeTrack((*video_it)->webkit_track()); 273 webkit_stream_.removeTrack((*video_it)->webkit_track());
236 video_it = video_track_observers_.erase(video_it); 274 video_it = video_track_observers_.erase(video_it);
237 } else { 275 } else {
238 ++video_it; 276 ++video_it;
239 } 277 }
240 } 278 }
241 279
242 // Find added audio tracks. 280 // Find added audio tracks.
243 webrtc::AudioTrackVector webrtc_audio_tracks = 281 webrtc::AudioTrackVector webrtc_audio_tracks =
244 webrtc_stream_->GetAudioTracks(); 282 webrtc_stream_->GetAudioTracks();
245 for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin(); 283 for (webrtc::AudioTrackVector::iterator it = webrtc_audio_tracks.begin();
246 it != webrtc_audio_tracks.end(); ++it) { 284 it != webrtc_audio_tracks.end(); ++it) {
247 if (!FindTrackObserver(*it, audio_track_observers_)) { 285 if (!FindTrackObserver(*it, audio_track_observers_)) {
248 blink::WebMediaStreamTrack new_track; 286 blink::WebMediaStreamTrack new_track;
249 InitializeWebkitTrack(*it, &new_track, 287 InitializeWebkitTrack(*it, &new_track,
250 blink::WebMediaStreamSource::TypeAudio); 288 blink::WebMediaStreamSource::TypeAudio);
251 audio_track_observers_.push_back( 289 audio_track_observers_.push_back(
252 new RemoteMediaStreamTrackObserver(*it, new_track)); 290 new RemoteAudioMediaStreamTrackAdapter(*it, new_track));
253 webkit_stream_.addTrack(new_track); 291 webkit_stream_.addTrack(new_track);
254 } 292 }
255 } 293 }
256 294
257 // Find added video tracks. 295 // Find added video tracks.
258 webrtc::VideoTrackVector webrtc_video_tracks = 296 webrtc::VideoTrackVector webrtc_video_tracks =
259 webrtc_stream_->GetVideoTracks(); 297 webrtc_stream_->GetVideoTracks();
260 for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin(); 298 for (webrtc::VideoTrackVector::iterator it = webrtc_video_tracks.begin();
261 it != webrtc_video_tracks.end(); ++it) { 299 it != webrtc_video_tracks.end(); ++it) {
262 if (!FindTrackObserver(*it, video_track_observers_)) { 300 if (!FindTrackObserver(*it, video_track_observers_)) {
263 blink::WebMediaStreamTrack new_track; 301 blink::WebMediaStreamTrack new_track;
264 InitializeWebkitTrack(*it, &new_track, 302 InitializeWebkitTrack(*it, &new_track,
265 blink::WebMediaStreamSource::TypeVideo); 303 blink::WebMediaStreamSource::TypeVideo);
266 video_track_observers_.push_back( 304 video_track_observers_.push_back(
267 new RemoteMediaStreamTrackObserver(*it, new_track)); 305 new RemoteMediaStreamTrackAdapter(*it, new_track));
268 webkit_stream_.addTrack(new_track); 306 webkit_stream_.addTrack(new_track);
269 } 307 }
270 } 308 }
271 } 309 }
272 310
273 } // namespace content 311 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698