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