| 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/webaudio_capturer_source.h" |
| 17 #include "content/renderer/media/webrtc_audio_device_impl.h" | 17 #include "content/renderer/media/webrtc_audio_device_impl.h" |
| 18 #include "content/renderer/media/webrtc_uma_histograms.h" | 18 #include "content/renderer/media/webrtc_uma_histograms.h" |
| 19 #include "content/renderer/p2p/ipc_network_manager.h" | 19 #include "content/renderer/p2p/ipc_network_manager.h" |
| 20 #include "content/renderer/p2p/ipc_socket_factory.h" | 20 #include "content/renderer/p2p/ipc_socket_factory.h" |
| 21 #include "content/renderer/p2p/port_allocator.h" | 21 #include "content/renderer/p2p/port_allocator.h" |
| 22 #include "jingle/glue/thread_wrapper.h" | 22 #include "jingle/glue/thread_wrapper.h" |
| 23 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamCompo
nent.h" | 23 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStream.h" |
| 24 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamDescr
iptor.h" | |
| 25 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSourc
e.h" | 24 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamSourc
e.h" |
| 25 #include "third_party/WebKit/Source/Platform/chromium/public/WebMediaStreamTrack
.h" |
| 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" | 26 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" |
| 27 | 27 |
| 28 #if !defined(USE_OPENSSL) | 28 #if !defined(USE_OPENSSL) |
| 29 #include "net/socket/nss_ssl_util.h" | 29 #include "net/socket/nss_ssl_util.h" |
| 30 #endif | 30 #endif |
| 31 | 31 |
| 32 namespace content { | 32 namespace content { |
| 33 | 33 |
| 34 class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { | 34 class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { |
| 35 public: | 35 public: |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 talk_base::NetworkManager* network_manager_; | 78 talk_base::NetworkManager* network_manager_; |
| 79 talk_base::PacketSocketFactory* socket_factory_; | 79 talk_base::PacketSocketFactory* socket_factory_; |
| 80 // Raw ptr to the WebFrame that created the P2PPortAllocatorFactory. | 80 // Raw ptr to the WebFrame that created the P2PPortAllocatorFactory. |
| 81 WebKit::WebFrame* web_frame_; | 81 WebKit::WebFrame* web_frame_; |
| 82 }; | 82 }; |
| 83 | 83 |
| 84 // SourceStateObserver is a help class used for observing the startup state | 84 // SourceStateObserver is a help class used for observing the startup state |
| 85 // transition of webrtc media sources such as a camera or microphone. | 85 // transition of webrtc media sources such as a camera or microphone. |
| 86 // An instance of the object deletes itself after use. | 86 // An instance of the object deletes itself after use. |
| 87 // Usage: | 87 // Usage: |
| 88 // 1. Create an instance of the object with the WebKit::WebMediaStreamDescriptor | 88 // 1. Create an instance of the object with the WebKit::WebMediaStream |
| 89 // the observed sources belongs to a callback. | 89 // the observed sources belongs to a callback. |
| 90 // 2. Add the sources to the observer using AddSource. | 90 // 2. Add the sources to the observer using AddSource. |
| 91 // 3. Call StartObserving() | 91 // 3. Call StartObserving() |
| 92 // 4. The callback will be triggered when all sources have transitioned from | 92 // 4. The callback will be triggered when all sources have transitioned from |
| 93 // webrtc::MediaSourceInterface::kInitializing. | 93 // webrtc::MediaSourceInterface::kInitializing. |
| 94 class SourceStateObserver : public webrtc::ObserverInterface, | 94 class SourceStateObserver : public webrtc::ObserverInterface, |
| 95 public base::NonThreadSafe { | 95 public base::NonThreadSafe { |
| 96 public: | 96 public: |
| 97 SourceStateObserver( | 97 SourceStateObserver( |
| 98 WebKit::WebMediaStreamDescriptor* description, | 98 WebKit::WebMediaStream* description, |
| 99 const MediaStreamDependencyFactory::MediaSourcesCreatedCallback& callback) | 99 const MediaStreamDependencyFactory::MediaSourcesCreatedCallback& callback) |
| 100 : description_(description), | 100 : description_(description), |
| 101 ready_callback_(callback), | 101 ready_callback_(callback), |
| 102 live_(true) { | 102 live_(true) { |
| 103 } | 103 } |
| 104 | 104 |
| 105 void AddSource(webrtc::MediaSourceInterface* source) { | 105 void AddSource(webrtc::MediaSourceInterface* source) { |
| 106 DCHECK(CalledOnValidThread()); | 106 DCHECK(CalledOnValidThread()); |
| 107 switch (source->state()) { | 107 switch (source->state()) { |
| 108 case webrtc::MediaSourceInterface::kInitializing: | 108 case webrtc::MediaSourceInterface::kInitializing: |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 142 } else { | 142 } else { |
| 143 ++it; | 143 ++it; |
| 144 } | 144 } |
| 145 } | 145 } |
| 146 if (sources_.empty()) { | 146 if (sources_.empty()) { |
| 147 ready_callback_.Run(description_, live_); | 147 ready_callback_.Run(description_, live_); |
| 148 delete this; | 148 delete this; |
| 149 } | 149 } |
| 150 } | 150 } |
| 151 | 151 |
| 152 WebKit::WebMediaStreamDescriptor* description_; | 152 WebKit::WebMediaStream* description_; |
| 153 MediaStreamDependencyFactory::MediaSourcesCreatedCallback ready_callback_; | 153 MediaStreamDependencyFactory::MediaSourcesCreatedCallback ready_callback_; |
| 154 bool live_; | 154 bool live_; |
| 155 typedef std::vector<scoped_refptr<webrtc::MediaSourceInterface> > | 155 typedef std::vector<scoped_refptr<webrtc::MediaSourceInterface> > |
| 156 ObservedSources; | 156 ObservedSources; |
| 157 ObservedSources sources_; | 157 ObservedSources sources_; |
| 158 }; | 158 }; |
| 159 | 159 |
| 160 MediaStreamDependencyFactory::MediaStreamDependencyFactory( | 160 MediaStreamDependencyFactory::MediaStreamDependencyFactory( |
| 161 VideoCaptureImplManager* vc_manager, | 161 VideoCaptureImplManager* vc_manager, |
| 162 P2PSocketDispatcher* p2p_socket_dispatcher) | 162 P2PSocketDispatcher* p2p_socket_dispatcher) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 182 | 182 |
| 183 if (!EnsurePeerConnectionFactory()) | 183 if (!EnsurePeerConnectionFactory()) |
| 184 return NULL; | 184 return NULL; |
| 185 | 185 |
| 186 return new RTCPeerConnectionHandler(client, this); | 186 return new RTCPeerConnectionHandler(client, this); |
| 187 } | 187 } |
| 188 | 188 |
| 189 void MediaStreamDependencyFactory::CreateNativeMediaSources( | 189 void MediaStreamDependencyFactory::CreateNativeMediaSources( |
| 190 const WebKit::WebMediaConstraints& audio_constraints, | 190 const WebKit::WebMediaConstraints& audio_constraints, |
| 191 const WebKit::WebMediaConstraints& video_constraints, | 191 const WebKit::WebMediaConstraints& video_constraints, |
| 192 WebKit::WebMediaStreamDescriptor* description, | 192 WebKit::WebMediaStream* description, |
| 193 const MediaSourcesCreatedCallback& sources_created) { | 193 const MediaSourcesCreatedCallback& sources_created) { |
| 194 DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeMediaSources()"; | 194 DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeMediaSources()"; |
| 195 if (!EnsurePeerConnectionFactory()) { | 195 if (!EnsurePeerConnectionFactory()) { |
| 196 sources_created.Run(description, false); | 196 sources_created.Run(description, false); |
| 197 return; | 197 return; |
| 198 } | 198 } |
| 199 | 199 |
| 200 // |source_observer| clean up itself when it has completed | 200 // |source_observer| clean up itself when it has completed |
| 201 // source_observer->StartObservering. | 201 // source_observer->StartObservering. |
| 202 SourceStateObserver* source_observer = | 202 SourceStateObserver* source_observer = |
| 203 new SourceStateObserver(description, sources_created); | 203 new SourceStateObserver(description, sources_created); |
| 204 | 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::WebMediaStreamTrack> 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 CreateLocalVideoSource(source_data->device_info().session_id, | 221 CreateLocalVideoSource(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 | 226 |
| 227 // Do additional source initialization if the audio source is a valid | 227 // Do additional source initialization if the audio source is a valid |
| 228 // microphone or tab audio. | 228 // microphone or tab audio. |
| 229 RTCMediaConstraints native_audio_constraints(audio_constraints); | 229 RTCMediaConstraints native_audio_constraints(audio_constraints); |
| 230 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; | 230 WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_components; |
| 231 description->audioSources(audio_components); | 231 description->audioSources(audio_components); |
| 232 for (size_t i = 0; i < audio_components.size(); ++i) { | 232 for (size_t i = 0; i < audio_components.size(); ++i) { |
| 233 const WebKit::WebMediaStreamSource& source = audio_components[i].source(); | 233 const WebKit::WebMediaStreamSource& source = audio_components[i].source(); |
| 234 MediaStreamSourceExtraData* source_data = | 234 MediaStreamSourceExtraData* source_data = |
| 235 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 235 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| 236 if (!source_data) { | 236 if (!source_data) { |
| 237 // TODO(henrika): Implement support for sources from remote MediaStreams. | 237 // TODO(henrika): Implement support for sources from remote MediaStreams. |
| 238 NOTIMPLEMENTED(); | 238 NOTIMPLEMENTED(); |
| 239 continue; | 239 continue; |
| 240 } | 240 } |
| (...skipping 10 matching lines...) Expand all Loading... |
| 251 // Creates a LocalAudioSource object which holds audio options. | 251 // Creates a LocalAudioSource object which holds audio options. |
| 252 source_data->SetLocalAudioSource( | 252 source_data->SetLocalAudioSource( |
| 253 CreateLocalAudioSource(&native_audio_constraints)); | 253 CreateLocalAudioSource(&native_audio_constraints)); |
| 254 source_observer->AddSource(source_data->local_audio_source()); | 254 source_observer->AddSource(source_data->local_audio_source()); |
| 255 } | 255 } |
| 256 | 256 |
| 257 source_observer->StartObservering(); | 257 source_observer->StartObservering(); |
| 258 } | 258 } |
| 259 | 259 |
| 260 void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( | 260 void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( |
| 261 WebKit::WebMediaStreamDescriptor* description) { | 261 WebKit::WebMediaStream* description) { |
| 262 DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeLocalMediaStream()"; | 262 DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeLocalMediaStream()"; |
| 263 if (!EnsurePeerConnectionFactory()) { | 263 if (!EnsurePeerConnectionFactory()) { |
| 264 DVLOG(1) << "EnsurePeerConnectionFactory() failed!"; | 264 DVLOG(1) << "EnsurePeerConnectionFactory() failed!"; |
| 265 return; | 265 return; |
| 266 } | 266 } |
| 267 | 267 |
| 268 std::string label = UTF16ToUTF8(description->label()); | 268 std::string label = UTF16ToUTF8(description->label()); |
| 269 scoped_refptr<webrtc::LocalMediaStreamInterface> native_stream = | 269 scoped_refptr<webrtc::LocalMediaStreamInterface> native_stream = |
| 270 CreateLocalMediaStream(label); | 270 CreateLocalMediaStream(label); |
| 271 | 271 |
| 272 // Add audio tracks. | 272 // Add audio tracks. |
| 273 WebKit::WebVector<WebKit::WebMediaStreamComponent> audio_components; | 273 WebKit::WebVector<WebKit::WebMediaStreamTrack> audio_components; |
| 274 description->audioSources(audio_components); | 274 description->audioSources(audio_components); |
| 275 | 275 |
| 276 for (size_t i = 0; i < audio_components.size(); ++i) { | 276 for (size_t i = 0; i < audio_components.size(); ++i) { |
| 277 WebKit::WebMediaStreamSource source = audio_components[i].source(); | 277 WebKit::WebMediaStreamSource source = audio_components[i].source(); |
| 278 | 278 |
| 279 // See if we're adding a WebAudio MediaStream. | 279 // See if we're adding a WebAudio MediaStream. |
| 280 if (source.requiresAudioConsumer()) { | 280 if (source.requiresAudioConsumer()) { |
| 281 // TODO(crogers, xians): In reality we should be able to send a unique | 281 // TODO(crogers, xians): In reality we should be able to send a unique |
| 282 // audio stream to each PeerConnection separately. But currently WebRTC | 282 // audio stream to each PeerConnection separately. But currently WebRTC |
| 283 // is only able to handle a global audio stream sent to ALL peers. | 283 // is only able to handle a global audio stream sent to ALL peers. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 306 | 306 |
| 307 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( | 307 scoped_refptr<webrtc::LocalAudioTrackInterface> audio_track( |
| 308 CreateLocalAudioTrack(UTF16ToUTF8(source.id()), | 308 CreateLocalAudioTrack(UTF16ToUTF8(source.id()), |
| 309 source_data->local_audio_source())); | 309 source_data->local_audio_source())); |
| 310 native_stream->AddTrack(audio_track); | 310 native_stream->AddTrack(audio_track); |
| 311 audio_track->set_enabled(audio_components[i].isEnabled()); | 311 audio_track->set_enabled(audio_components[i].isEnabled()); |
| 312 } | 312 } |
| 313 } | 313 } |
| 314 | 314 |
| 315 // Add video tracks. | 315 // Add video tracks. |
| 316 WebKit::WebVector<WebKit::WebMediaStreamComponent> video_components; | 316 WebKit::WebVector<WebKit::WebMediaStreamTrack> video_components; |
| 317 description->videoSources(video_components); | 317 description->videoSources(video_components); |
| 318 for (size_t i = 0; i < video_components.size(); ++i) { | 318 for (size_t i = 0; i < video_components.size(); ++i) { |
| 319 const WebKit::WebMediaStreamSource& source = video_components[i].source(); | 319 const WebKit::WebMediaStreamSource& source = video_components[i].source(); |
| 320 MediaStreamSourceExtraData* source_data = | 320 MediaStreamSourceExtraData* source_data = |
| 321 static_cast<MediaStreamSourceExtraData*>(source.extraData()); | 321 static_cast<MediaStreamSourceExtraData*>(source.extraData()); |
| 322 if (!source_data || !source_data->video_source()) { | 322 if (!source_data || !source_data->video_source()) { |
| 323 // TODO(perkj): Implement support for sources from remote MediaStreams. | 323 // TODO(perkj): Implement support for sources from remote MediaStreams. |
| 324 NOTIMPLEMENTED(); | 324 NOTIMPLEMENTED(); |
| 325 continue; | 325 continue; |
| 326 } | 326 } |
| 327 | 327 |
| 328 scoped_refptr<webrtc::VideoTrackInterface> video_track( | 328 scoped_refptr<webrtc::VideoTrackInterface> video_track( |
| 329 CreateLocalVideoTrack(UTF16ToUTF8(source.id()), | 329 CreateLocalVideoTrack(UTF16ToUTF8(source.id()), |
| 330 source_data->video_source())); | 330 source_data->video_source())); |
| 331 | 331 |
| 332 native_stream->AddTrack(video_track); | 332 native_stream->AddTrack(video_track); |
| 333 video_track->set_enabled(video_components[i].isEnabled()); | 333 video_track->set_enabled(video_components[i].isEnabled()); |
| 334 } | 334 } |
| 335 | 335 |
| 336 MediaStreamExtraData* extra_data = new MediaStreamExtraData(native_stream); | 336 MediaStreamExtraData* extra_data = new MediaStreamExtraData(native_stream); |
| 337 description->setExtraData(extra_data); | 337 description->setExtraData(extra_data); |
| 338 } | 338 } |
| 339 | 339 |
| 340 void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( | 340 void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( |
| 341 WebKit::WebMediaStreamDescriptor* description, | 341 WebKit::WebMediaStream* description, |
| 342 const MediaStreamExtraData::StreamStopCallback& stream_stop) { | 342 const MediaStreamExtraData::StreamStopCallback& stream_stop) { |
| 343 CreateNativeLocalMediaStream(description); | 343 CreateNativeLocalMediaStream(description); |
| 344 | 344 |
| 345 MediaStreamExtraData* extra_data = | 345 MediaStreamExtraData* extra_data = |
| 346 static_cast<MediaStreamExtraData*>(description->extraData()); | 346 static_cast<MediaStreamExtraData*>(description->extraData()); |
| 347 extra_data->SetLocalStreamStopCallback(stream_stop); | 347 extra_data->SetLocalStreamStopCallback(stream_stop); |
| 348 } | 348 } |
| 349 | 349 |
| 350 bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { | 350 bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { |
| 351 DVLOG(1) << "MediaStreamDependencyFactory::CreatePeerConnectionFactory()"; | 351 DVLOG(1) << "MediaStreamDependencyFactory::CreatePeerConnectionFactory()"; |
| (...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 586 // processed before returning. We wait for the above task to finish before | 586 // processed before returning. We wait for the above task to finish before |
| 587 // letting the the function continue to avoid any potential race issues. | 587 // letting the the function continue to avoid any potential race issues. |
| 588 chrome_worker_thread_.Stop(); | 588 chrome_worker_thread_.Stop(); |
| 589 } else { | 589 } else { |
| 590 NOTREACHED() << "Worker thread not running."; | 590 NOTREACHED() << "Worker thread not running."; |
| 591 } | 591 } |
| 592 } | 592 } |
| 593 } | 593 } |
| 594 | 594 |
| 595 } // namespace content | 595 } // namespace content |
| OLD | NEW |