(Auto)update libjingle 72785180-> 72785516

git-svn-id: http://webrtc.googlecode.com/svn/trunk/talk@6842 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/libjingle.gyp b/libjingle.gyp
index f14854c..6064277 100755
--- a/libjingle.gyp
+++ b/libjingle.gyp
@@ -480,6 +480,8 @@
         'media/base/cpuid.cc',
         'media/base/cpuid.h',
         'media/base/cryptoparams.h',
+        'media/base/device.h',
+        'media/base/fakescreencapturerfactory.h',
         'media/base/filemediaengine.cc',
         'media/base/filemediaengine.h',
         'media/base/hybriddataengine.h',
@@ -502,6 +504,7 @@
         'media/base/videoadapter.h',
         'media/base/videocapturer.cc',
         'media/base/videocapturer.h',
+        'media/base/videocapturerfactory.h',
         'media/base/videocommon.cc',
         'media/base/videocommon.h',
         'media/base/videoframe.cc',
@@ -533,6 +536,8 @@
         'media/webrtc/webrtctexturevideoframe.cc',
         'media/webrtc/webrtctexturevideoframe.h',
         'media/webrtc/webrtcvideocapturer.cc',
+        'media/webrtc/webrtcvideocapturerfactory.h',
+        'media/webrtc/webrtcvideocapturerfactory.cc',
         'media/webrtc/webrtcvideocapturer.h',
         'media/webrtc/webrtcvideodecoderfactory.h',
         'media/webrtc/webrtcvideoencoderfactory.h',
diff --git a/media/base/device.h b/media/base/device.h
new file mode 100755
index 0000000..ced74c6
--- /dev/null
+++ b/media/base/device.h
@@ -0,0 +1,50 @@
+// libjingle
+// Copyright 2014 Google Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//  3. The name of the author may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#ifndef TALK_MEDIA_BASE_DEVICE_H_
+#define TALK_MEDIA_BASE_DEVICE_H_
+
+#include "webrtc/base/stringencode.h"
+
+namespace cricket {
+
+// Used to represent an audio or video capture or render device.
+struct Device {
+  Device() {}
+  Device(const std::string& name, int id)
+      : name(name),
+        id(rtc::ToString(id)) {
+  }
+  Device(const std::string& name, const std::string& id)
+      : name(name), id(id) {}
+
+  std::string name;
+  std::string id;
+};
+
+}  // namespace cricket
+
+#endif  // TALK_MEDIA_BASE_DEVICE_H_
diff --git a/media/base/fakescreencapturerfactory.h b/media/base/fakescreencapturerfactory.h
new file mode 100755
index 0000000..dfd7376
--- /dev/null
+++ b/media/base/fakescreencapturerfactory.h
@@ -0,0 +1,78 @@
+/*
+ * libjingle
+ * Copyright 2012 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef TALK_MEDIA_BASE_FAKESCREENCAPTURERFACTORY_H_
+#define TALK_MEDIA_BASE_FAKESCREENCAPTURERFACTORY_H_
+
+#include "talk/media/base/fakevideocapturer.h"
+#include "talk/media/base/videocapturerfactory.h"
+
+namespace cricket {
+
+class FakeScreenCapturerFactory
+    : public cricket::ScreenCapturerFactory,
+      public sigslot::has_slots<> {
+ public:
+  FakeScreenCapturerFactory()
+      : window_capturer_(NULL),
+        capture_state_(cricket::CS_STOPPED) {}
+
+  virtual cricket::VideoCapturer* Create(const ScreencastId& window) {
+    if (window_capturer_ != NULL) {
+      return NULL;
+    }
+    window_capturer_ = new cricket::FakeVideoCapturer;
+    window_capturer_->SignalDestroyed.connect(
+        this,
+        &FakeScreenCapturerFactory::OnWindowCapturerDestroyed);
+    window_capturer_->SignalStateChange.connect(
+        this,
+        &FakeScreenCapturerFactory::OnStateChange);
+    return window_capturer_;
+  }
+
+  cricket::FakeVideoCapturer* window_capturer() { return window_capturer_; }
+
+  cricket::CaptureState capture_state() { return capture_state_; }
+
+ private:
+  void OnWindowCapturerDestroyed(cricket::FakeVideoCapturer* capturer) {
+    if (capturer == window_capturer_) {
+      window_capturer_ = NULL;
+    }
+  }
+  void OnStateChange(cricket::VideoCapturer*, cricket::CaptureState state) {
+    capture_state_ = state;
+  }
+
+  cricket::FakeVideoCapturer* window_capturer_;
+  cricket::CaptureState capture_state_;
+};
+
+}  // namespace cricket
+
+#endif  // TALK_MEDIA_BASE_FAKESCREENCAPTURERFACTORY_H_
diff --git a/media/base/videocapturerfactory.h b/media/base/videocapturerfactory.h
new file mode 100755
index 0000000..009a5ee
--- /dev/null
+++ b/media/base/videocapturerfactory.h
@@ -0,0 +1,55 @@
+// libjingle
+// Copyright 2014 Google Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//  3. The name of the author may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+#ifndef TALK_MEDIA_BASE_VIDEOCAPTURERFACTORY_H_
+#define TALK_MEDIA_BASE_VIDEOCAPTURERFACTORY_H_
+
+#include "talk/media/base/device.h"
+#include "talk/media/base/screencastid.h"
+
+namespace cricket {
+
+class VideoCapturer;
+
+class VideoDeviceCapturerFactory {
+ public:
+  VideoDeviceCapturerFactory() {}
+  virtual ~VideoDeviceCapturerFactory() {}
+
+  virtual VideoCapturer* Create(const Device& device) = 0;
+};
+
+class ScreenCapturerFactory {
+ public:
+  ScreenCapturerFactory() {}
+  virtual ~ScreenCapturerFactory() {}
+
+  virtual VideoCapturer* Create(const ScreencastId& screenid) = 0;
+};
+
+}  // namespace cricket
+
+#endif  // TALK_MEDIA_BASE_VIDEOCAPTURERFACTORY_H_
diff --git a/media/devices/devicemanager.cc b/media/devices/devicemanager.cc
index c331adc..9d7a951 100644
--- a/media/devices/devicemanager.cc
+++ b/media/devices/devicemanager.cc
@@ -35,19 +35,14 @@
 #include "webrtc/base/windowpicker.h"
 #include "webrtc/base/windowpickerfactory.h"
 #include "talk/media/base/mediacommon.h"
+#include "talk/media/base/videocapturerfactory.h"
 #include "talk/media/devices/deviceinfo.h"
 #include "talk/media/devices/filevideocapturer.h"
 #include "talk/media/devices/yuvframescapturer.h"
 
-#if defined(HAVE_WEBRTC_VIDEO)
-#include "talk/media/webrtc/webrtcvideocapturer.h"
-#endif
-
-
-#if defined(HAVE_WEBRTC_VIDEO)
-#define VIDEO_CAPTURER_NAME WebRtcVideoCapturer
-#endif
-
+#ifdef HAVE_WEBRTC_VIDEO
+#include "talk/media/webrtc/webrtcvideocapturerfactory.h"
+#endif  // HAVE_WEBRTC_VIDEO
 
 namespace {
 
@@ -64,29 +59,12 @@
 // Initialize to empty string.
 const char DeviceManagerInterface::kDefaultDeviceName[] = "";
 
-class DefaultVideoCapturerFactory : public VideoCapturerFactory {
- public:
-  DefaultVideoCapturerFactory() {}
-  virtual ~DefaultVideoCapturerFactory() {}
-
-  VideoCapturer* Create(const Device& device) {
-#if defined(VIDEO_CAPTURER_NAME)
-    VIDEO_CAPTURER_NAME* return_value = new VIDEO_CAPTURER_NAME;
-    if (!return_value->Init(device)) {
-      delete return_value;
-      return NULL;
-    }
-    return return_value;
-#else
-    return NULL;
-#endif
-  }
-};
-
 DeviceManager::DeviceManager()
     : initialized_(false),
-      device_video_capturer_factory_(new DefaultVideoCapturerFactory),
       window_picker_(rtc::WindowPickerFactory::CreateWindowPicker()) {
+#ifdef HAVE_WEBRTC_VIDEO
+  SetVideoDeviceCapturerFactory(new WebRtcVideoDeviceCapturerFactory());
+#endif  // HAVE_WEBRTC_VIDEO
 }
 
 DeviceManager::~DeviceManager() {
@@ -212,12 +190,16 @@
 }
 
 VideoCapturer* DeviceManager::CreateVideoCapturer(const Device& device) const {
-  VideoCapturer* capturer = ConstructFakeVideoCapturer(device);
+  VideoCapturer* capturer = MaybeConstructFakeVideoCapturer(device);
   if (capturer) {
     return capturer;
   }
 
-  capturer = device_video_capturer_factory_->Create(device);
+  if (!video_device_capturer_factory_) {
+    LOG(LS_ERROR) << "No video capturer factory for devices.";
+    return NULL;
+  }
+  capturer = video_device_capturer_factory_->Create(device);
   if (!capturer) {
     return NULL;
   }
@@ -231,7 +213,7 @@
   return capturer;
 }
 
-VideoCapturer* DeviceManager::ConstructFakeVideoCapturer(
+VideoCapturer* DeviceManager::MaybeConstructFakeVideoCapturer(
     const Device& device) const {
   // TODO(hellner): Throw out the creation of a file video capturer once the
   // refactoring is completed.
@@ -262,19 +244,6 @@
   return window_picker_->GetWindowList(descriptions);
 }
 
-VideoCapturer* DeviceManager::CreateWindowCapturer(rtc::WindowId window) {
-#if defined(WINDOW_CAPTURER_NAME)
-  WINDOW_CAPTURER_NAME* window_capturer = new WINDOW_CAPTURER_NAME();
-  if (!window_capturer->Init(window)) {
-    delete window_capturer;
-    return NULL;
-  }
-  return window_capturer;
-#else
-  return NULL;
-#endif
-}
-
 bool DeviceManager::GetDesktops(
     std::vector<rtc::DesktopDescription>* descriptions) {
   if (!window_picker_) {
@@ -283,18 +252,13 @@
   return window_picker_->GetDesktopList(descriptions);
 }
 
-VideoCapturer* DeviceManager::CreateDesktopCapturer(
-    rtc::DesktopId desktop) {
-#if defined(DESKTOP_CAPTURER_NAME)
-  DESKTOP_CAPTURER_NAME* desktop_capturer = new DESKTOP_CAPTURER_NAME();
-  if (!desktop_capturer->Init(desktop.index())) {
-    delete desktop_capturer;
+VideoCapturer* DeviceManager::CreateScreenCapturer(
+    const ScreencastId& screenid) const {
+  if (!screen_capturer_factory_) {
+    LOG(LS_ERROR) << "No video capturer factory for screens.";
     return NULL;
   }
-  return desktop_capturer;
-#else
-  return NULL;
-#endif
+  return screen_capturer_factory_->Create(screenid);
 }
 
 bool DeviceManager::GetAudioDevices(bool input,
diff --git a/media/devices/devicemanager.h b/media/devices/devicemanager.h
index 0107348..74ceb38 100644
--- a/media/devices/devicemanager.h
+++ b/media/devices/devicemanager.h
@@ -32,11 +32,14 @@
 #include <string>
 #include <vector>
 
+#include "talk/media/base/device.h"
+#include "talk/media/base/screencastid.h"
+#include "talk/media/base/videocommon.h"
+#include "talk/media/base/videocapturerfactory.h"
 #include "webrtc/base/scoped_ptr.h"
 #include "webrtc/base/sigslot.h"
 #include "webrtc/base/stringencode.h"
 #include "webrtc/base/window.h"
-#include "talk/media/base/videocommon.h"
 
 namespace rtc {
 
@@ -49,28 +52,6 @@
 
 class VideoCapturer;
 
-// Used to represent an audio or video capture or render device.
-struct Device {
-  Device() {}
-  Device(const std::string& first, int second)
-      : name(first),
-        id(rtc::ToString(second)) {
-  }
-  Device(const std::string& first, const std::string& second)
-      : name(first), id(second) {}
-
-  std::string name;
-  std::string id;
-};
-
-class VideoCapturerFactory {
- public:
-  VideoCapturerFactory() {}
-  virtual ~VideoCapturerFactory() {}
-
-  virtual VideoCapturer* Create(const Device& device) = 0;
-};
-
 // DeviceManagerInterface - interface to manage the audio and
 // video devices on the system.
 class DeviceManagerInterface {
@@ -94,6 +75,14 @@
   virtual bool GetVideoCaptureDevices(std::vector<Device>* devs) = 0;
   virtual bool GetVideoCaptureDevice(const std::string& name, Device* out) = 0;
 
+  // If the device manager needs to create video capturers, here is
+  // how to control which video capturers are created.  These take
+  // ownership of the factories.
+  virtual void SetVideoDeviceCapturerFactory(
+      VideoDeviceCapturerFactory* video_device_capturer_factory) = 0;
+  virtual void SetScreenCapturerFactory(
+      ScreenCapturerFactory* screen_capturer_factory) = 0;
+
   // Caps the capture format according to max format for capturers created
   // by CreateVideoCapturer(). See ConstrainSupportedFormats() in
   // videocapturer.h for more detail.
@@ -109,12 +98,10 @@
 
   virtual bool GetWindows(
       std::vector<rtc::WindowDescription>* descriptions) = 0;
-  virtual VideoCapturer* CreateWindowCapturer(rtc::WindowId window) = 0;
-
   virtual bool GetDesktops(
       std::vector<rtc::DesktopDescription>* descriptions) = 0;
-  virtual VideoCapturer* CreateDesktopCapturer(
-      rtc::DesktopId desktop) = 0;
+  virtual VideoCapturer* CreateScreenCapturer(
+      const ScreencastId& screenid) const = 0;
 
   sigslot::signal0<> SignalDevicesChange;
 
@@ -142,11 +129,6 @@
   DeviceManager();
   virtual ~DeviceManager();
 
-  void set_device_video_capturer_factory(
-      VideoCapturerFactory* device_video_capturer_factory) {
-    device_video_capturer_factory_.reset(device_video_capturer_factory);
-  }
-
   // Initialization
   virtual bool Init();
   virtual void Terminate();
@@ -164,19 +146,29 @@
   virtual bool GetVideoCaptureDevices(std::vector<Device>* devs);
   virtual bool GetVideoCaptureDevice(const std::string& name, Device* out);
 
+  virtual void SetVideoDeviceCapturerFactory(
+      VideoDeviceCapturerFactory* video_device_capturer_factory) {
+    video_device_capturer_factory_.reset(video_device_capturer_factory);
+  }
+  virtual void SetScreenCapturerFactory(
+      ScreenCapturerFactory* screen_capturer_factory) {
+    screen_capturer_factory_.reset(screen_capturer_factory);
+  }
+
+
   virtual void SetVideoCaptureDeviceMaxFormat(const std::string& usb_id,
                                               const VideoFormat& max_format);
   virtual void ClearVideoCaptureDeviceMaxFormat(const std::string& usb_id);
 
+  // TODO(pthatcher): Rename to CreateVideoDeviceCapturer.
   virtual VideoCapturer* CreateVideoCapturer(const Device& device) const;
 
   virtual bool GetWindows(
       std::vector<rtc::WindowDescription>* descriptions);
-  virtual VideoCapturer* CreateWindowCapturer(rtc::WindowId window);
-
   virtual bool GetDesktops(
       std::vector<rtc::DesktopDescription>* descriptions);
-  virtual VideoCapturer* CreateDesktopCapturer(rtc::DesktopId desktop);
+  virtual VideoCapturer* CreateScreenCapturer(
+      const ScreencastId& screenid) const;
 
   // The exclusion_list MUST be a NULL terminated list.
   static bool FilterDevices(std::vector<Device>* devices,
@@ -202,10 +194,13 @@
   static bool ShouldDeviceBeIgnored(const std::string& device_name,
       const char* const exclusion_list[]);
   bool GetFakeVideoCaptureDevice(const std::string& name, Device* out) const;
-  VideoCapturer* ConstructFakeVideoCapturer(const Device& device) const;
+  VideoCapturer* MaybeConstructFakeVideoCapturer(const Device& device) const;
 
   bool initialized_;
-  rtc::scoped_ptr<VideoCapturerFactory> device_video_capturer_factory_;
+  rtc::scoped_ptr<
+    VideoDeviceCapturerFactory> video_device_capturer_factory_;
+  rtc::scoped_ptr<
+    ScreenCapturerFactory> screen_capturer_factory_;
   std::map<std::string, VideoFormat> max_formats_;
   rtc::scoped_ptr<DeviceWatcher> watcher_;
   rtc::scoped_ptr<rtc::WindowPicker> window_picker_;
diff --git a/media/devices/devicemanager_unittest.cc b/media/devices/devicemanager_unittest.cc
index 3bc0241..19aaa90 100644
--- a/media/devices/devicemanager_unittest.cc
+++ b/media/devices/devicemanager_unittest.cc
@@ -33,6 +33,12 @@
 #endif
 #include <string>
 
+#include "talk/media/base/fakevideocapturer.h"
+#include "talk/media/base/screencastid.h"
+#include "talk/media/base/testutils.h"
+#include "talk/media/base/videocapturerfactory.h"
+#include "talk/media/devices/filevideocapturer.h"
+#include "talk/media/devices/v4llookup.h"
 #include "webrtc/base/fileutils.h"
 #include "webrtc/base/gunit.h"
 #include "webrtc/base/logging.h"
@@ -40,10 +46,6 @@
 #include "webrtc/base/scoped_ptr.h"
 #include "webrtc/base/stream.h"
 #include "webrtc/base/windowpickerfactory.h"
-#include "talk/media/base/fakevideocapturer.h"
-#include "talk/media/base/testutils.h"
-#include "talk/media/devices/filevideocapturer.h"
-#include "talk/media/devices/v4llookup.h"
 
 #ifdef LINUX
 // TODO(juberti): Figure out why this doesn't compile on Windows.
@@ -65,24 +67,38 @@
                                      cricket::VideoFormat::FpsToInterval(30),
                                      cricket::FOURCC_I420);
 
-class FakeVideoCapturerFactory : public cricket::VideoCapturerFactory {
+class FakeVideoDeviceCapturerFactory :
+    public cricket::VideoDeviceCapturerFactory {
  public:
-  FakeVideoCapturerFactory() {}
-  virtual ~FakeVideoCapturerFactory() {}
+  FakeVideoDeviceCapturerFactory() {}
+  virtual ~FakeVideoDeviceCapturerFactory() {}
 
   virtual cricket::VideoCapturer* Create(const cricket::Device& device) {
     return new cricket::FakeVideoCapturer;
   }
 };
 
+class FakeScreenCapturerFactory : public cricket::ScreenCapturerFactory {
+ public:
+  FakeScreenCapturerFactory() {}
+  virtual ~FakeScreenCapturerFactory() {}
+
+  virtual cricket::VideoCapturer* Create(
+      const cricket::ScreencastId& screenid) {
+    return new cricket::FakeVideoCapturer;
+  }
+};
+
 class DeviceManagerTestFake : public testing::Test {
  public:
   virtual void SetUp() {
     dm_.reset(DeviceManagerFactory::Create());
     EXPECT_TRUE(dm_->Init());
     DeviceManager* device_manager = static_cast<DeviceManager*>(dm_.get());
-    device_manager->set_device_video_capturer_factory(
-        new FakeVideoCapturerFactory());
+    device_manager->SetVideoDeviceCapturerFactory(
+        new FakeVideoDeviceCapturerFactory());
+    device_manager->SetScreenCapturerFactory(
+        new FakeScreenCapturerFactory());
   }
 
   virtual void TearDown() {
@@ -371,6 +387,7 @@
     return;
   }
   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
+  dm->SetScreenCapturerFactory(new FakeScreenCapturerFactory());
   std::vector<rtc::WindowDescription> descriptions;
   EXPECT_TRUE(dm->Init());
   if (!dm->GetWindows(&descriptions) || descriptions.empty()) {
@@ -378,8 +395,8 @@
                  << "windows to capture.";
     return;
   }
-  scoped_ptr<cricket::VideoCapturer> capturer(dm->CreateWindowCapturer(
-      descriptions.front().id()));
+  scoped_ptr<cricket::VideoCapturer> capturer(dm->CreateScreenCapturer(
+      cricket::ScreencastId(descriptions.front().id())));
   EXPECT_FALSE(capturer.get() == NULL);
   // TODO(hellner): creating a window capturer and immediately deleting it
   // results in "Continuous Build and Test Mainline - Mac opt" failure (crash).
@@ -394,6 +411,7 @@
     return;
   }
   scoped_ptr<DeviceManagerInterface> dm(DeviceManagerFactory::Create());
+  dm->SetScreenCapturerFactory(new FakeScreenCapturerFactory());
   std::vector<rtc::DesktopDescription> descriptions;
   EXPECT_TRUE(dm->Init());
   if (!dm->GetDesktops(&descriptions) || descriptions.empty()) {
@@ -401,8 +419,8 @@
                  << "desktops to capture.";
     return;
   }
-  scoped_ptr<cricket::VideoCapturer> capturer(dm->CreateDesktopCapturer(
-      descriptions.front().id()));
+  scoped_ptr<cricket::VideoCapturer> capturer(dm->CreateScreenCapturer(
+      cricket::ScreencastId(descriptions.front().id())));
   EXPECT_FALSE(capturer.get() == NULL);
 }
 #endif  // !WIN32
diff --git a/media/devices/fakedevicemanager.h b/media/devices/fakedevicemanager.h
index 5fc3715..7bc649d 100644
--- a/media/devices/fakedevicemanager.h
+++ b/media/devices/fakedevicemanager.h
@@ -31,11 +31,11 @@
 #include <string>
 #include <vector>
 
-#include "webrtc/base/window.h"
-#include "webrtc/base/windowpicker.h"
 #include "talk/media/base/fakevideocapturer.h"
 #include "talk/media/base/mediacommon.h"
 #include "talk/media/devices/devicemanager.h"
+#include "webrtc/base/window.h"
+#include "webrtc/base/windowpicker.h"
 
 namespace cricket {
 
@@ -79,6 +79,12 @@
     *devs = vidcap_devices_;
     return true;
   }
+  virtual void SetVideoDeviceCapturerFactory(
+      VideoDeviceCapturerFactory* video_device_capturer_factory) {
+  }
+  virtual void SetScreenCapturerFactory(
+      ScreenCapturerFactory* screen_capturer_factory) {
+  }
   virtual void SetVideoCaptureDeviceMaxFormat(const std::string& usb_id,
                                               const VideoFormat& max_format) {
     max_formats_[usb_id] = max_format;
@@ -97,6 +103,10 @@
   virtual VideoCapturer* CreateVideoCapturer(const Device& device) const {
     return new FakeVideoCapturer();
   }
+  virtual VideoCapturer* CreateScreenCapturer(
+      const ScreencastId& screenid) const {
+    return new FakeVideoCapturer();
+  }
   virtual bool GetWindows(
       std::vector<rtc::WindowDescription>* descriptions) {
     descriptions->clear();
diff --git a/media/webrtc/webrtcvideocapturerfactory.cc b/media/webrtc/webrtcvideocapturerfactory.cc
new file mode 100755
index 0000000..9f542bd
--- /dev/null
+++ b/media/webrtc/webrtcvideocapturerfactory.cc
@@ -0,0 +1,43 @@
+/*
+ * libjingle
+ * Copyright 2014 Google Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *  1. Redistributions of source code must retain the above copyright notice,
+ *     this list of conditions and the following disclaimer.
+ *  2. Redistributions in binary form must reproduce the above copyright notice,
+ *     this list of conditions and the following disclaimer in the documentation
+ *     and/or other materials provided with the distribution.
+ *  3. The name of the author may not be used to endorse or promote products
+ *     derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "talk/media/webrtc/webrtcvideocapturer.h"
+#include "talk/media/webrtc/webrtcvideocapturerfactory.h"
+#include "webrtc/base/scoped_ptr.h"
+
+namespace cricket {
+
+VideoCapturer* WebRtcVideoDeviceCapturerFactory::Create(const Device& device) {
+  rtc::scoped_ptr<WebRtcVideoCapturer> capturer(
+      new WebRtcVideoCapturer());
+  if (!capturer->Init(device)) {
+    return NULL;
+  }
+  return capturer.release();
+}
+
+}  // namespace cricket
diff --git a/media/webrtc/webrtcvideocapturerfactory.h b/media/webrtc/webrtcvideocapturerfactory.h
new file mode 100755
index 0000000..091b072
--- /dev/null
+++ b/media/webrtc/webrtcvideocapturerfactory.h
@@ -0,0 +1,43 @@
+// libjingle
+// Copyright 2014 Google Inc.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are met:
+//
+//  1. Redistributions of source code must retain the above copyright notice,
+//     this list of conditions and the following disclaimer.
+//  2. Redistributions in binary form must reproduce the above copyright notice,
+//     this list of conditions and the following disclaimer in the documentation
+//     and/or other materials provided with the distribution.
+//  3. The name of the author may not be used to endorse or promote products
+//     derived from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
+// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+
+// TODO(pthatcher): Reneme file to match class name.
+#ifndef TALK_MEDIA_WEBRTC_WEBRTCVIDEOCAPTURERFACTORY_H_
+#define TALK_MEDIA_WEBRTC_WEBRTCVIDEOCAPTURERFACTORY_H_
+
+#include "talk/media/base/videocapturerfactory.h"
+
+namespace cricket {
+
+// Creates instances of cricket::WebRtcVideoCapturer.
+class WebRtcVideoDeviceCapturerFactory : public VideoDeviceCapturerFactory {
+ public:
+  virtual VideoCapturer* Create(const Device& device);
+};
+
+}  // namespace cricket
+
+#endif  // TALK_MEDIA_WEBRTC_WEBRTCVIDEOCAPTURERFACTORY_H_
diff --git a/session/media/call.cc b/session/media/call.cc
index fc22eb4..ac02e7c 100644
--- a/session/media/call.cc
+++ b/session/media/call.cc
@@ -493,7 +493,7 @@
 
 bool Call::StartScreencast(Session* session,
                            const std::string& streamid, uint32 ssrc,
-                           const ScreencastId& screencastid, int fps) {
+                           const ScreencastId& screenid, int fps) {
   MediaSessionMap::iterator it = media_session_map_.find(session->id());
   if (it == media_session_map_.end()) {
     return false;
@@ -506,12 +506,19 @@
     return false;
   }
 
-  VideoCapturer *capturer = video_channel->AddScreencast(ssrc, screencastid);
-  if (capturer == NULL) {
+  VideoCapturer* capturer = session_client_->channel_manager()->
+      CreateScreenCapturer(screenid);
+  if (!capturer) {
     LOG(LS_WARNING) << "Could not create screencast capturer.";
     return false;
   }
 
+  if (!video_channel->AddScreencast(ssrc, capturer)) {
+    delete capturer;
+    LOG(LS_WARNING) << "Could not add screencast capturer.";
+    return false;
+  }
+
   VideoFormat format = ScreencastFormatFromFps(fps);
   if (!session_client_->channel_manager()->StartVideoCapture(
           capturer, format)) {
diff --git a/session/media/call.h b/session/media/call.h
index e61fec8..3122f55 100644
--- a/session/media/call.h
+++ b/session/media/call.h
@@ -115,7 +115,7 @@
   void PressDTMF(int event);
   bool StartScreencast(Session* session,
                        const std::string& stream_name, uint32 ssrc,
-                       const ScreencastId& screencastid, int fps);
+                       const ScreencastId& screenid, int fps);
   bool StopScreencast(Session* session,
                       const std::string& stream_name, uint32 ssrc);
 
diff --git a/session/media/channel.cc b/session/media/channel.cc
index 67bd2da..3615da8 100644
--- a/session/media/channel.cc
+++ b/session/media/channel.cc
@@ -27,19 +27,18 @@
 
 #include "talk/session/media/channel.h"
 
-#include "webrtc/base/bind.h"
-#include "webrtc/base/buffer.h"
-#include "webrtc/base/byteorder.h"
-#include "webrtc/base/common.h"
-#include "webrtc/base/dscp.h"
-#include "webrtc/base/logging.h"
 #include "talk/media/base/constants.h"
 #include "talk/media/base/rtputils.h"
 #include "talk/p2p/base/transportchannel.h"
 #include "talk/session/media/channelmanager.h"
 #include "talk/session/media/mediamessages.h"
 #include "talk/session/media/typingmonitor.h"
-
+#include "webrtc/base/bind.h"
+#include "webrtc/base/buffer.h"
+#include "webrtc/base/byteorder.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/dscp.h"
+#include "webrtc/base/logging.h"
 
 namespace cricket {
 
@@ -73,20 +72,6 @@
   }
 }
 
-// TODO(hellner): use the device manager for creation of screen capturers when
-// the cl enabling it has landed.
-class NullScreenCapturerFactory : public VideoChannel::ScreenCapturerFactory {
- public:
-  VideoCapturer* CreateScreenCapturer(const ScreencastId& window) {
-    return NULL;
-  }
-};
-
-
-VideoChannel::ScreenCapturerFactory* CreateScreenCapturerFactory() {
-  return new NullScreenCapturerFactory();
-}
-
 struct PacketMessageData : public rtc::MessageData {
   rtc::Buffer packet;
   rtc::DiffServCodePoint dscp;
@@ -1674,7 +1659,6 @@
                   rtcp),
       voice_channel_(voice_channel),
       renderer_(NULL),
-      screencapture_factory_(CreateScreenCapturerFactory()),
       previous_we_(rtc::WE_CLOSE) {
 }
 
@@ -1729,10 +1713,9 @@
   return InvokeOnWorker(Bind(&VideoChannel::ApplyViewRequest_w, this, request));
 }
 
-VideoCapturer* VideoChannel::AddScreencast(
-    uint32 ssrc, const ScreencastId& id) {
-  return worker_thread()->Invoke<VideoCapturer*>(Bind(
-      &VideoChannel::AddScreencast_w, this, ssrc, id));
+bool VideoChannel::AddScreencast(uint32 ssrc, VideoCapturer* capturer) {
+  return worker_thread()->Invoke<bool>(Bind(
+      &VideoChannel::AddScreencast_w, this, ssrc, capturer));
 }
 
 bool VideoChannel::SetCapturer(uint32 ssrc, VideoCapturer* capturer) {
@@ -1774,13 +1757,6 @@
   return true;
 }
 
-void VideoChannel::SetScreenCaptureFactory(
-    ScreenCapturerFactory* screencapture_factory) {
-  worker_thread()->Invoke<void>(Bind(
-      &VideoChannel::SetScreenCaptureFactory_w,
-      this, screencapture_factory));
-}
-
 void VideoChannel::ChangeState() {
   // Render incoming data if we're the active call, and we have the local
   // content. We receive data on the default channel and multiplexed streams.
@@ -1960,20 +1936,13 @@
   return ret;
 }
 
-VideoCapturer* VideoChannel::AddScreencast_w(
-    uint32 ssrc, const ScreencastId& id) {
+bool VideoChannel::AddScreencast_w(uint32 ssrc, VideoCapturer* capturer) {
   if (screencast_capturers_.find(ssrc) != screencast_capturers_.end()) {
-    return NULL;
+    return false;
   }
-  VideoCapturer* screen_capturer =
-      screencapture_factory_->CreateScreenCapturer(id);
-  if (!screen_capturer) {
-    return NULL;
-  }
-  screen_capturer->SignalStateChange.connect(this,
-                                             &VideoChannel::OnStateChange);
-  screencast_capturers_[ssrc] = screen_capturer;
-  return screen_capturer;
+  capturer->SignalStateChange.connect(this, &VideoChannel::OnStateChange);
+  screencast_capturers_[ssrc] = capturer;
+  return true;
 }
 
 bool VideoChannel::RemoveScreencast_w(uint32 ssrc) {
@@ -2003,15 +1972,6 @@
   data->screencast_max_pixels = capturer->screencast_max_pixels();
 }
 
-void VideoChannel::SetScreenCaptureFactory_w(
-    ScreenCapturerFactory* screencapture_factory) {
-  if (screencapture_factory == NULL) {
-    screencapture_factory_.reset(CreateScreenCapturerFactory());
-  } else {
-    screencapture_factory_.reset(screencapture_factory);
-  }
-}
-
 void VideoChannel::OnScreencastWindowEvent_s(uint32 ssrc,
                                              rtc::WindowEvent we) {
   ASSERT(signaling_thread() == rtc::Thread::Current());
diff --git a/session/media/channel.h b/session/media/channel.h
index 2480f45..4d3baf6 100644
--- a/session/media/channel.h
+++ b/session/media/channel.h
@@ -38,7 +38,6 @@
 #include "webrtc/base/window.h"
 #include "talk/media/base/mediachannel.h"
 #include "talk/media/base/mediaengine.h"
-#include "talk/media/base/screencastid.h"
 #include "talk/media/base/streamparams.h"
 #include "talk/media/base/videocapturer.h"
 #include "talk/p2p/base/session.h"
@@ -508,14 +507,6 @@
 // VideoChannel is a specialization for video.
 class VideoChannel : public BaseChannel {
  public:
-  // Make screen capturer virtual so that it can be overriden in testing.
-  // E.g. used to test that window events are triggered correctly.
-  class ScreenCapturerFactory {
-   public:
-    virtual VideoCapturer* CreateScreenCapturer(const ScreencastId& window) = 0;
-    virtual ~ScreenCapturerFactory() {}
-  };
-
   VideoChannel(rtc::Thread* thread, MediaEngineInterface* media_engine,
                VideoMediaChannel* channel, BaseSession* session,
                const std::string& content_name, bool rtcp,
@@ -528,7 +519,8 @@
 
   // TODO(pthatcher): Refactor to use a "capture id" instead of an
   // ssrc here as the "key".
-  VideoCapturer* AddScreencast(uint32 ssrc, const ScreencastId& id);
+  // Passes ownership of the capturer to the channel.
+  bool AddScreencast(uint32 ssrc, VideoCapturer* capturer);
   bool SetCapturer(uint32 ssrc, VideoCapturer* capturer);
   bool RemoveScreencast(uint32 ssrc);
   // True if we've added a screencast.  Doesn't matter if the capturer
@@ -552,9 +544,6 @@
   sigslot::signal3<VideoChannel*, uint32, VideoMediaChannel::Error>
       SignalMediaError;
 
-  void SetScreenCaptureFactory(
-      ScreenCapturerFactory* screencapture_factory);
-
   // Configuration and setting.
   bool SetChannelOptions(const VideoOptions& options);
 
@@ -579,13 +568,11 @@
                                   std::string* error_desc);
   bool ApplyViewRequest_w(const ViewRequest& request);
 
-  VideoCapturer* AddScreencast_w(uint32 ssrc, const ScreencastId& id);
+  bool AddScreencast_w(uint32 ssrc, VideoCapturer* capturer);
   bool RemoveScreencast_w(uint32 ssrc);
   void OnScreencastWindowEvent_s(uint32 ssrc, rtc::WindowEvent we);
   bool IsScreencasting_w() const;
   void GetScreencastDetails_w(ScreencastDetailsData* d) const;
-  void SetScreenCaptureFactory_w(
-      ScreenCapturerFactory* screencapture_factory);
   bool GetStats_w(VideoMediaInfo* stats);
 
   virtual void OnMessage(rtc::Message* pmsg);
@@ -604,7 +591,6 @@
 
   VoiceChannel* voice_channel_;
   VideoRenderer* renderer_;
-  rtc::scoped_ptr<ScreenCapturerFactory> screencapture_factory_;
   ScreencastMap screencast_capturers_;
   rtc::scoped_ptr<VideoMediaMonitor> media_monitor_;
 
diff --git a/session/media/channel_unittest.cc b/session/media/channel_unittest.cc
index cf0aad8..b2fc92b 100644
--- a/session/media/channel_unittest.cc
+++ b/session/media/channel_unittest.cc
@@ -23,16 +23,8 @@
 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
-#include "webrtc/base/fileutils.h"
-#include "webrtc/base/gunit.h"
-#include "webrtc/base/helpers.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/pathutils.h"
-#include "webrtc/base/signalthread.h"
-#include "webrtc/base/ssladapter.h"
-#include "webrtc/base/sslidentity.h"
-#include "webrtc/base/window.h"
 #include "talk/media/base/fakemediaengine.h"
+#include "talk/media/base/fakescreencapturerfactory.h"
 #include "talk/media/base/fakertp.h"
 #include "talk/media/base/fakevideocapturer.h"
 #include "talk/media/base/mediachannel.h"
@@ -45,6 +37,15 @@
 #include "talk/session/media/mediarecorder.h"
 #include "talk/session/media/mediasessionclient.h"
 #include "talk/session/media/typingmonitor.h"
+#include "webrtc/base/fileutils.h"
+#include "webrtc/base/gunit.h"
+#include "webrtc/base/helpers.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/pathutils.h"
+#include "webrtc/base/signalthread.h"
+#include "webrtc/base/ssladapter.h"
+#include "webrtc/base/sslidentity.h"
+#include "webrtc/base/window.h"
 
 #define MAYBE_SKIP_TEST(feature)                    \
   if (!(rtc::SSLStreamAdapter::feature())) {  \
@@ -88,49 +89,6 @@
   typedef MediaInfoT MediaInfo;
 };
 
-class FakeScreenCaptureFactory
-    : public cricket::VideoChannel::ScreenCapturerFactory,
-      public sigslot::has_slots<> {
- public:
-  FakeScreenCaptureFactory()
-      : window_capturer_(NULL),
-        capture_state_(cricket::CS_STOPPED) {}
-
-  virtual cricket::VideoCapturer* CreateScreenCapturer(
-      const ScreencastId& window) {
-    if (window_capturer_ != NULL) {
-      // Class is only designed to handle one fake screencapturer.
-      ADD_FAILURE();
-      return NULL;
-    }
-    window_capturer_ = new cricket::FakeVideoCapturer;
-    window_capturer_->SignalDestroyed.connect(
-        this,
-        &FakeScreenCaptureFactory::OnWindowCapturerDestroyed);
-    window_capturer_->SignalStateChange.connect(
-        this,
-        &FakeScreenCaptureFactory::OnStateChange);
-    return window_capturer_;
-  }
-
-  cricket::FakeVideoCapturer* window_capturer() { return window_capturer_; }
-
-  cricket::CaptureState capture_state() { return capture_state_; }
-
- private:
-  void OnWindowCapturerDestroyed(cricket::FakeVideoCapturer* capturer) {
-    if (capturer == window_capturer_) {
-      window_capturer_ = NULL;
-    }
-  }
-  void OnStateChange(cricket::VideoCapturer*, cricket::CaptureState state) {
-    capture_state_ = state;
-  }
-
-  cricket::FakeVideoCapturer* window_capturer_;
-  cricket::CaptureState capture_state_;
-};
-
 // Controls how long we wait for a session to send messages that we
 // expect, in milliseconds.  We put it high to avoid flaky tests.
 static const int kEventTimeout = 5000;
@@ -2469,28 +2427,31 @@
 TEST_F(VideoChannelTest, TestScreencastEvents) {
   const int kTimeoutMs = 500;
   TestInit();
-  FakeScreenCaptureFactory* screencapture_factory =
-      new FakeScreenCaptureFactory();
-  channel1_->SetScreenCaptureFactory(screencapture_factory);
   cricket::ScreencastEventCatcher catcher;
   channel1_->SignalScreencastWindowEvent.connect(
       &catcher,
       &cricket::ScreencastEventCatcher::OnEvent);
-  EXPECT_TRUE(channel1_->AddScreencast(0, ScreencastId(WindowId(0))) != NULL);
-  ASSERT_TRUE(screencapture_factory->window_capturer() != NULL);
-  EXPECT_EQ_WAIT(cricket::CS_STOPPED, screencapture_factory->capture_state(),
+
+  rtc::scoped_ptr<cricket::FakeScreenCapturerFactory>
+      screen_capturer_factory(new cricket::FakeScreenCapturerFactory());
+  cricket::VideoCapturer* screen_capturer = screen_capturer_factory->Create(
+      ScreencastId(WindowId(0)));
+  ASSERT_TRUE(screen_capturer != NULL);
+
+  EXPECT_TRUE(channel1_->AddScreencast(0, screen_capturer));
+  EXPECT_EQ_WAIT(cricket::CS_STOPPED, screen_capturer_factory->capture_state(),
                  kTimeoutMs);
-  screencapture_factory->window_capturer()->SignalStateChange(
-      screencapture_factory->window_capturer(), cricket::CS_PAUSED);
+
+  screen_capturer->SignalStateChange(screen_capturer, cricket::CS_PAUSED);
   EXPECT_EQ_WAIT(rtc::WE_MINIMIZE, catcher.event(), kTimeoutMs);
-  screencapture_factory->window_capturer()->SignalStateChange(
-      screencapture_factory->window_capturer(), cricket::CS_RUNNING);
+
+  screen_capturer->SignalStateChange(screen_capturer, cricket::CS_RUNNING);
   EXPECT_EQ_WAIT(rtc::WE_RESTORE, catcher.event(), kTimeoutMs);
-  screencapture_factory->window_capturer()->SignalStateChange(
-      screencapture_factory->window_capturer(), cricket::CS_STOPPED);
+
+  screen_capturer->SignalStateChange(screen_capturer, cricket::CS_STOPPED);
   EXPECT_EQ_WAIT(rtc::WE_CLOSE, catcher.event(), kTimeoutMs);
+
   EXPECT_TRUE(channel1_->RemoveScreencast(0));
-  ASSERT_TRUE(screencapture_factory->window_capturer() == NULL);
 }
 
 TEST_F(VideoChannelTest, TestUpdateStreamsInLocalContent) {
diff --git a/session/media/channelmanager.cc b/session/media/channelmanager.cc
index 684e9a9..8ceb148 100644
--- a/session/media/channelmanager.cc
+++ b/session/media/channelmanager.cc
@@ -33,12 +33,6 @@
 
 #include <algorithm>
 
-#include "webrtc/base/bind.h"
-#include "webrtc/base/common.h"
-#include "webrtc/base/logging.h"
-#include "webrtc/base/sigslotrepeater.h"
-#include "webrtc/base/stringencode.h"
-#include "webrtc/base/stringutils.h"
 #include "talk/media/base/capturemanager.h"
 #include "talk/media/base/hybriddataengine.h"
 #include "talk/media/base/rtpdataengine.h"
@@ -49,6 +43,12 @@
 #endif
 #include "talk/session/media/soundclip.h"
 #include "talk/session/media/srtpfilter.h"
+#include "webrtc/base/bind.h"
+#include "webrtc/base/common.h"
+#include "webrtc/base/logging.h"
+#include "webrtc/base/sigslotrepeater.h"
+#include "webrtc/base/stringencode.h"
+#include "webrtc/base/stringutils.h"
 
 namespace cricket {
 
@@ -710,6 +710,11 @@
   return capturer;
 }
 
+VideoCapturer* ChannelManager::CreateScreenCapturer(
+    const ScreencastId& screenid) {
+  return device_manager_->CreateScreenCapturer(screenid);
+}
+
 bool ChannelManager::SetCaptureDevice_w(const Device* cam_device) {
   ASSERT(worker_thread_ == rtc::Thread::Current());
   ASSERT(initialized_);
diff --git a/session/media/channelmanager.h b/session/media/channelmanager.h
index d742280..e13ae12 100644
--- a/session/media/channelmanager.h
+++ b/session/media/channelmanager.h
@@ -31,14 +31,14 @@
 #include <string>
 #include <vector>
 
-#include "webrtc/base/criticalsection.h"
-#include "webrtc/base/fileutils.h"
-#include "webrtc/base/sigslotrepeater.h"
-#include "webrtc/base/thread.h"
 #include "talk/media/base/capturemanager.h"
 #include "talk/media/base/mediaengine.h"
 #include "talk/p2p/base/session.h"
 #include "talk/session/media/voicechannel.h"
+#include "webrtc/base/criticalsection.h"
+#include "webrtc/base/fileutils.h"
+#include "webrtc/base/sigslotrepeater.h"
+#include "webrtc/base/thread.h"
 
 namespace cricket {
 
@@ -157,6 +157,8 @@
   bool GetVideoCaptureDevice(Device* device);
   // Create capturer based on what has been set in SetCaptureDevice().
   VideoCapturer* CreateVideoCapturer();
+  // Create capturer from a screen.
+  VideoCapturer* CreateScreenCapturer(const ScreencastId& screenid);
   bool SetCaptureDevice(const std::string& cam_device);
   bool SetDefaultVideoEncoderConfig(const VideoEncoderConfig& config);
   // RTX will be enabled/disabled in engines that support it. The supporting
@@ -240,6 +242,9 @@
                        const AudioOptions& options,
                        int delay_offset);
   int audio_delay_offset() const { return audio_delay_offset_; }
+  // This is here so that ChannelManager subclasses can set the video
+  // capturer factories to use.
+  DeviceManagerInterface* device_manager() { return device_manager_.get(); }
 
  private:
   typedef std::vector<VoiceChannel*> VoiceChannels;