| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_dependency_factory.h" | 5 #include "content/renderer/media/media_stream_dependency_factory.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/synchronization/waitable_event.h" | 9 #include "base/synchronization/waitable_event.h" |
| 10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
| 11 #include "content/renderer/media/media_stream_source_extra_data.h" | 11 #include "content/renderer/media/media_stream_source_extra_data.h" |
| 12 #include "content/renderer/media/rtc_media_constraints.h" | 12 #include "content/renderer/media/rtc_media_constraints.h" |
| 13 #include "content/renderer/media/rtc_peer_connection_handler.h" | 13 #include "content/renderer/media/rtc_peer_connection_handler.h" |
| 14 #include "content/renderer/media/rtc_video_capturer.h" | 14 #include "content/renderer/media/rtc_video_capturer.h" |
| 15 #include "content/renderer/media/video_capture_impl_manager.h" | 15 #include "content/renderer/media/video_capture_impl_manager.h" |
| 16 #include "content/renderer/media/webaudio_capturer_source.h" |
| 16 #include "content/renderer/media/webrtc_audio_device_impl.h" | 17 #include "content/renderer/media/webrtc_audio_device_impl.h" |
| 17 #include "content/renderer/media/webrtc_uma_histograms.h" | 18 #include "content/renderer/media/webrtc_uma_histograms.h" |
| 18 #include "content/renderer/p2p/ipc_network_manager.h" | 19 #include "content/renderer/p2p/ipc_network_manager.h" |
| 19 #include "content/renderer/p2p/ipc_socket_factory.h" | 20 #include "content/renderer/p2p/ipc_socket_factory.h" |
| 20 #include "content/renderer/p2p/port_allocator.h" | 21 #include "content/renderer/p2p/port_allocator.h" |
| 21 #include "jingle/glue/thread_wrapper.h" | 22 #include "jingle/glue/thread_wrapper.h" |
| 22 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamCompo
nent.h" | 23 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamCompo
nent.h" |
| 23 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamDescr
iptor.h" | 24 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamDescr
iptor.h" |
| 24 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSourc
e.h" | 25 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSourc
e.h" |
| 25 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| (...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 return NULL; | 184 return NULL; |
| 184 | 185 |
| 185 return new RTCPeerConnectionHandler(client, this); | 186 return new RTCPeerConnectionHandler(client, this); |
| 186 } | 187 } |
| 187 | 188 |
| 188 void MediaStreamDependencyFactory::CreateNativeMediaSources( | 189 void MediaStreamDependencyFactory::CreateNativeMediaSources( |
| 189 const WebKit::WebMediaConstraints& audio_constraints, | 190 const WebKit::WebMediaConstraints& audio_constraints, |
| 190 const WebKit::WebMediaConstraints& video_constraints, | 191 const WebKit::WebMediaConstraints& video_constraints, |
| 191 WebKit::WebMediaStreamDescriptor* description, | 192 WebKit::WebMediaStreamDescriptor* description, |
| 192 const MediaSourcesCreatedCallback& sources_created) { | 193 const MediaSourcesCreatedCallback& sources_created) { |
| 194 DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeMediaSources()"; |
| 193 if (!EnsurePeerConnectionFactory()) { | 195 if (!EnsurePeerConnectionFactory()) { |
| 194 sources_created.Run(description, false); | 196 sources_created.Run(description, false); |
| 195 return; | 197 return; |
| 196 } | 198 } |
| 197 | 199 |
| 198 // |source_observer| clean up itself when it has completed | 200 // |source_observer| clean up itself when it has completed |
| 199 // source_observer->StartObservering. | 201 // source_observer->StartObservering. |
| 200 SourceStateObserver* source_observer = | 202 SourceStateObserver* source_observer = |
| 201 new SourceStateObserver(description, sources_created); | 203 new SourceStateObserver(description, sources_created); |
| 202 | 204 |
| 203 // TODO(perkj): Implement local audio sources. | |
| 204 | |
| 205 // Create local video sources. | 205 // Create local video sources. |
| 206 RTCMediaConstraints native_video_constraints(video_constraints); | 206 RTCMediaConstraints native_video_constraints(video_constraints); |
| 207 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components; | 207 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components; |
| 208 description->videoSources(video_components); | 208 description->videoSources(video_components); |
| 209 for (size_t i = 0; i < video_components.size(); ++i) { | 209 for (size_t i = 0; i < video_components.size(); ++i) { |
| 210 const WebKit::WebMediaStreamSource& source = video_components[i].source(); | 210 const WebKit::WebMediaStreamSource& source = video_components[i].source(); |
| 211 MediaStreamSourceExtraData* source_data = | 211 MediaStreamSourceExtraData* source_data = |
| 212 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 212 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| 213 if (!source_data) { | 213 if (!source_data) { |
| 214 // TODO(perkj): Implement support for sources from remote MediaStreams. | 214 // TODO(perkj): Implement support for sources from remote MediaStreams. |
| 215 NOTIMPLEMENTED(); | 215 NOTIMPLEMENTED(); |
| 216 continue; | 216 continue; |
| 217 } | 217 } |
| 218 const bool is_screencast = (source_data->device_info().device.type == | 218 const bool is_screencast = (source_data->device_info().device.type == |
| 219 content::MEDIA_TAB_VIDEO_CAPTURE); | 219 content::MEDIA_TAB_VIDEO_CAPTURE); |
| 220 source_data->SetVideoSource( | 220 source_data->SetVideoSource( |
| 221 CreateVideoSource(source_data->device_info().session_id, | 221 CreateVideoSource(source_data->device_info().session_id, |
| 222 is_screencast, | 222 is_screencast, |
| 223 &native_video_constraints)); | 223 &native_video_constraints)); |
| 224 source_observer->AddSource(source_data->video_source()); | 224 source_observer->AddSource(source_data->video_source()); |
| 225 } | 225 } |
| 226 |
| 227 // Do additional source initialization if the audio source is a valid |
| 228 // microphone. |
| 229 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; |
| 230 description->audioSources(audio_components); |
| 231 for (size_t i = 0; i < audio_components.size(); ++i) { |
| 232 const WebKit::WebMediaStreamSource& source = audio_components[i].source(); |
| 233 MediaStreamSourceExtraData* source_data = |
| 234 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| 235 if (!source_data) { |
| 236 // TODO(henrika): Implement support for sources from remote MediaStreams. |
| 237 NOTIMPLEMENTED(); |
| 238 continue; |
| 239 } |
| 240 |
| 241 const StreamDeviceInfo device_info = source_data->device_info(); |
| 242 if (device_info.device.type == content::MEDIA_DEVICE_AUDIO_CAPTURE) { |
| 243 if (!InitializeAudioSource(device_info)) { |
| 244 DLOG(WARNING) << "Unsupported audio source"; |
| 245 sources_created.Run(description, false); |
| 246 return; |
| 247 } |
| 248 } |
| 249 } |
| 250 |
| 226 source_observer->StartObservering(); | 251 source_observer->StartObservering(); |
| 227 } | 252 } |
| 228 | 253 |
| 229 void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( | 254 void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( |
| 230 WebKit::WebMediaStreamDescriptor* description) { | 255 WebKit::WebMediaStreamDescriptor* description) { |
| 256 DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeLocalMediaStream()"; |
| 231 if (!EnsurePeerConnectionFactory()) { | 257 if (!EnsurePeerConnectionFactory()) { |
| 232 DVLOG(1) << "EnsurePeerConnectionFactory() failed!"; | 258 DVLOG(1) << "EnsurePeerConnectionFactory() failed!"; |
| 233 return; | 259 return; |
| 234 } | 260 } |
| 235 | 261 |
| 236 std::string label = UTF16ToUTF8(description->label()); | 262 std::string label = UTF16ToUTF8(description->label()); |
| 237 scoped_refptr<webrtc::LocalMediaStreamInterface> native_stream = | 263 scoped_refptr<webrtc::LocalMediaStreamInterface> native_stream = |
| 238 CreateLocalMediaStream(label); | 264 CreateLocalMediaStream(label); |
| 239 | 265 |
| 240 WebRtcAudioCapturer* capturer = | |
| 241 GetWebRtcAudioDevice() ? GetWebRtcAudioDevice()->capturer() : 0; | |
| 242 if (!capturer) | |
| 243 DVLOG(1) << "CreateNativeLocalMediaStream: missing WebRtcAudioCapturer."; | |
| 244 | |
| 245 // Add audio tracks. | 266 // Add audio tracks. |
| 246 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; | 267 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; |
| 247 description->audioSources(audio_components); | 268 description->audioSources(audio_components); |
| 248 | 269 |
| 249 for (size_t i = 0; i < audio_components.size(); ++i) { | 270 for (size_t i = 0; i < audio_components.size(); ++i) { |
| 250 WebKit::WebMediaStreamSource source = audio_components[i].source(); | 271 WebKit::WebMediaStreamSource source = audio_components[i].source(); |
| 251 | 272 |
| 252 // See if we're adding a WebAudio MediaStream. | 273 // See if we're adding a WebAudio MediaStream. |
| 253 if (source.requiresAudioConsumer()) { | 274 if (source.requiresAudioConsumer()) { |
| 254 if (!webaudio_capturer_source_.get() && capturer) { | 275 // TODO(crogers, xians): In reality we should be able to send a unique |
| 255 DCHECK(GetWebRtcAudioDevice()); | 276 // audio stream to each PeerConnection separately. But currently WebRTC |
| 277 // is only able to handle a global audio stream sent to ALL peers. |
| 256 | 278 |
| 257 // TODO(crogers, xians): In reality we should be able to send a unique | 279 // TODO(henrika): refactor and utilize audio constraints. |
| 258 // audio stream to each PeerConnection separately. But currently WebRTC | 280 if (CreateWebAudioSource(&source)) { |
| 259 // is only able to handle a global audio stream sent to ALL peers. | |
| 260 | |
| 261 // For lifetime, we're relying on the fact that | |
| 262 // |webaudio_capturer_source_| will live longer than any | |
| 263 // MediaStreamSource, since we're never calling removeAudioConsumer(). | |
| 264 webaudio_capturer_source_ = new WebAudioCapturerSource(capturer); | |
| 265 source.addAudioConsumer(webaudio_capturer_source_.get()); | |
| 266 | |
| 267 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( | 281 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( |
| 268 CreateLocalAudioTrack(label + "a0", NULL)); | 282 CreateLocalAudioTrack(UTF16ToUTF8(audio_components[i].id()), NULL)); |
| 269 native_stream->AddTrack(audio_track); | 283 native_stream->AddTrack(audio_track); |
| 270 audio_track->set_enabled(audio_components[i].isEnabled()); | 284 audio_track->set_enabled(audio_components[i].isEnabled()); |
| 271 } else { | 285 } else { |
| 272 // TODO(crogers): this is very likely to be less important, but | 286 DLOG(WARNING) << "Failed to create WebAudio source"; |
| 273 // in theory we should be able to "connect" multiple WebAudio | |
| 274 // MediaStreams to a single peer, mixing their results. | |
| 275 // Instead we just ignore additional ones after the first. | |
| 276 LOG(WARNING) | |
| 277 << "Multiple MediaStreamAudioDestinationNodes not yet supported!"; | |
| 278 } | 287 } |
| 279 } else { | 288 } else { |
| 280 MediaStreamSourceExtraData* source_data = | 289 MediaStreamSourceExtraData* source_data = |
| 281 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 290 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| 282 | 291 |
| 283 if (!source_data) { | 292 if (!source_data) { |
| 284 // TODO(perkj): Implement support for sources from | 293 // TODO(perkj): Implement support for sources from |
| 285 // remote MediaStreams. | 294 // remote MediaStreams. |
| 286 NOTIMPLEMENTED(); | 295 NOTIMPLEMENTED(); |
| 287 continue; | 296 continue; |
| 288 } | 297 } |
| 289 | 298 |
| 290 // TODO(perkj): Refactor the creation of audio tracks to use a proper | 299 // TODO(perkj): Refactor the creation of audio tracks to use a proper |
| 291 // interface for receiving audio input data. Currently NULL is passed | 300 // interface for receiving audio input data. Currently NULL is passed |
| 292 // since the |audio_device| is the wrong class and is unused. | 301 // since the |audio_device| is the wrong class and is unused. |
| 293 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( | 302 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( |
| 294 CreateLocalAudioTrack(UTF16ToUTF8(source.id()), NULL)); | 303 CreateLocalAudioTrack(UTF16ToUTF8(source.id()), NULL)); |
| 295 native_stream->AddTrack(audio_track); | 304 native_stream->AddTrack(audio_track); |
| 296 audio_track->set_enabled(audio_components[i].isEnabled()); | 305 audio_track->set_enabled(audio_components[i].isEnabled()); |
| 297 // TODO(xians): This set the source of all audio tracks to the same | |
| 298 // microphone. Implement support for setting the source per audio track | |
| 299 // instead. | |
| 300 SetAudioDeviceSessionId(source_data->device_info().session_id); | |
| 301 } | 306 } |
| 302 } | 307 } |
| 303 | 308 |
| 304 // Add video tracks. | 309 // Add video tracks. |
| 305 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components; | 310 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components; |
| 306 description->videoSources(video_components); | 311 description->videoSources(video_components); |
| 307 for (size_t i = 0; i < video_components.size(); ++i) { | 312 for (size_t i = 0; i < video_components.size(); ++i) { |
| 308 const WebKit::WebMediaStreamSource& source = video_components[i].source(); | 313 const WebKit::WebMediaStreamSource& source = video_components[i].source(); |
| 309 MediaStreamSourceExtraData* source_data = | 314 MediaStreamSourceExtraData* source_data = |
| 310 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 315 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| (...skipping 19 matching lines...) Expand all Loading... |
| 330 WebKit::WebMediaStreamDescriptor* description, | 335 WebKit::WebMediaStreamDescriptor* description, |
| 331 const MediaStreamExtraData::StreamStopCallback& stream_stop) { | 336 const MediaStreamExtraData::StreamStopCallback& stream_stop) { |
| 332 CreateNativeLocalMediaStream(description); | 337 CreateNativeLocalMediaStream(description); |
| 333 | 338 |
| 334 MediaStreamExtraData* extra_data = | 339 MediaStreamExtraData* extra_data = |
| 335 static_cast<MediaStreamExtraData*>(description->extraData()); | 340 static_cast<MediaStreamExtraData*>(description->extraData()); |
| 336 extra_data->SetLocalStreamStopCallback(stream_stop); | 341 extra_data->SetLocalStreamStopCallback(stream_stop); |
| 337 } | 342 } |
| 338 | 343 |
| 339 bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { | 344 bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { |
| 345 DVLOG(1) << "MediaStreamDependencyFactory::CreatePeerConnectionFactory()"; |
| 340 if (!pc_factory_.get()) { | 346 if (!pc_factory_.get()) { |
| 341 DCHECK(!audio_device_); | 347 DCHECK(!audio_device_); |
| 342 audio_device_ = new WebRtcAudioDeviceImpl(); | 348 audio_device_ = new WebRtcAudioDeviceImpl(); |
| 343 scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory( | 349 scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory( |
| 344 webrtc::CreatePeerConnectionFactory(worker_thread_, | 350 webrtc::CreatePeerConnectionFactory(worker_thread_, |
| 345 signaling_thread_, | 351 signaling_thread_, |
| 346 audio_device_)); | 352 audio_device_)); |
| 347 if (factory.get()) | 353 if (factory.get()) |
| 348 pc_factory_ = factory; | 354 pc_factory_ = factory; |
| 349 else | 355 else |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 const webrtc::MediaConstraintsInterface* constraints) { | 393 const webrtc::MediaConstraintsInterface* constraints) { |
| 388 RtcVideoCapturer* capturer = new RtcVideoCapturer( | 394 RtcVideoCapturer* capturer = new RtcVideoCapturer( |
| 389 video_session_id, vc_manager_.get(), is_screencast); | 395 video_session_id, vc_manager_.get(), is_screencast); |
| 390 | 396 |
| 391 // The video source takes ownership of |capturer|. | 397 // The video source takes ownership of |capturer|. |
| 392 scoped_refptr<webrtc::VideoSourceInterface> source = | 398 scoped_refptr<webrtc::VideoSourceInterface> source = |
| 393 pc_factory_->CreateVideoSource(capturer, constraints).get(); | 399 pc_factory_->CreateVideoSource(capturer, constraints).get(); |
| 394 return source; | 400 return source; |
| 395 } | 401 } |
| 396 | 402 |
| 403 bool MediaStreamDependencyFactory::InitializeAudioSource( |
| 404 const StreamDeviceInfo& device_info) { |
| 405 DVLOG(1) << "MediaStreamDependencyFactory::InitializeAudioSource()"; |
| 406 const MediaStreamDevice device = device_info.device; |
| 407 |
| 408 // Initialize the source using audio parameters for the selected |
| 409 // capture device. |
| 410 WebRtcAudioCapturer* capturer = GetWebRtcAudioDevice()->capturer(); |
| 411 // TODO(henrika): refactor \content\public\common\media_stream_request.h |
| 412 // to allow dependency of media::ChannelLayout and avoid static_cast. |
| 413 if (!capturer->Initialize( |
| 414 static_cast<media::ChannelLayout>(device.channel_layout), |
| 415 device.sample_rate)) |
| 416 return false; |
| 417 |
| 418 // Specify which capture device to use. The acquired session id is used |
| 419 // for identification. |
| 420 // TODO(henrika): the current design does not support a uniqe source |
| 421 // for each audio track. |
| 422 if (device_info.session_id <= 0) |
| 423 return false; |
| 424 |
| 425 capturer->SetDevice(device_info.session_id); |
| 426 return true; |
| 427 } |
| 428 |
| 429 bool MediaStreamDependencyFactory::CreateWebAudioSource( |
| 430 WebKit::WebMediaStreamSource* source) { |
| 431 DVLOG(1) << "MediaStreamDependencyFactory::CreateWebAudioSource()"; |
| 432 DCHECK(GetWebRtcAudioDevice()); |
| 433 |
| 434 // WebAudio needs the WebRtcAudioCapturer to be able to send its data |
| 435 // over a PeerConnection. The microphone source is not utilized in this |
| 436 // case; instead the WebRtcAudioCapturer is driving. |
| 437 WebRtcAudioCapturer* capturer = GetWebRtcAudioDevice()->capturer(); |
| 438 if (!capturer) |
| 439 return false; |
| 440 |
| 441 // TODO(henrika): life-time handling is not perfect here; there is room |
| 442 // for improvements. |
| 443 scoped_refptr<WebAudioCapturerSource> |
| 444 webaudio_capturer_source(new WebAudioCapturerSource(capturer)); |
| 445 source->setExtraData(new content::MediaStreamSourceExtraData( |
| 446 webaudio_capturer_source)); |
| 447 source->addAudioConsumer(webaudio_capturer_source); |
| 448 |
| 449 return true; |
| 450 } |
| 451 |
| 397 scoped_refptr<webrtc::VideoTrackInterface> | 452 scoped_refptr<webrtc::VideoTrackInterface> |
| 398 MediaStreamDependencyFactory::CreateLocalVideoTrack( | 453 MediaStreamDependencyFactory::CreateLocalVideoTrack( |
| 399 const std::string& label, | 454 const std::string& label, |
| 400 webrtc::VideoSourceInterface* source) { | 455 webrtc::VideoSourceInterface* source) { |
| 401 return pc_factory_->CreateVideoTrack(label, source).get(); | 456 return pc_factory_->CreateVideoTrack(label, source).get(); |
| 402 } | 457 } |
| 403 | 458 |
| 404 scoped_refptr<webrtc::LocalAudioTrackInterface> | 459 scoped_refptr<webrtc::LocalAudioTrackInterface> |
| 405 MediaStreamDependencyFactory::CreateLocalAudioTrack( | 460 MediaStreamDependencyFactory::CreateLocalAudioTrack( |
| 406 const std::string& label, | 461 const std::string& label, |
| (...skipping 12 matching lines...) Expand all Loading... |
| 419 int sdp_mline_index, | 474 int sdp_mline_index, |
| 420 const std::string& sdp) { | 475 const std::string& sdp) { |
| 421 return webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, sdp); | 476 return webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, sdp); |
| 422 } | 477 } |
| 423 | 478 |
| 424 WebRtcAudioDeviceImpl* | 479 WebRtcAudioDeviceImpl* |
| 425 MediaStreamDependencyFactory::GetWebRtcAudioDevice() { | 480 MediaStreamDependencyFactory::GetWebRtcAudioDevice() { |
| 426 return audio_device_; | 481 return audio_device_; |
| 427 } | 482 } |
| 428 | 483 |
| 429 void MediaStreamDependencyFactory::SetAudioDeviceSessionId(int session_id) { | |
| 430 audio_device_->SetSessionId(session_id); | |
| 431 } | |
| 432 | |
| 433 void MediaStreamDependencyFactory::InitializeWorkerThread( | 484 void MediaStreamDependencyFactory::InitializeWorkerThread( |
| 434 talk_base::Thread** thread, | 485 talk_base::Thread** thread, |
| 435 base::WaitableEvent* event) { | 486 base::WaitableEvent* event) { |
| 436 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); | 487 jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); |
| 437 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); | 488 jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); |
| 438 *thread = jingle_glue::JingleThreadWrapper::current(); | 489 *thread = jingle_glue::JingleThreadWrapper::current(); |
| 439 event->Signal(); | 490 event->Signal(); |
| 440 } | 491 } |
| 441 | 492 |
| 442 void MediaStreamDependencyFactory::CreateIpcNetworkManagerOnWorkerThread( | 493 void MediaStreamDependencyFactory::CreateIpcNetworkManagerOnWorkerThread( |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 // processed before returning. We wait for the above task to finish before | 572 // processed before returning. We wait for the above task to finish before |
| 522 // letting the the function continue to avoid any potential race issues. | 573 // letting the the function continue to avoid any potential race issues. |
| 523 chrome_worker_thread_.Stop(); | 574 chrome_worker_thread_.Stop(); |
| 524 } else { | 575 } else { |
| 525 NOTREACHED() << "Worker thread not running."; | 576 NOTREACHED() << "Worker thread not running."; |
| 526 } | 577 } |
| 527 } | 578 } |
| 528 } | 579 } |
| 529 | 580 |
| 530 } // namespace content | 581 } // namespace content |
| OLD | NEW |