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

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

Issue 8060055: Adding support for MediaStream and PeerConnection functionality (Closed) Base URL: http://git.chromium.org/chromium/chromium.git@trunk
Patch Set: Changed ID to object in WebKit interface. Created 9 years, 2 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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/media_stream_impl.h" 5 #include "content/renderer/media/media_stream_impl.h"
6 6
7 #include "base/string_util.h" 7 #include <vector>
8
9 #include "base/logging.h"
10 #include "base/synchronization/waitable_event.h"
11 #include "base/utf_string_conversions.h"
12 #include "content/common/media/media_stream_options.h"
8 #include "content/renderer/media/capture_video_decoder.h" 13 #include "content/renderer/media/capture_video_decoder.h"
14 #include "content/renderer/media/media_stream_dispatcher.h"
15 #include "content/renderer/media/rtc_video_decoder.h"
9 #include "content/renderer/media/video_capture_impl_manager.h" 16 #include "content/renderer/media/video_capture_impl_manager.h"
10 #include "googleurl/src/gurl.h" 17 #include "content/renderer/media/video_capture_module_impl.h"
18 #include "content/renderer/media/webrtc_audio_device_impl.h"
19 #include "content/renderer/p2p/ipc_network_manager.h"
20 #include "content/renderer/p2p/ipc_socket_factory.h"
21 #include "content/renderer/p2p/socket_dispatcher.h"
22 #include "jingle/glue/thread_wrapper.h"
11 #include "media/base/message_loop_factory.h" 23 #include "media/base/message_loop_factory.h"
12 #include "media/base/pipeline.h" 24 #include "third_party/libjingle/source/talk/p2p/client/httpportallocator.h"
25 #include "third_party/libjingle/source/talk/session/phone/dummydevicemanager.h"
26 #include "third_party/libjingle/source/talk/session/phone/webrtcmediaengine.h"
27 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
28 #include "third_party/WebKit/Source/WebKit/chromium/public/WebLocalMediaStream.h "
29 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStream.h"
30 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamControl ler.h"
31 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamRegistr y.h"
32 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamTrackLi st.h"
33 #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaStreamTrack.h "
34 #include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
35 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
36 #include "third_party/WebKit/Source/WebKit/chromium/public/WebVector.h"
13 37
14 namespace { 38 namespace {
15 39
16 static const int kVideoCaptureWidth = 352; 40 static const int kVideoCaptureWidth = 352;
17 static const int kVideoCaptureHeight = 288; 41 static const int kVideoCaptureHeight = 288;
18 static const int kVideoCaptureFramePerSecond = 30; 42 static const int kVideoCaptureFramePerSecond = 30;
19 43
20 static const int kStartOpenSessionId = 1;
21
22 // TODO(wjia): remove this string when full media stream code is checked in.
23 static const char kRawMediaScheme[] = "mediastream";
24
25 } // namespace 44 } // namespace
26 45
27 MediaStreamImpl::MediaStreamImpl(VideoCaptureImplManager* vc_manager) 46 MediaStreamImpl::MediaStreamImpl(
28 : vc_manager_(vc_manager) { 47 MediaStreamDispatcher* media_stream_dispatcher,
29 } 48 content::P2PSocketDispatcher* p2p_socket_dispatcher,
30 49 VideoCaptureImplManager* vc_manager)
31 MediaStreamImpl::~MediaStreamImpl() {} 50 : controller_(NULL),
51 media_stream_dispatcher_(media_stream_dispatcher),
52 media_engine_(NULL),
53 p2p_socket_dispatcher_(p2p_socket_dispatcher),
54 vc_manager_(vc_manager),
55 signaling_thread_(NULL),
56 worker_thread_(NULL),
57 chrome_worker_thread_("Chrome_libJingle_WorkerThread"),
58 call_state_(NOT_STARTED),
59 vcm_is_created_(false) {
60 message_loop_proxy_ = base::MessageLoopProxy::current();
61 // chrome_worker_thread_.Start();
tommi (sloooow) - chröme 2011/10/03 12:14:14 remove or unintentional?
Henrik Grunell 2011/10/18 19:04:05 Removed.
62 }
63
64 MediaStreamImpl::~MediaStreamImpl() {
65 if (peer_connection_native_.get()) {
66 peer_connection_native_->RegisterObserver(NULL);
67 peer_connection_native_->Close();
68 }
69 }
70
71 void MediaStreamImpl::setController(
72 WebKit::WebMediaStreamController* controller) {
73 controller_.reset(controller);
74 }
75
76 void MediaStreamImpl::shutdown() {
77 controller_.reset();
78 }
79
80 void MediaStreamImpl::generateStream(
81 int request_id,
82 WebKit::WebGenerateStreamOptionFlags flags,
83 const WebKit::WebSecurityOrigin& web_security_origin) {
84
tommi (sloooow) - chröme 2011/10/03 12:14:14 no empty lines at the top of a function
Henrik Grunell 2011/10/18 19:04:05 Done.
85 bool audio = (flags & WebKit::WebGenerateStreamRequestAudio) != 0;
86 media_stream::StreamOptions::VideoOption video_option =
87 media_stream::StreamOptions::kNoCamera;
88
89 if ((flags & WebKit::WebGenerateStreamRequestVideoFacingUser) &&
90 (flags & WebKit::WebGenerateStreamRequestVideoFacingEnvironment)) {
91 video_option = media_stream::StreamOptions::kFacingBoth;
92 } else {
93 if (flags & WebKit::WebGenerateStreamRequestVideoFacingEnvironment)
94 video_option = media_stream::StreamOptions::kFacingEnvironment;
95 if (flags & WebKit::WebGenerateStreamRequestVideoFacingUser)
96 video_option = media_stream::StreamOptions::kFacingUser;
97 }
98
99 VLOG(1) << "MediaStreamImpl::generateStream("
100 << request_id << ", [ "
101 << (audio ? "audio " : "")
102 << ((flags &
103 flags & WebKit::WebGenerateStreamRequestVideoFacingUser) ?
104 "video_facing_user " : "")
105 << ((flags &
106 WebKit::WebGenerateStreamRequestVideoFacingEnvironment) ?
107 "video_facing_environment " : "")
108 << "], "
109 << static_cast<string16>(web_security_origin.toString()) << ")";
tommi (sloooow) - chröme 2011/10/03 12:14:14 is the cast necessary? feels like if the cast is
Henrik Grunell 2011/10/18 19:04:05 Yes needed, WebString isn't handled. And yes an ob
110
111 media_stream_dispatcher_->GenerateStream(request_id, this,
112 media_stream::StreamOptions(audio, video_option),
113 UTF16ToUTF8(web_security_origin.toString()));
114 }
115
116 void MediaStreamImpl::stopGeneratedStream(
117 const WebKit::WebLocalMediaStream& stream) {
118 std::string label = UTF16ToUTF8(stream.label());
119 media_stream_dispatcher_->StopStream(label);
120 }
121
122 void MediaStreamImpl::recordStream(
123 const WebKit::WebMediaStreamRecorder& recorder) {
124 // TODO(grunell): Implement.
125 }
126
127 void MediaStreamImpl::getRecordedData(
128 const WebKit::WebMediaStreamRecorder& recorder,
129 int request_id) {
130 // TODO(grunell): Implement.
131 }
132
133 void MediaStreamImpl::disposeRecordedData(
134 const WebKit::WebMediaStreamRecorder& recorder) {
135 // TODO(grunell): Implement.
136 }
137
138 void MediaStreamImpl::setMediaStreamTrackEnabled(
139 const WebKit::WebMediaStreamTrack& track) {
140 // TODO(grunell): Implement.
141 }
142
143 void MediaStreamImpl::processSignalingMessage(
144 const WebKit::WebPeerConnection& peer_connection_web,
145 const WebKit::WebString& message) {
146 VLOG(1) << "MediaStreamImpl::processSignalingMessage("
147 << UTF16ToUTF8(message) << ")";
148 if (peer_connection_web != peer_connection_web_) {
149 DLOG(ERROR) << __FUNCTION__ << ": PeerConnection is not valid";
150 return;
151 }
152 DCHECK(peer_connection_native_.get());
153 peer_connection_native_->SignalingMessage(UTF16ToUTF8(message));
154 }
155
156 void MediaStreamImpl::message(
157 const WebKit::WebPeerConnection& peer_connection_web,
158 const WebKit::WebString& message) {
159 VLOG(1) << "MediaStreamImpl::message(" << UTF16ToUTF8(message) << ")";
160 if (peer_connection_web != peer_connection_web_) {
161 DLOG(ERROR) << __FUNCTION__ << ": PeerConnection is not valid";
162 return;
163 }
164 // TODO(grunell): Implement.
165 }
166
167 void MediaStreamImpl::addStream(
168 const WebKit::WebPeerConnection& peer_connection_web,
169 const WebKit::WebMediaStream& stream) {
170 VLOG(1) << "MediaStreamImpl::addStream("
171 << UTF16ToUTF8(stream.label()) << ")";
172
173 if (peer_connection_web != peer_connection_web_) {
174 DLOG(ERROR) << __FUNCTION__ << ": PeerConnection is not valid";
175 return;
176 }
177
178 // TODO(grunell): Fix code in this function after libjingle with new
179 // PeerConnection version has been rolled out.
180
181 if (call_state_ == NOT_STARTED) {
182 DCHECK(peer_connection_native_.get());
183 // TODO(grunell): Add audio and/or video depending on what's enabled
184 // in the stream.
185 std::string label = UTF16ToUTF8(stream.label());
186 std::string audioLabel = label;
187 audioLabel.append("-audio");
188 peer_connection_native_->AddStream(audioLabel, false); // Audio
189 peer_connection_native_->AddStream(label, true); // Video
190 local_label_ = label;
191 call_state_ = INITIATING;
192 }
193 if (call_state_ == INITIATING || call_state_ == RECEIVING) {
194 if (!vcm_is_created_) {
195 // Set the capture device
196 // TODO(grunell): instead of using the first track,
197 // the selected track should be used.
198 int id = media_stream_dispatcher_->video_session_id(local_label_, 0);
199 if (id != media_stream::StreamDeviceInfo::kNoId) {
200 webrtc::VideoCaptureModule* vcm = new VideoCaptureModuleImpl(
201 id, vc_manager_.get());
202 vcm_is_created_ = true;
203 media_engine_->SetVideoCaptureModule(vcm);
204 peer_connection_native_->SetVideoCapture("");
205 }
206 }
207 if (call_state_ == INITIATING)
208 peer_connection_native_->Connect();
209 else if (call_state_ == RECEIVING)
210 call_state_ = SENDING_AND_RECEIVING;
211 } else {
212 DLOG(ERROR) << __FUNCTION__ << ": Multiple calls not supported";
213 return;
214 }
215 }
216
217 void MediaStreamImpl::newPeerConnection(
218 const WebKit::WebPeerConnection& peer_connection_web,
219 const WebKit::WebString& configuration) {
220 if (peer_connection_native_.get()) {
221 LOG(ERROR) << __FUNCTION__ << ": A PeerConnection already exists";
222 return;
223 }
224
225 if (!media_engine_) {
226 webrtc::AudioDeviceModule* adm = new WebRtcAudioDeviceImpl();
227 webrtc::AudioDeviceModule* adm_sc = new WebRtcAudioDeviceImpl();
228 media_engine_ = new cricket::WebRtcMediaEngine(adm, adm_sc, NULL);
229 }
230
231 if (!signaling_thread_) {
232 jingle_glue::JingleThreadWrapper::EnsureForCurrentThread();
233 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true);
234 signaling_thread_ = jingle_glue::JingleThreadWrapper::current();
235 }
236
237 if (!worker_thread_) {
238 if (!chrome_worker_thread_.IsRunning()) {
239 if (!chrome_worker_thread_.Start()) {
240 LOG(ERROR) << __FUNCTION__ << ": Could not start worker thread";
241 return;
242 }
243 }
244 base::WaitableEvent event(true, false);
245 chrome_worker_thread_.message_loop()->PostTask(
246 FROM_HERE, NewRunnableMethod(
247 this, &MediaStreamImpl::InitializeWorkerThread,
248 &worker_thread_, &event));
249 event.Wait();
250 DCHECK(worker_thread_);
251 }
252
253 if (!pc_factory_.get()) {
254 ipc_network_manager_.reset(
255 new content::IpcNetworkManager(p2p_socket_dispatcher_));
256 ipc_socket_factory_.reset(
257 new content::IpcPacketSocketFactory(p2p_socket_dispatcher_));
258 cricket::HttpPortAllocator* port_allocator =
259 new cricket::HttpPortAllocator(ipc_network_manager_.get(),
260 ipc_socket_factory_.get(),
261 "PeerConnection");
262 // TODO(mallinath) - Following flags added to solve crash in HttpClient
263 port_allocator->set_flags(cricket::PORTALLOCATOR_DISABLE_TCP |
264 cricket::PORTALLOCATOR_DISABLE_RELAY);
265
266 // TODO(mallinath) - PeerConnectionFactory constructor changed in latest
267 // code and it no more accepts config string. Config string must be parsed
268 // here and set in HttpPortAllocator. Now using standard google STUN server
269 // address.
270 std::vector<talk_base::SocketAddress> stun_hosts;
271 stun_hosts.push_back(talk_base::SocketAddress("stun.l.google.com", 19302));
272 port_allocator->SetStunHosts(stun_hosts);
273
274 pc_factory_.reset(
275 new webrtc::PeerConnectionFactory(port_allocator,
276 media_engine_,
277 new cricket::DummyDeviceManager(),
278 worker_thread_));
279 if (!pc_factory_->Initialize()) {
280 LOG(ERROR) << __FUNCTION__ << ": Could not initialize PeerConnection "
281 "factory";
282 return;
283 }
284 }
285
286 peer_connection_native_.reset(pc_factory_.get()->CreatePeerConnection(
287 signaling_thread_));
288 DCHECK(peer_connection_native_.get());
289 peer_connection_web_ = peer_connection_web;
290 peer_connection_native_->RegisterObserver(this);
291 }
292
293 void MediaStreamImpl::closePeerConnection(
294 const WebKit::WebPeerConnection& peer_connection_web) {
295 if (peer_connection_web != peer_connection_web_) {
296 DLOG(ERROR) << __FUNCTION__ << ": PeerConnection is not valid";
297 return;
298 }
299 // TODO(grunell): Fix code in this function after libjingle with new
300 // PeerConnection version has been rolled out.
301 if (call_state_ == RECEIVING || call_state_ == SENDING_AND_RECEIVING)
302 call_state_ = TERMINATING;
303 if (peer_connection_native_.get())
304 DeletePeerConnection();
305 }
306
307 void MediaStreamImpl::startNegotiation(
308 const WebKit::WebPeerConnection& peer_connection_web) {
309 if (peer_connection_web != peer_connection_web_) {
310 DLOG(ERROR) << __FUNCTION__ << ": PeerConnection is not valid";
311 return;
312 }
313 // TODO(grunell): Implement. Currently not supported in libjingle.
314 }
315
316 void MediaStreamImpl::removeStream(
317 const WebKit::WebPeerConnection& peer_connection_web,
318 const WebKit::WebMediaStream& stream) {
319 if (peer_connection_web != peer_connection_web_) {
320 DLOG(ERROR) << __FUNCTION__ << ": PeerConnection is not valid";
321 return;
322 }
323 // TODO(grunell): Implement. Currently not supported in libjingle.
324 }
325
326 void MediaStreamImpl::commitStreamChanges(
327 const WebKit::WebPeerConnection& peer_connection_web) {
328 if (peer_connection_web != peer_connection_web_) {
329 DLOG(ERROR) << __FUNCTION__ << ": PeerConnection is not valid";
330 return;
331 }
332 // TODO(grunell): Implement. Currently not supported in libjingle.
333 }
32 334
33 scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder( 335 scoped_refptr<media::VideoDecoder> MediaStreamImpl::GetVideoDecoder(
34 const GURL& url, media::MessageLoopFactory* message_loop_factory) { 336 const GURL& url, media::MessageLoopFactory* message_loop_factory) {
35 bool raw_media = (url.spec().find(kRawMediaScheme) == 0); 337 std::string label =
36 media::VideoDecoder* decoder = NULL; 338 UTF16ToUTF8(WebKit::WebMediaStreamRegistry::mediaStreamLabel(url));
37 if (raw_media) { 339 if (label.empty())
340 return NULL; // This is not a valid stream.
341
342 scoped_refptr<media::VideoDecoder> decoder;
343 if (media_stream_dispatcher_->IsStream(label)) {
344 // It's a local stream.
345 int video_session_id = media_stream_dispatcher_->video_session_id(label, 0);
38 media::VideoCapture::VideoCaptureCapability capability; 346 media::VideoCapture::VideoCaptureCapability capability;
39 capability.width = kVideoCaptureWidth; 347 capability.width = kVideoCaptureWidth;
40 capability.height = kVideoCaptureHeight; 348 capability.height = kVideoCaptureHeight;
41 capability.max_fps = kVideoCaptureFramePerSecond; 349 capability.max_fps = kVideoCaptureFramePerSecond;
42 capability.expected_capture_delay = 0; 350 capability.expected_capture_delay = 0;
43 capability.raw_type = media::VideoFrame::I420; 351 capability.raw_type = media::VideoFrame::I420;
44 capability.interlaced = false; 352 capability.interlaced = false;
45 capability.resolution_fixed = false; 353 capability.resolution_fixed = false;
46
47 decoder = new CaptureVideoDecoder( 354 decoder = new CaptureVideoDecoder(
48 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoder").get(), 355 message_loop_factory->GetMessageLoopProxy("CaptureVideoDecoderThread"),
49 kStartOpenSessionId, vc_manager_.get(), capability); 356 video_session_id, vc_manager_.get(), capability);
357 } else {
358 // It's a remote stream.
359 DCHECK(label.size());
360 if (rtc_video_decoder_.get()) {
361 // The renderer is used by PeerConnection, release it first.
362 size_t found = label.rfind("-remote");
363 if (found != std::string::npos)
364 label = label.substr(0, found);
365 if (peer_connection_native_.get()) {
366 peer_connection_native_->SetVideoRenderer(label, NULL);
367 }
368 }
369 rtc_video_decoder_ = new RTCVideoDecoder(
370 message_loop_factory->GetMessageLoop("RtcVideoDecoderThread"),
371 url.spec());
372 decoder = rtc_video_decoder_;
373 size_t found = label.rfind("-remote");
374 if (found != std::string::npos)
375 label = label.substr(0, found);
376 if (peer_connection_native_.get()) {
377 peer_connection_native_->SetVideoRenderer(label, rtc_video_decoder_);
378 }
50 } 379 }
51 return decoder; 380 return decoder;
52 } 381 }
382
383 void MediaStreamImpl::OnStreamGenerated(
384 int request_id, const std::string& label,
385 const media_stream::StreamDeviceInfoArray& audio_array,
386 const media_stream::StreamDeviceInfoArray& video_array) {
387 VLOG(1) << "MediaStreamImpl::OnStreamGenerated(" << request_id << ", "
388 << label << ")";
389 DCHECK(controller_.get());
390
391 WebKit::WebVector<WebKit::WebMediaStreamTrack> web_track_vector(
392 audio_array.size() + video_array.size());
393
394 WebKit::WebString track_id(WebKit::WebString::fromUTF8(""));
395 WebKit::WebString track_kind(WebKit::WebString::fromUTF8("main"));
396 WebKit::WebString track_label_audio(
397 WebKit::WebString::fromUTF8("AudioDevice"));
398 WebKit::WebString track_label_video(
399 WebKit::WebString::fromUTF8("VideoCapture"));
400 unsigned int track_num = web_track_vector.size();
401 while (track_num--) {
402 if (track_num < audio_array.size()) {
403 web_track_vector[track_num].initialize(track_id,
404 track_kind,
405 track_label_audio);
406 } else {
407 web_track_vector[track_num].initialize(track_id,
408 track_kind,
409 track_label_video);
410 }
411 }
412
413 local_label_ = label;
414
415 WebKit::WebMediaStreamTrackList web_track_list;
416 web_track_list.initialize(web_track_vector);
417
418 WebKit::WebLocalMediaStream web_local_media_stream;
419 web_local_media_stream.initialize(UTF8ToUTF16(label), web_track_list);
420
421 controller_->streamGenerated(request_id, web_local_media_stream);
422 }
423
424 void MediaStreamImpl::OnStreamGenerationFailed(int request_id) {
425 VLOG(1) << "MediaStreamImpl::OnStreamGenerationFailed("
426 << request_id << ")\n";
427 DCHECK(controller_.get());
428 controller_->streamGenerationFailed(
429 request_id,
430 WebKit::WebMediaStreamController::ErrorPermissionDenied);
431 }
432
433 void MediaStreamImpl::OnVideoDeviceFailed(const std::string& label,
434 int index) {
435 VLOG(1) << "MediaStreamImpl::OnVideoDeviceFailed("
436 << label << ", " << index << ")\n";
437 DCHECK(controller_.get());
438 controller_->streamFailed(UTF8ToUTF16(label));
439 }
440
441 void MediaStreamImpl::OnAudioDeviceFailed(const std::string& label,
442 int index) {
443 VLOG(1) << "MediaStreamImpl::OnAudioDeviceFailed("
444 << label << ", " << index << ")\n";
445 DCHECK(controller_.get());
446 controller_->streamFailed(UTF8ToUTF16(label));
447 }
448
449 void MediaStreamImpl::OnError() {
450 VLOG(1) << "MediaStreamImpl::OnError()";
451 }
452
453 void MediaStreamImpl::OnSignalingMessage(const std::string& msg) {
454 VLOG(1) << "MediaStreamImpl::OnSignalingMessage(" << msg << ")";
455
456 if (!message_loop_proxy_->BelongsToCurrentThread()) {
457 message_loop_proxy_->PostTask(
458 FROM_HERE,
459 NewRunnableMethod(this, &MediaStreamImpl::OnSignalingMessage, msg));
460 return;
461 }
462
463 DCHECK(controller_.get());
464 controller_->onSignalingMessage(peer_connection_web_, UTF8ToUTF16(msg));
465 }
466
467 void MediaStreamImpl::OnAddStream(const std::string& stream_id, bool video) {
468 VLOG(1) << "MediaStreamImpl::OnAddStream(" << stream_id << ", "
469 << video << ")";
470
471 DCHECK(controller_.get());
472
473 // TODO(grunell): Fix code in this function after libjingle with new
474 // PeerConnection version has been rolled out.
475 if (video) {
476 if (call_state_ == NOT_STARTED) {
477 remote_label_ = stream_id;
478 call_state_ = RECEIVING;
479 } else if (call_state_ == INITIATING) {
480 std::string label = local_label_;
481 label += "-remote";
482 remote_label_ = label;
483 call_state_ = SENDING_AND_RECEIVING;
484 }
485
486 if (!message_loop_proxy_->BelongsToCurrentThread()) {
487 message_loop_proxy_->PostTask(
488 FROM_HERE,
489 NewRunnableMethod(this,
490 &MediaStreamImpl::OnAddStreamCallback,
491 remote_label_));
492 return;
493 } else {
494 OnAddStreamCallback(remote_label_);
495 }
496 }
497 }
498
499 void MediaStreamImpl::OnRemoveStream(const std::string& stream_id, bool video) {
500 VLOG(1) << "MediaStreamImpl::OnRemoveStream(" << stream_id << ", "
501 << video << ")";
502
503 if (video) {
504 if (!message_loop_proxy_->BelongsToCurrentThread()) {
505 message_loop_proxy_->PostTask(
506 FROM_HERE,
507 NewRunnableMethod(this,
508 &MediaStreamImpl::OnRemoveStreamCallback,
509 remote_label_));
510 } else {
511 OnRemoveStreamCallback(remote_label_);
512 }
513 }
514 }
515
516 void MediaStreamImpl::OnAddStreamCallback(const std::string& stream_label) {
517 size_t size = 1;
518 WebKit::WebVector<WebKit::WebMediaStreamTrack> web_track_vector(size);
519 web_track_vector[0].initialize(WebKit::WebString::fromUTF8(""),
520 WebKit::WebString::fromUTF8("main"),
521 WebKit::WebString::fromUTF8(stream_label));
522 WebKit::WebMediaStreamTrackList web_track_list;
523 web_track_list.initialize(web_track_vector);
524
525 WebKit::WebMediaStream web_media_stream;
526 web_media_stream.initialize(UTF8ToUTF16(stream_label), web_track_list);
527
528 controller_->onAddStream(peer_connection_web_, web_media_stream);
529 }
530
531 void MediaStreamImpl::OnRemoveStreamCallback(const std::string& stream_label) {
532 DCHECK(controller_.get());
533 controller_->onRemoveStream(peer_connection_web_, UTF8ToUTF16(stream_label));
534 }
535
536 void MediaStreamImpl::DeletePeerConnection() {
537 DCHECK(peer_connection_native_.get());
538 peer_connection_native_->RegisterObserver(NULL);
539 peer_connection_native_.reset();
540 peer_connection_web_.reset();
541 // TODO(grunell): Stop chrome_worker_thread_ here?
542 rtc_video_decoder_ = NULL;
543 media_engine_->SetVideoCaptureModule(NULL);
544 vcm_is_created_ = false;
545 call_state_ = NOT_STARTED;
546 }
547
548 void MediaStreamImpl::InitializeWorkerThread(talk_base::Thread** thread,
549 base::WaitableEvent* event) {
550 jingle_glue::JingleThreadWrapper::EnsureForCurrentThread();
551 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true);
552 *thread = jingle_glue::JingleThreadWrapper::current();
553 event->Signal();
554 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698