15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/media_stream_dependency_factory.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/command_line.h" 10868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h" 1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/common/content_switches.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/media_stream_source_extra_data.h" 141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)#include "content/renderer/media/media_stream_track_extra_data.h" 15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "content/renderer/media/media_stream_video_track.h" 16ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch#include "content/renderer/media/peer_connection_identity_service.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/rtc_media_constraints.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/rtc_peer_connection_handler.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/rtc_video_capturer.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "content/renderer/media/rtc_video_decoder_factory.h" 213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "content/renderer/media/rtc_video_encoder_factory.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/video_capture_impl_manager.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "content/renderer/media/webaudio_capturer_source.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/webrtc_audio_device_impl.h" 25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/renderer/media/webrtc_local_audio_track.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/media/webrtc_uma_histograms.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/p2p/ipc_network_manager.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/p2p/ipc_socket_factory.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/renderer/p2p/port_allocator.h" 3090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/renderer/render_thread_impl.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "jingle/glue/thread_wrapper.h" 323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "media/filters/gpu_video_accelerator_factories.h" 33868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebMediaConstraints.h" 34868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebMediaStream.h" 35868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebMediaStreamSource.h" 36868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebMediaStreamTrack.h" 37868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "third_party/WebKit/public/platform/WebURL.h" 387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebDocument.h" 397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "third_party/WebKit/public/web/WebFrame.h" 40eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "third_party/libjingle/source/talk/app/webrtc/mediaconstraintsinterface.h" 41eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_OPENSSL) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "third_party/libjingle/source/talk/base/ssladapter.h" 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/nss_ssl_util.h" 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 48868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(GOOGLE_TV) 49868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "content/renderer/media/rtc_video_decoder_factory_tv.h" 50868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 51868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_ANDROID) 53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "media/base/android/media_codec_bridge.h" 54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// Constant constraint keys which enables default audio constraints on 59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)// mediastreams with audio. 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct { 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* key; 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const char* value; 63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)} const kDefaultAudioConstraints[] = { 64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { webrtc::MediaConstraintsInterface::kEchoCancellation, 65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::MediaConstraintsInterface::kValueTrue }, 664e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#if defined(OS_CHROMEOS) || defined(OS_MACOSX) 674e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) // Enable the extended filter mode AEC on platforms with known echo issues. 684e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { webrtc::MediaConstraintsInterface::kExperimentalEchoCancellation, 694e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) webrtc::MediaConstraintsInterface::kValueTrue }, 704e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#endif 71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { webrtc::MediaConstraintsInterface::kAutoGainControl, 72d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::MediaConstraintsInterface::kValueTrue }, 734e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) { webrtc::MediaConstraintsInterface::kExperimentalAutoGainControl, 744e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) webrtc::MediaConstraintsInterface::kValueTrue }, 75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { webrtc::MediaConstraintsInterface::kNoiseSuppression, 76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::MediaConstraintsInterface::kValueTrue }, 77d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) { webrtc::MediaConstraintsInterface::kHighpassFilter, 78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webrtc::MediaConstraintsInterface::kValueTrue }, 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 81d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// Map of corresponding media constraints and platform effects. 82d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)struct { 83d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const char* constraint; 84d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) const media::AudioParameters::PlatformEffectsMask effect; 85d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)} const kConstraintEffectMap[] = { 86d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) { webrtc::MediaConstraintsInterface::kEchoCancellation, 87d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) media::AudioParameters::ECHO_CANCELLER}, 88d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)}; 89d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// Merge |constraints| with |kDefaultAudioConstraints|. For any key which exists 914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// in both, the value from |constraints| is maintained, including its 924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// mandatory/optional status. New values from |kDefaultAudioConstraints| will 934e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)// be added with mandatory status. 94d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)void ApplyFixedAudioConstraints(RTCMediaConstraints* constraints) { 95d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kDefaultAudioConstraints); ++i) { 964e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) bool already_set_value; 974e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (!webrtc::FindConstraint(constraints, kDefaultAudioConstraints[i].key, 984e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) &already_set_value, NULL)) { 99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) constraints->AddMandatory(kDefaultAudioConstraints[i].key, 100d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) kDefaultAudioConstraints[i].value, false); 101d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } else { 102d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DVLOG(1) << "Constraint " << kDefaultAudioConstraints[i].key 1034e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) << " already set to " << already_set_value; 104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 10658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)} 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class P2PPortAllocatorFactory : public webrtc::PortAllocatorFactoryInterface { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) P2PPortAllocatorFactory( 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) P2PSocketDispatcher* socket_dispatcher, 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) talk_base::NetworkManager* network_manager, 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) talk_base::PacketSocketFactory* socket_factory, 114f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebFrame* web_frame) 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : socket_dispatcher_(socket_dispatcher), 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_manager_(network_manager), 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_factory_(socket_factory), 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_frame_(web_frame) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual cricket::PortAllocator* CreatePortAllocator( 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<StunConfiguration>& stun_servers, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::vector<TurnConfiguration>& turn_configurations) OVERRIDE { 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(web_frame_); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) P2PPortAllocator::Config config; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stun_servers.size() > 0) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.stun_server = stun_servers[0].server.hostname(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) config.stun_server_port = stun_servers[0].server.port(); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 130eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch config.legacy_relay = false; 131eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch for (size_t i = 0; i < turn_configurations.size(); ++i) { 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch P2PPortAllocator::Config::RelayServerConfig relay_config; 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch relay_config.server_address = turn_configurations[i].server.hostname(); 134eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch relay_config.port = turn_configurations[i].server.port(); 135eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch relay_config.username = turn_configurations[i].username; 136eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch relay_config.password = turn_configurations[i].password; 137eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch relay_config.transport_type = turn_configurations[i].transport_type; 138c2db58bd994c04d98e4ee2cd7565b71548655fe3Ben Murdoch relay_config.secure = turn_configurations[i].secure; 139eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch config.relays.push_back(relay_config); 140eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch } 141eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 142eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch // Use first turn server as the stun server. 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (turn_configurations.size() > 0) { 144eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch config.stun_server = config.relays[0].server_address; 145eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch config.stun_server_port = config.relays[0].port; 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 148eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch return new P2PPortAllocator( 149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch web_frame_, socket_dispatcher_.get(), network_manager_, 150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch socket_factory_, config); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~P2PPortAllocatorFactory() {} 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<P2PSocketDispatcher> socket_dispatcher_; 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |network_manager_| and |socket_factory_| are a weak references, owned by 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // MediaStreamDependencyFactory. 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) talk_base::NetworkManager* network_manager_; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) talk_base::PacketSocketFactory* socket_factory_; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Raw ptr to the WebFrame that created the P2PPortAllocatorFactory. 163f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebFrame* web_frame_; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SourceStateObserver is a help class used for observing the startup state 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// transition of webrtc media sources such as a camera or microphone. 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// An instance of the object deletes itself after use. 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Usage: 170f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)// 1. Create an instance of the object with the blink::WebMediaStream 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the observed sources belongs to a callback. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2. Add the sources to the observer using AddSource. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3. Call StartObserving() 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 4. The callback will be triggered when all sources have transitioned from 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// webrtc::MediaSourceInterface::kInitializing. 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SourceStateObserver : public webrtc::ObserverInterface, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public base::NonThreadSafe { 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceStateObserver( 180f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStream* web_stream, 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MediaStreamDependencyFactory::MediaSourcesCreatedCallback& callback) 182bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch : web_stream_(web_stream), 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ready_callback_(callback), 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) live_(true) { 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddSource(webrtc::MediaSourceInterface* source) { 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (source->state()) { 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case webrtc::MediaSourceInterface::kInitializing: 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sources_.push_back(source); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source->RegisterObserver(this); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case webrtc::MediaSourceInterface::kLive: 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The source is already live so we don't need to wait for it. 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case webrtc::MediaSourceInterface::kEnded: 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The source have already failed. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) live_ = false; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartObservering() { 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIfSourcesAreLive(); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual void OnChanged() OVERRIDE { 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckIfSourcesAreLive(); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckIfSourcesAreLive() { 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObservedSources::iterator it = sources_.begin(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (it != sources_.end()) { 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((*it)->state() != webrtc::MediaSourceInterface::kInitializing) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) live_ &= (*it)->state() == webrtc::MediaSourceInterface::kLive; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (*it)->UnregisterObserver(this); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it = sources_.erase(it); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++it; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sources_.empty()) { 229bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch ready_callback_.Run(web_stream_, live_); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete this; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 234f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStream* web_stream_; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStreamDependencyFactory::MediaSourcesCreatedCallback ready_callback_; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool live_; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::vector<scoped_refptr<webrtc::MediaSourceInterface> > 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObservedSources; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ObservedSources sources_; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDependencyFactory::MediaStreamDependencyFactory( 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) VideoCaptureImplManager* vc_manager, 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) P2PSocketDispatcher* p2p_socket_dispatcher) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : network_manager_(NULL), 246868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#if defined(GOOGLE_TV) 247868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) decoder_factory_tv_(NULL), 248868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) vc_manager_(vc_manager), 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_socket_dispatcher_(p2p_socket_dispatcher), 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaling_thread_(NULL), 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) worker_thread_(NULL), 253868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) chrome_worker_thread_("Chrome_libJingle_WorkerThread") { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDependencyFactory::~MediaStreamDependencyFactory() { 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CleanupPeerConnectionFactory(); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 260f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)blink::WebRTCPeerConnectionHandler* 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDependencyFactory::CreateRTCPeerConnectionHandler( 262f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebRTCPeerConnectionHandlerClient* client) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Save histogram data so we can see how much PeerConnetion is used. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The histogram counts the number of calls to the JS API 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // webKitRTCPeerConnection. 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UpdateWebRTCMethodCount(WEBKIT_RTC_PEER_CONNECTION); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EnsurePeerConnectionFactory()) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new RTCPeerConnectionHandler(client, this); 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamDependencyFactory::CreateNativeMediaSources( 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) int render_view_id, 276f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaConstraints& audio_constraints, 277f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaConstraints& video_constraints, 278f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStream* web_stream, 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const MediaSourcesCreatedCallback& sources_created) { 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeMediaSources()"; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EnsurePeerConnectionFactory()) { 282bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch sources_created.Run(web_stream, false); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // |source_observer| clean up itself when it has completed 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // source_observer->StartObservering. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SourceStateObserver* source_observer = 289bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch new SourceStateObserver(web_stream, sources_created); 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create local video sources. 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RTCMediaConstraints native_video_constraints(video_constraints); 293f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebVector<blink::WebMediaStreamTrack> video_tracks; 294bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch web_stream->videoTracks(video_tracks); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < video_tracks.size(); ++i) { 296f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStreamSource& source = video_tracks[i].source(); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStreamSourceExtraData* source_data = 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<MediaStreamSourceExtraData*>(source.extraData()); 2998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Check if the source has already been created. This happens when the same 3018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // source is used in multiple MediaStreams as a result of calling 3028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // getUserMedia. 3038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (source_data->video_source()) 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 3058bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const bool is_screencast = 307d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) source_data->device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE || 308d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) source_data->device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_data->SetVideoSource( 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateLocalVideoSource(source_data->device_info().session_id, 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) is_screencast, 3127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) &native_video_constraints).get()); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_observer->AddSource(source_data->video_source()); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Do additional source initialization if the audio source is a valid 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // microphone or tab audio. 3182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) RTCMediaConstraints native_audio_constraints(audio_constraints); 319d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) ApplyFixedAudioConstraints(&native_audio_constraints); 320f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; 321bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch web_stream->audioTracks(audio_tracks); 3222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < audio_tracks.size(); ++i) { 323f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStreamSource& source = audio_tracks[i].source(); 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MediaStreamSourceExtraData* source_data = 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<MediaStreamSourceExtraData*>(source.extraData()); 3268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 3278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // Check if the source has already been created. This happens when the same 3288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // source is used in multiple MediaStreams as a result of calling 3298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // getUserMedia. 3308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) if (source_data->local_audio_source()) 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) continue; 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 333bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // TODO(xians): Create a new capturer for difference microphones when we 334bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // support multiple microphones. See issue crbug/262117 . 335d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) StreamDeviceInfo device_info = source_data->device_info(); 336d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) RTCMediaConstraints constraints = native_audio_constraints; 337d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 338d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // If any platform effects are available, check them against the 339d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // constraints. Disable effects to match false constraints, but if a 340d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // constraint is true, set the constraint to false to later disable the 341d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // software effect. 342d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) int effects = device_info.device.input.effects; 343d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (effects != media::AudioParameters::NO_EFFECTS) { 344d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kConstraintEffectMap); ++i) { 345d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) bool value; 346d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) if (!webrtc::FindConstraint(&constraints, 347d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) kConstraintEffectMap[i].constraint, &value, NULL) || !value) { 348d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // If the constraint is false, or does not exist, disable the platform 349d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // effect. 350d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) effects &= ~kConstraintEffectMap[i].effect; 351d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) DVLOG(1) << "Disabling constraint: " 352d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) << kConstraintEffectMap[i].constraint; 353d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } else if (effects & kConstraintEffectMap[i].effect) { 354d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // If the constraint is true, leave the platform effect enabled, and 355d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) // set the constraint to false to later disable the software effect. 356d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) constraints.AddMandatory(kConstraintEffectMap[i].constraint, 357d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) webrtc::MediaConstraintsInterface::kValueFalse, true); 358d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) DVLOG(1) << "Disabling platform effect: " 359d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) << kConstraintEffectMap[i].constraint; 360d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 361d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 362d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) device_info.device.input.effects = effects; 363d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) } 364d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) 365bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcAudioCapturer> capturer( 366bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch MaybeCreateAudioCapturer(render_view_id, device_info)); 367bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!capturer.get()) { 368bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch DLOG(WARNING) << "Failed to create the capturer for device " 369bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch << device_info.device.id; 370bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch sources_created.Run(web_stream, false); 37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // TODO(xians): Don't we need to check if source_observer is observing 37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // something? If not, then it looks like we have a leak here. 37358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // OTOH, if it _is_ observing something, then the callback might 37458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // be called multiple times which is likely also a bug. 375bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return; 37690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 3778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) source_data->SetAudioCapturer(capturer); 37890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates a LocalAudioSource object which holds audio options. 380bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // TODO(xians): The option should apply to the track instead of the source. 3812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source_data->SetLocalAudioSource( 382d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) CreateLocalAudioSource(&constraints).get()); 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source_observer->AddSource(source_data->local_audio_source()); 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) source_observer->StartObservering(); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( 390f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStream* web_stream) { 3912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "MediaStreamDependencyFactory::CreateNativeLocalMediaStream()"; 3922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!EnsurePeerConnectionFactory()) { 393c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DVLOG(1) << "EnsurePeerConnectionFactory() failed!"; 394c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 3952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 397bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch std::string label = UTF16ToUTF8(web_stream->id()); 3982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<webrtc::MediaStreamInterface> native_stream = 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CreateLocalMediaStream(label); 400868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) MediaStreamExtraData* extra_data = 401868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new MediaStreamExtraData(native_stream.get(), true); 402bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch web_stream->setExtraData(extra_data); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add audio tracks. 405f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebVector<blink::WebMediaStreamTrack> audio_tracks; 406bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch web_stream->audioTracks(audio_tracks); 4072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (size_t i = 0; i < audio_tracks.size(); ++i) { 408bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch AddNativeMediaStreamTrack(*web_stream, audio_tracks[i]); 409c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 410c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 411c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add video tracks. 412f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebVector<blink::WebMediaStreamTrack> video_tracks; 413bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch web_stream->videoTracks(video_tracks); 414c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) for (size_t i = 0; i < video_tracks.size(); ++i) { 415bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch AddNativeMediaStreamTrack(*web_stream, video_tracks[i]); 416c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 417c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 419c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void MediaStreamDependencyFactory::CreateNativeLocalMediaStream( 420f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStream* web_stream, 421c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const MediaStreamExtraData::StreamStopCallback& stream_stop) { 422bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch CreateNativeLocalMediaStream(web_stream); 423c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 424c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MediaStreamExtraData* extra_data = 425bbcdd45c55eb7c4641ab97aef9889b0fc828e7d3Ben Murdoch static_cast<MediaStreamExtraData*>(web_stream->extraData()); 426c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) extra_data->SetLocalStreamStopCallback(stream_stop); 427c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 428c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<webrtc::AudioTrackInterface> 430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MediaStreamDependencyFactory::CreateNativeAudioMediaStreamTrack( 431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStreamTrack& track) { 432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamSource source = track.source(); 433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(source.type(), blink::WebMediaStreamSource::TypeAudio); 434c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) MediaStreamSourceExtraData* source_data = 435c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<MediaStreamSourceExtraData*>(source.extraData()); 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 43758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // In the future the constraints will belong to the track itself, but 43858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // right now they're on the source, so we fetch them from there. 43958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints track_constraints(source.constraints()); 44058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 441f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Apply default audio constraints that enable echo cancellation, 442f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // automatic gain control, noise suppression and high-pass filter. 443f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) ApplyFixedAudioConstraints(&track_constraints); 444d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 445d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<WebAudioCapturerSource> webaudio_source; 446c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!source_data) { 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (source.requiresAudioConsumer()) { 448c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // We're adding a WebAudio MediaStream. 449bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Create a specific capturer for each WebAudio consumer. 450d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webaudio_source = CreateWebAudioSource(&source, &track_constraints); 451bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch source_data = 452bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch static_cast<MediaStreamSourceExtraData*>(source.extraData()); 453c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } else { 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(perkj): Implement support for sources from 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // remote MediaStreams. 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTIMPLEMENTED(); 457f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 461c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string track_id = UTF16ToUTF8(track.id()); 462f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<WebRtcAudioCapturer> capturer; 463f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (GetWebRtcAudioDevice()) 464f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer = GetWebRtcAudioDevice()->GetDefaultCapturer(); 465f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 466f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<webrtc::AudioTrackInterface> audio_track( 467f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateLocalAudioTrack(track_id, 468f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) capturer, 469f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) webaudio_source.get(), 470f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) source_data->local_audio_source(), 471f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) &track_constraints)); 472a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNativeTrackToBlinkTrack(audio_track.get(), track, true); 473f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 474f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_track->set_enabled(track.isEnabled()); 475f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 476f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Pass the pointer of the source provider to the blink audio track. 477f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamTrack writable_track = track; 478f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) writable_track.setSourceProvider(static_cast<WebRtcLocalAudioTrack*>( 479f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) audio_track.get())->audio_source_provider()); 480f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 481f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return audio_track; 482f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 483f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 484f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<webrtc::VideoTrackInterface> 485f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)MediaStreamDependencyFactory::CreateNativeVideoMediaStreamTrack( 486f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStreamTrack& track) { 487f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamSource source = track.source(); 488f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK_EQ(source.type(), blink::WebMediaStreamSource::TypeVideo); 489f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) MediaStreamSourceExtraData* source_data = 490f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) static_cast<MediaStreamSourceExtraData*>(source.extraData()); 491f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 492f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!source_data) { 493f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // TODO(perkj): Implement support for sources from 494f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // remote MediaStreams. 495f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) NOTIMPLEMENTED(); 496f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return NULL; 497f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 498f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 499f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) std::string track_id = UTF16ToUTF8(track.id()); 500f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<webrtc::VideoTrackInterface> video_track( 501f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateLocalVideoTrack(track_id, source_data->video_source())); 502a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNativeTrackToBlinkTrack(video_track.get(), track, true); 503f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 504f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) video_track->set_enabled(track.isEnabled()); 505f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 506f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return video_track; 507f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 508f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 509f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void MediaStreamDependencyFactory::CreateNativeMediaStreamTrack( 510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStreamTrack& track) { 511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!track.isNull() && !track.extraData()); 512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(!track.source().isNull()); 513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (track.source().type()) { 515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebMediaStreamSource::TypeAudio: 516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateNativeAudioMediaStreamTrack(track); 517f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 518f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebMediaStreamSource::TypeVideo: 519f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) CreateNativeVideoMediaStreamTrack(track); 520f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) break; 521f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 522f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)} 523f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 524f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool MediaStreamDependencyFactory::AddNativeMediaStreamTrack( 525f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStream& stream, 526f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStreamTrack& track) { 527f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) webrtc::MediaStreamInterface* native_stream = GetNativeMediaStream(stream); 528f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(native_stream); 529f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 530f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (track.source().type()) { 531f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebMediaStreamSource::TypeAudio: { 532f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<webrtc::AudioTrackInterface> native_audio_track; 533f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!track.extraData()) { 534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_audio_track = CreateNativeAudioMediaStreamTrack(track); 535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 536f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_audio_track = static_cast<webrtc::AudioTrackInterface*>( 537f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetNativeMediaStreamTrack(track)); 538f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 539f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 540f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return native_audio_track.get() && 541f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_stream->AddTrack(native_audio_track); 542f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 543f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebMediaStreamSource::TypeVideo: { 544f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) scoped_refptr<webrtc::VideoTrackInterface> native_video_track; 545f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) if (!track.extraData()) { 546f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_video_track = CreateNativeVideoMediaStreamTrack(track); 547f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } else { 548f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_video_track = static_cast<webrtc::VideoTrackInterface*>( 549f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetNativeMediaStreamTrack(track)); 550f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) } 551f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) 552f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return native_video_track.get() && 553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_stream->AddTrack(native_video_track); 554d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 555c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 556f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 557c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 559c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDependencyFactory::AddNativeVideoMediaTrack( 560c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& track_id, 561f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStream* stream, 562c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) cricket::VideoCapturer* capturer) { 563c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!stream) { 564c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "AddNativeVideoMediaTrack called with null WebMediaStream."; 565c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 568c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create native track from the source. 569c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<webrtc::VideoTrackInterface> native_track = 570c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CreateLocalVideoTrack(track_id, capturer); 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 572c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add the native track to native stream 573f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) webrtc::MediaStreamInterface* native_stream = 574f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) GetNativeMediaStream(*stream); 575f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) DCHECK(native_stream); 576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) native_stream->AddTrack(native_track.get()); 577c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 578c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create a new webkit video track. 579f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamTrack webkit_track; 580f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamSource webkit_source; 581f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebString webkit_track_id(UTF8ToUTF16(track_id)); 582f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamSource::Type type = 583f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamSource::TypeVideo; 584c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) webkit_source.initialize(webkit_track_id, type, webkit_track_id); 5851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 586c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) webkit_track.initialize(webkit_track_id, webkit_source); 587a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) AddNativeTrackToBlinkTrack(native_track.get(), webkit_track, true); 588c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 589c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Add the track to WebMediaStream. 590c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) stream->addTrack(webkit_track); 591c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return true; 592c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 594c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool MediaStreamDependencyFactory::RemoveNativeMediaStreamTrack( 595f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStream& stream, 596f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStreamTrack& track) { 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MediaStreamExtraData* extra_data = 598c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) static_cast<MediaStreamExtraData*>(stream.extraData()); 599868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) webrtc::MediaStreamInterface* native_stream = extra_data->stream().get(); 600c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK(native_stream); 601c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string track_id = UTF16ToUTF8(track.id()); 602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) switch (track.source().type()) { 603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebMediaStreamSource::TypeAudio: 604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return native_stream->RemoveTrack( 605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_stream->FindAudioTrack(track_id)); 606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) case blink::WebMediaStreamSource::TypeVideo: 607f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return native_stream->RemoveTrack( 608f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) native_stream->FindVideoTrack(track_id)); 609d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) } 610f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) return false; 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MediaStreamDependencyFactory::CreatePeerConnectionFactory() { 6140f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(!pc_factory_.get()); 6150f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) DCHECK(!audio_device_.get()); 6162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "MediaStreamDependencyFactory::CreatePeerConnectionFactory()"; 617868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6180f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<cricket::WebRtcVideoDecoderFactory> decoder_factory; 6190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_ptr<cricket::WebRtcVideoEncoderFactory> encoder_factory; 620eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch 6210f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) const CommandLine* cmd_line = CommandLine::ForCurrentProcess(); 6220f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_refptr<RendererGpuVideoAcceleratorFactories> gpu_factories = 6230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) RenderThreadImpl::current()->GetGpuFactories(); 6243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if !defined(GOOGLE_TV) 6250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!cmd_line->HasSwitch(switches::kDisableWebRtcHWDecoding)) { 6260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (gpu_factories) 6270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) decoder_factory.reset(new RTCVideoDecoderFactory(gpu_factories)); 6280f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 6293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#else 6300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // PeerConnectionFactory will hold the ownership of this 6310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) // VideoDecoderFactory. 6320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) decoder_factory.reset(decoder_factory_tv_ = new RTCVideoDecoderFactoryTv()); 633868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#endif 634868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 6350f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!cmd_line->HasSwitch(switches::kDisableWebRtcHWEncoding)) { 6360f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (gpu_factories) 6370f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) encoder_factory.reset(new RTCVideoEncoderFactory(gpu_factories)); 6380f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) } 6393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#if defined(OS_ANDROID) 641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!media::MediaCodecBridge::IsAvailable() || 642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) !media::MediaCodecBridge::SupportsSetParameters()) { 643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) encoder_factory.reset(); 644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 645a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#endif 646a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 6470f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_refptr<WebRtcAudioDeviceImpl> audio_device( 6480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) new WebRtcAudioDeviceImpl()); 6490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 6500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) scoped_refptr<webrtc::PeerConnectionFactoryInterface> factory( 6510f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) webrtc::CreatePeerConnectionFactory(worker_thread_, 6520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) signaling_thread_, 6530f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) audio_device.get(), 6540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) encoder_factory.release(), 6550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) decoder_factory.release())); 6560f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) if (!factory.get()) { 6570f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return false; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) 6600f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) audio_device_ = audio_device; 6610f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) pc_factory_ = factory; 6620f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) webrtc::PeerConnectionFactoryInterface::Options factory_options; 6637da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles) factory_options.enable_aec_dump = 6647da551c69e84cdee501ba0193ee132bc3b5b2c1dTorne (Richard Coles) cmd_line->HasSwitch(switches::kEnableWebRtcAecRecordings); 6650f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) factory_options.disable_sctp_data_channels = 6660f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) cmd_line->HasSwitch(switches::kDisableSCTPDataChannels); 6670f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) factory_options.disable_encryption = 6680f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) cmd_line->HasSwitch(switches::kDisableWebRtcEncryption); 6690f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) pc_factory_->SetOptions(factory_options); 6700f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) return true; 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MediaStreamDependencyFactory::PeerConnectionFactoryCreated() { 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pc_factory_.get() != NULL; 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<webrtc::PeerConnectionInterface> 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDependencyFactory::CreatePeerConnection( 6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const webrtc::PeerConnectionInterface::IceServers& ice_servers, 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const webrtc::MediaConstraintsInterface* constraints, 681f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebFrame* web_frame, 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webrtc::PeerConnectionObserver* observer) { 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(web_frame); 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(observer); 68590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<P2PPortAllocatorFactory> pa_factory = 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new talk_base::RefCountedObject<P2PPortAllocatorFactory>( 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) p2p_socket_dispatcher_.get(), 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_manager_, 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_factory_.get(), 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) web_frame); 692ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 693ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch PeerConnectionIdentityService* identity_service = 6948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) new PeerConnectionIdentityService( 695ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch GURL(web_frame->document().url().spec()).GetOrigin()); 696ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 697ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch return pc_factory_->CreatePeerConnection(ice_servers, 698ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch constraints, 699ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch pa_factory.get(), 700ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch identity_service, 701ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch observer).get(); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<webrtc::MediaStreamInterface> 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDependencyFactory::CreateLocalMediaStream( 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& label) { 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pc_factory_->CreateLocalMediaStream(label).get(); 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<webrtc::AudioSourceInterface> 7112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaStreamDependencyFactory::CreateLocalAudioSource( 7122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const webrtc::MediaConstraintsInterface* constraints) { 7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<webrtc::AudioSourceInterface> source = 7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pc_factory_->CreateAudioSource(constraints).get(); 7152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return source; 7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<webrtc::VideoSourceInterface> 7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaStreamDependencyFactory::CreateLocalVideoSource( 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int video_session_id, 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_screencast, 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const webrtc::MediaConstraintsInterface* constraints) { 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RtcVideoCapturer* capturer = new RtcVideoCapturer( 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) video_session_id, vc_manager_.get(), is_screencast); 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The video source takes ownership of |capturer|. 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<webrtc::VideoSourceInterface> source = 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pc_factory_->CreateVideoSource(capturer, constraints).get(); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return source; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 732d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)scoped_refptr<WebAudioCapturerSource> 733bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochMediaStreamDependencyFactory::CreateWebAudioSource( 734f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamSource* source, 73558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) RTCMediaConstraints* constraints) { 7362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DVLOG(1) << "MediaStreamDependencyFactory::CreateWebAudioSource()"; 7372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(GetWebRtcAudioDevice()); 7382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<WebAudioCapturerSource> 740d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) webaudio_capturer_source(new WebAudioCapturerSource()); 741d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) MediaStreamSourceExtraData* source_data = new MediaStreamSourceExtraData(); 7422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Create a LocalAudioSource object which holds audio options. 744d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // SetLocalAudioSource() affects core audio parts in third_party/Libjingle. 74558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) source_data->SetLocalAudioSource(CreateLocalAudioSource(constraints).get()); 7462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) source->setExtraData(source_data); 7472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Replace the default source with WebAudio as source instead. 749868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) source->addAudioConsumer(webaudio_capturer_source.get()); 7502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 751d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) return webaudio_capturer_source; 7522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 7532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_refptr<webrtc::VideoTrackInterface> 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDependencyFactory::CreateLocalVideoTrack( 7562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) webrtc::VideoSourceInterface* source) { 7582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return pc_factory_->CreateVideoTrack(id, source).get(); 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 761c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_refptr<webrtc::VideoTrackInterface> 762c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)MediaStreamDependencyFactory::CreateLocalVideoTrack( 763c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const std::string& id, cricket::VideoCapturer* capturer) { 764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!capturer) { 765c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(ERROR) << "CreateLocalVideoTrack called with null VideoCapturer."; 766c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return NULL; 767c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 768c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 769c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create video source from the |capturer|. 770c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<webrtc::VideoSourceInterface> source = 771c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) pc_factory_->CreateVideoSource(capturer, NULL).get(); 772c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 773c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Create native track from the source. 774868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return pc_factory_->CreateVideoTrack(id, source.get()).get(); 775c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 776c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 7772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_refptr<webrtc::AudioTrackInterface> 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDependencyFactory::CreateLocalAudioTrack( 7792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& id, 780bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch const scoped_refptr<WebRtcAudioCapturer>& capturer, 781d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebAudioCapturerSource* webaudio_source, 78258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) webrtc::AudioSourceInterface* source, 78358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) const webrtc::MediaConstraintsInterface* constraints) { 784c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // TODO(xians): Merge |source| to the capturer(). We can't do this today 785c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // because only one capturer() is supported while one |source| is created 786c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // for each audio track. 787bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch scoped_refptr<WebRtcLocalAudioTrack> audio_track( 788d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) WebRtcLocalAudioTrack::Create(id, capturer, webaudio_source, 789d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) source, constraints)); 790d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 791bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Add the WebRtcAudioDevice as the sink to the local audio track. 792bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch audio_track->AddSink(GetWebRtcAudioDevice()); 793bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Start the audio track. This will hook the |audio_track| to the capturer 794bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // as the sink of the audio, and only start the source of the capturer if 795bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // it is the first audio track connecting to the capturer. 796bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch audio_track->Start(); 797bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return audio_track; 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)webrtc::SessionDescriptionInterface* 8012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MediaStreamDependencyFactory::CreateSessionDescription( 8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& type, 8032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string& sdp, 8042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) webrtc::SdpParseError* error) { 8052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return webrtc::CreateSessionDescription(type, sdp, error); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)webrtc::IceCandidateInterface* MediaStreamDependencyFactory::CreateIceCandidate( 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sdp_mid, 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int sdp_mline_index, 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& sdp) { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return webrtc::CreateIceCandidate(sdp_mid, sdp_mline_index, sdp); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)WebRtcAudioDeviceImpl* 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)MediaStreamDependencyFactory::GetWebRtcAudioDevice() { 817868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return audio_device_.get(); 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamDependencyFactory::InitializeWorkerThread( 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) talk_base::Thread** thread, 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent* event) { 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *thread = jingle_glue::JingleThreadWrapper::current(); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->Signal(); 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamDependencyFactory::CreateIpcNetworkManagerOnWorkerThread( 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent* event) { 831c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), chrome_worker_thread_.message_loop()); 832868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) network_manager_ = new IpcNetworkManager(p2p_socket_dispatcher_.get()); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event->Signal(); 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamDependencyFactory::DeleteIpcNetworkManager() { 837c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DCHECK_EQ(base::MessageLoop::current(), chrome_worker_thread_.message_loop()); 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete network_manager_; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) network_manager_ = NULL; 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool MediaStreamDependencyFactory::EnsurePeerConnectionFactory() { 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(CalledOnValidThread()); 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (PeerConnectionFactoryCreated()) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!signaling_thread_) { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jingle_glue::JingleThreadWrapper::EnsureForCurrentMessageLoop(); 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) jingle_glue::JingleThreadWrapper::current()->set_send_allowed(true); 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaling_thread_ = jingle_glue::JingleThreadWrapper::current(); 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK(signaling_thread_); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!worker_thread_) { 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!chrome_worker_thread_.IsRunning()) { 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!chrome_worker_thread_.Start()) { 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Could not start worker thread"; 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) signaling_thread_ = NULL; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent event(true, false); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MediaStreamDependencyFactory::InitializeWorkerThread, 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &worker_thread_, 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &event)); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Wait(); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(worker_thread_); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!network_manager_) { 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::WaitableEvent event(true, false); 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MediaStreamDependencyFactory::CreateIpcNetworkManagerOnWorkerThread, 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this), 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &event)); 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) event.Wait(); 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!socket_factory_) { 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) socket_factory_.reset( 883868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) new IpcPacketSocketFactory(p2p_socket_dispatcher_.get())); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Init SSL, which will be needed by PeerConnection. 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(USE_OPENSSL) 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!talk_base::InitializeSSL()) { 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(ERROR) << "Failed on InitializeSSL."; 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(ronghuawu): Replace this call with InitializeSSL. 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::EnsureNSSSSLInit(); 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!CreatePeerConnectionFactory()) { 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(ERROR) << "Could not create PeerConnection factory"; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void MediaStreamDependencyFactory::CleanupPeerConnectionFactory() { 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pc_factory_ = NULL; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (network_manager_) { 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The network manager needs to free its resources on the thread they were 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // created, which is the worked thread. 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (chrome_worker_thread_.IsRunning()) { 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_worker_thread_.message_loop()->PostTask(FROM_HERE, base::Bind( 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &MediaStreamDependencyFactory::DeleteIpcNetworkManager, 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stopping the thread will wait until all tasks have been 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // processed before returning. We wait for the above task to finish before 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // letting the the function continue to avoid any potential race issues. 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome_worker_thread_.Stop(); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Worker thread not running."; 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 923bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochscoped_refptr<WebRtcAudioCapturer> 924bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben MurdochMediaStreamDependencyFactory::MaybeCreateAudioCapturer( 925bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch int render_view_id, 926bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch const StreamDeviceInfo& device_info) { 927d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // TODO(xians): Handle the cases when gUM is called without a proper render 928d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) // view, for example, by an extension. 929d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) DCHECK_GE(render_view_id, 0); 930d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 931d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_refptr<WebRtcAudioCapturer> capturer = 932d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) GetWebRtcAudioDevice()->GetDefaultCapturer(); 933d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) 934bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // If the default capturer does not exist or |render_view_id| == -1, create 935bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // a new capturer. 936bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch bool is_new_capturer = false; 937bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!capturer.get()) { 938bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch capturer = WebRtcAudioCapturer::CreateCapturer(); 939bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch is_new_capturer = true; 940bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 941bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 942bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (!capturer->Initialize( 943bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch render_view_id, 94458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static_cast<media::ChannelLayout>( 94558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) device_info.device.input.channel_layout), 94658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) device_info.device.input.sample_rate, 947d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) device_info.device.input.frames_per_buffer, 94858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) device_info.session_id, 9494e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) device_info.device.id, 9504e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) device_info.device.matched_output.sample_rate, 951d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) device_info.device.matched_output.frames_per_buffer, 952d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles) device_info.device.input.effects)) { 953bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return NULL; 954bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch } 955bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 956bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch // Add the capturer to the WebRtcAudioDeviceImpl if it is a new capturer. 957bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch if (is_new_capturer) 958bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch GetWebRtcAudioDevice()->AddAudioCapturer(capturer); 959bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 960bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch return capturer; 961bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch} 962bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch 9631e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void MediaStreamDependencyFactory::AddNativeTrackToBlinkTrack( 9641e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) webrtc::MediaStreamTrackInterface* native_track, 965a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) const blink::WebMediaStreamTrack& webkit_track, 966a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) bool is_local_track) { 9671e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) DCHECK(!webkit_track.isNull() && !webkit_track.extraData()); 968f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) blink::WebMediaStreamTrack track = webkit_track; 969a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) 970a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (track.source().type() == blink::WebMediaStreamSource::TypeVideo) { 971a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) track.setExtraData(new MediaStreamVideoTrack( 972a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) static_cast<webrtc::VideoTrackInterface*>(native_track), 973a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) is_local_track)); 974a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } else { 975a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) track.setExtraData(new MediaStreamTrackExtraData(native_track, 976a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) is_local_track)); 977a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) } 9781e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 9791e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 9801e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)webrtc::MediaStreamInterface* 9811e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)MediaStreamDependencyFactory::GetNativeMediaStream( 982f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStream& stream) { 9831e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (stream.isNull()) 9841e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 9851e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MediaStreamExtraData* extra_data = 9861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static_cast<MediaStreamExtraData*>(stream.extraData()); 9871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return extra_data ? extra_data->stream().get() : NULL; 9881e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 9891e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 9901e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)webrtc::MediaStreamTrackInterface* 9911e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)MediaStreamDependencyFactory::GetNativeMediaStreamTrack( 992f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) const blink::WebMediaStreamTrack& track) { 9931e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) if (track.isNull()) 9941e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return NULL; 9951e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) MediaStreamTrackExtraData* extra_data = 9961e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) static_cast<MediaStreamTrackExtraData*>(track.extraData()); 9971e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) return extra_data ? extra_data->track().get() : NULL; 9981e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)} 9991e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles) 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 1001