Cleanup shared memory handling in DesktopCapturer interface.

Previously shared memory buffers for DesktopCapturer were created
using DesktopCapturer::Callback::CreateSharedBuffer(). That made it
difficult to proxy DesktopCapturer interface from one thread to another.
This CL adds SharedBufferFactory interface that's allowed to be called
on a background thread. This also simplifies clients that don't
need to use shared memory, as they no longer need to override
CreateSharedBuffer().

Review URL: https://codereview.webrtc.org/1678073003

Cr-Commit-Position: refs/heads/master@{#11543}
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer.cc b/webrtc/modules/desktop_capture/cropping_window_capturer.cc
index 1e37e78..7aab7f8 100644
--- a/webrtc/modules/desktop_capture/cropping_window_capturer.cc
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer.cc
@@ -31,6 +31,11 @@
   window_capturer_->Start(callback);
 }
 
+void CroppingWindowCapturer::SetSharedMemoryFactory(
+    rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) {
+  window_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory));
+}
+
 void CroppingWindowCapturer::Capture(const DesktopRegion& region) {
   if (ShouldUseScreenCapturer()) {
     if (!screen_capturer_.get()) {
@@ -69,10 +74,6 @@
   return window_capturer_->BringSelectedWindowToFront();
 }
 
-SharedMemory* CroppingWindowCapturer::CreateSharedMemory(size_t size) {
-  return callback_->CreateSharedMemory(size);
-}
-
 void CroppingWindowCapturer::OnCaptureCompleted(DesktopFrame* frame) {
   rtc::scoped_ptr<DesktopFrame> screen_frame(frame);
 
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer.h b/webrtc/modules/desktop_capture/cropping_window_capturer.h
index e0f598c..af456e5 100644
--- a/webrtc/modules/desktop_capture/cropping_window_capturer.h
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer.h
@@ -29,6 +29,8 @@
 
   // DesktopCapturer implementation.
   void Start(DesktopCapturer::Callback* callback) override;
+  void SetSharedMemoryFactory(
+      rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) override;
   void Capture(const DesktopRegion& region) override;
   void SetExcludedWindow(WindowId window) override;
 
@@ -39,7 +41,6 @@
 
   // DesktopCapturer::Callback implementation, passed to |screen_capturer_| to
   // intercept the capture result.
-  SharedMemory* CreateSharedMemory(size_t size) override;
   void OnCaptureCompleted(DesktopFrame* frame) override;
 
  protected:
diff --git a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc
index 74d25d4..5da8bee 100644
--- a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc
+++ b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc
@@ -136,6 +136,11 @@
   desktop_capturer_->Start(this);
 }
 
+void DesktopAndCursorComposer::SetSharedMemoryFactory(
+    rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) {
+  desktop_capturer_->SetSharedMemoryFactory(std::move(shared_memory_factory));
+}
+
 void DesktopAndCursorComposer::Capture(const DesktopRegion& region) {
   if (mouse_monitor_.get())
     mouse_monitor_->Capture();
@@ -146,10 +151,6 @@
   desktop_capturer_->SetExcludedWindow(window);
 }
 
-SharedMemory* DesktopAndCursorComposer::CreateSharedMemory(size_t size) {
-  return callback_->CreateSharedMemory(size);
-}
-
 void DesktopAndCursorComposer::OnCaptureCompleted(DesktopFrame* frame) {
   if (frame && cursor_.get() && cursor_state_ == MouseCursorMonitor::INSIDE) {
     DesktopFrameWithCursor* frame_with_cursor =
diff --git a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h
index 7a72031..6d381c8 100644
--- a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h
+++ b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h
@@ -20,8 +20,8 @@
 // A wrapper for DesktopCapturer that also captures mouse using specified
 // MouseCursorMonitor and renders it on the generated streams.
 class DesktopAndCursorComposer : public DesktopCapturer,
-                            public DesktopCapturer::Callback,
-                            public MouseCursorMonitor::Callback {
+                                 public DesktopCapturer::Callback,
+                                 public MouseCursorMonitor::Callback {
  public:
   // Creates a new blender that captures mouse cursor using |mouse_monitor| and
   // renders it into the frames generated by |desktop_capturer|. If
@@ -33,12 +33,13 @@
 
   // DesktopCapturer interface.
   void Start(DesktopCapturer::Callback* callback) override;
+  void SetSharedMemoryFactory(
+      rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) override;
   void Capture(const DesktopRegion& region) override;
   void SetExcludedWindow(WindowId window) override;
 
  private:
   // DesktopCapturer::Callback interface.
-  SharedMemory* CreateSharedMemory(size_t size) override;
   void OnCaptureCompleted(DesktopFrame* frame) override;
 
   // MouseCursorMonitor::Callback interface.
diff --git a/webrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc b/webrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc
index bee9e08..4835fc5 100644
--- a/webrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc
+++ b/webrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc
@@ -168,8 +168,6 @@
   }
 
   // DesktopCapturer::Callback interface
-  SharedMemory* CreateSharedMemory(size_t size) override { return NULL; }
-
   void OnCaptureCompleted(DesktopFrame* frame) override { frame_.reset(frame); }
 
  protected:
diff --git a/webrtc/modules/desktop_capture/desktop_capturer.h b/webrtc/modules/desktop_capture/desktop_capturer.h
index 7ad1636..47f78dc 100644
--- a/webrtc/modules/desktop_capture/desktop_capturer.h
+++ b/webrtc/modules/desktop_capture/desktop_capturer.h
@@ -13,13 +13,14 @@
 
 #include <stddef.h>
 
+#include "webrtc/base/scoped_ptr.h"
 #include "webrtc/modules/desktop_capture/desktop_capture_types.h"
+#include "webrtc/modules/desktop_capture/shared_memory.h"
 
 namespace webrtc {
 
 class DesktopFrame;
 class DesktopRegion;
-class SharedMemory;
 
 // Abstract interface for screen and window capturers.
 class DesktopCapturer {
@@ -27,10 +28,10 @@
   // Interface that must be implemented by the DesktopCapturer consumers.
   class Callback {
    public:
-    // Creates a new shared memory buffer for a frame create by the capturer.
-    // Should return null shared memory is not used for captured frames (in that
-    // case the capturer will allocate memory on the heap).
-    virtual SharedMemory* CreateSharedMemory(size_t size) = 0;
+    // Deprecated.
+    // TODO(sergeyu): Remove this method once all references to it are removed
+    // from chromium.
+    virtual SharedMemory* CreateSharedMemory(size_t size) { return nullptr; }
 
     // Called after a frame has been captured. Handler must take ownership of
     // |frame|. If capture has failed for any reason |frame| is set to NULL
@@ -47,6 +48,13 @@
   // valid until capturer is destroyed.
   virtual void Start(Callback* callback) = 0;
 
+  // Sets SharedMemoryFactory that will be used to create buffers for the
+  // captured frames. The factory can be invoked on a thread other than the one
+  // where Capture() is called. It will be destroyed on the same thread. Shared
+  // memory is currently supported only by some DesktopCapturer implementations.
+  virtual void SetSharedMemoryFactory(
+      rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) {}
+
   // Captures next frame. |region| specifies region of the capture target that
   // should be fresh in the resulting frame. The frame may also include fresh
   // data for areas outside |region|. In that case capturer will include these
diff --git a/webrtc/modules/desktop_capture/desktop_frame.cc b/webrtc/modules/desktop_capture/desktop_frame.cc
index cb32ef7..054427c 100644
--- a/webrtc/modules/desktop_capture/desktop_frame.cc
+++ b/webrtc/modules/desktop_capture/desktop_frame.cc
@@ -77,15 +77,38 @@
   return result;
 }
 
+// static
+rtc::scoped_ptr<DesktopFrame> SharedMemoryDesktopFrame::Create(
+    DesktopSize size,
+    SharedMemoryFactory* shared_memory_factory) {
+  size_t buffer_size =
+      size.width() * size.height() * DesktopFrame::kBytesPerPixel;
+  rtc::scoped_ptr<SharedMemory> shared_memory;
+  shared_memory = shared_memory_factory->CreateSharedMemory(buffer_size);
+  if (!shared_memory)
+    return nullptr;
+
+  return rtc_make_scoped_ptr(new SharedMemoryDesktopFrame(
+      size, size.width() * DesktopFrame::kBytesPerPixel,
+      std::move(shared_memory)));
+}
+
+SharedMemoryDesktopFrame::SharedMemoryDesktopFrame(DesktopSize size,
+                                                   int stride,
+                                                   SharedMemory* shared_memory)
+    : DesktopFrame(size,
+                   stride,
+                   reinterpret_cast<uint8_t*>(shared_memory->data()),
+                   shared_memory) {}
 
 SharedMemoryDesktopFrame::SharedMemoryDesktopFrame(
     DesktopSize size,
     int stride,
-    SharedMemory* shared_memory)
-    : DesktopFrame(size, stride,
+    rtc::scoped_ptr<SharedMemory> shared_memory)
+    : DesktopFrame(size,
+                   stride,
                    reinterpret_cast<uint8_t*>(shared_memory->data()),
-                   shared_memory) {
-}
+                   shared_memory.release()) {}
 
 SharedMemoryDesktopFrame::~SharedMemoryDesktopFrame() {
   delete shared_memory_;
diff --git a/webrtc/modules/desktop_capture/desktop_frame.h b/webrtc/modules/desktop_capture/desktop_frame.h
index 49b9646..cdfd829 100644
--- a/webrtc/modules/desktop_capture/desktop_frame.h
+++ b/webrtc/modules/desktop_capture/desktop_frame.h
@@ -110,10 +110,18 @@
 // A DesktopFrame that stores data in shared memory.
 class SharedMemoryDesktopFrame : public DesktopFrame {
  public:
+  static rtc::scoped_ptr<DesktopFrame> Create(
+      DesktopSize size,
+      SharedMemoryFactory* shared_memory_factory);
+
   // Takes ownership of |shared_memory|.
+  // TODO(sergeyu): Remove this constructor and keep the second one.
   SharedMemoryDesktopFrame(DesktopSize size,
                            int stride,
                            SharedMemory* shared_memory);
+  SharedMemoryDesktopFrame(DesktopSize size,
+                           int stride,
+                           rtc::scoped_ptr<SharedMemory> shared_memory);
   ~SharedMemoryDesktopFrame() override;
 
  private:
diff --git a/webrtc/modules/desktop_capture/desktop_frame_win.cc b/webrtc/modules/desktop_capture/desktop_frame_win.cc
index 6b97b13..22f9742 100644
--- a/webrtc/modules/desktop_capture/desktop_frame_win.cc
+++ b/webrtc/modules/desktop_capture/desktop_frame_win.cc
@@ -10,6 +10,8 @@
 
 #include "webrtc/modules/desktop_capture/desktop_frame_win.h"
 
+#include <utility>
+
 #include "webrtc/system_wrappers/include/logging.h"
 
 namespace webrtc {
@@ -17,22 +19,23 @@
 DesktopFrameWin::DesktopFrameWin(DesktopSize size,
                                  int stride,
                                  uint8_t* data,
-                                 SharedMemory* shared_memory,
+                                 rtc::scoped_ptr<SharedMemory> shared_memory,
                                  HBITMAP bitmap)
-    : DesktopFrame(size, stride, data, shared_memory),
+    : DesktopFrame(size, stride, data, shared_memory.get()),
       bitmap_(bitmap),
-      owned_shared_memory_(shared_memory_) {
-}
+      owned_shared_memory_(std::move(shared_memory)) {}
 
 DesktopFrameWin::~DesktopFrameWin() {
   DeleteObject(bitmap_);
 }
 
 // static
-DesktopFrameWin* DesktopFrameWin::Create(DesktopSize size,
-                                         SharedMemory* shared_memory,
-                                         HDC hdc) {
+DesktopFrameWin* DesktopFrameWin::Create(
+    DesktopSize size,
+    SharedMemoryFactory* shared_memory_factory,
+    HDC hdc) {
   int bytes_per_row = size.width() * kBytesPerPixel;
+  int buffer_size = bytes_per_row * size.height();
 
   // Describe a device independent bitmap (DIB) that is the size of the desktop.
   BITMAPINFO bmi = {};
@@ -43,21 +46,24 @@
   bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
   bmi.bmiHeader.biSizeImage = bytes_per_row * size.height();
 
-  HANDLE section_handle = NULL;
-  if (shared_memory)
-    section_handle = shared_memory->handle();
-  void* data = NULL;
+  rtc::scoped_ptr<SharedMemory> shared_memory;
+  HANDLE section_handle = nullptr;
+  if (shared_memory_factory) {
+    shared_memory = shared_memory_factory->CreateSharedMemory(buffer_size);
+    if (shared_memory)
+      section_handle = shared_memory->handle();
+  }
+  void* data = nullptr;
   HBITMAP bitmap = CreateDIBSection(hdc, &bmi, DIB_RGB_COLORS, &data,
                                     section_handle, 0);
   if (!bitmap) {
     LOG(LS_WARNING) << "Failed to allocate new window frame " << GetLastError();
-    delete shared_memory;
-    return NULL;
+    return nullptr;
   }
 
   return new DesktopFrameWin(size, bytes_per_row,
                              reinterpret_cast<uint8_t*>(data),
-                             shared_memory, bitmap);
+                             std::move(shared_memory), bitmap);
 }
 
 }  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/desktop_frame_win.h b/webrtc/modules/desktop_capture/desktop_frame_win.h
index 15b5883..fffaeab 100644
--- a/webrtc/modules/desktop_capture/desktop_frame_win.h
+++ b/webrtc/modules/desktop_capture/desktop_frame_win.h
@@ -25,7 +25,7 @@
  public:
   virtual ~DesktopFrameWin();
   static DesktopFrameWin* Create(DesktopSize size,
-                                 SharedMemory* shared_memory,
+                                 SharedMemoryFactory* shared_memory_factory,
                                  HDC hdc);
 
   HBITMAP bitmap() { return bitmap_; }
@@ -34,7 +34,7 @@
   DesktopFrameWin(DesktopSize size,
                   int stride,
                   uint8_t* data,
-                  SharedMemory* shared_memory,
+                  rtc::scoped_ptr<SharedMemory> shared_memory,
                   HBITMAP bitmap);
 
   HBITMAP bitmap_;
diff --git a/webrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc b/webrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc
index e3d037b..737d539 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc
+++ b/webrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc
@@ -80,10 +80,6 @@
       .WillOnce(Invoke(this, &ScreenCapturerMacTest::CaptureDoneCallback1))
       .WillOnce(Invoke(this, &ScreenCapturerMacTest::CaptureDoneCallback2));
 
-  EXPECT_CALL(callback_, CreateSharedMemory(_))
-      .Times(AnyNumber())
-      .WillRepeatedly(Return(static_cast<SharedMemory*>(NULL)));
-
   SCOPED_TRACE("");
   capturer_->Start(&callback_);
 
diff --git a/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h b/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h
index 8b83f41..b1f64e4 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h
+++ b/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h
@@ -35,7 +35,6 @@
   MockScreenCapturerCallback() {}
   virtual ~MockScreenCapturerCallback() {}
 
-  MOCK_METHOD1(CreateSharedMemory, SharedMemory*(size_t));
   MOCK_METHOD1(OnCaptureCompleted, void(DesktopFrame*));
 
  private:
diff --git a/webrtc/modules/desktop_capture/screen_capturer_unittest.cc b/webrtc/modules/desktop_capture/screen_capturer_unittest.cc
index a3cf6d9..470baaa 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_unittest.cc
+++ b/webrtc/modules/desktop_capture/screen_capturer_unittest.cc
@@ -28,8 +28,6 @@
 
 class ScreenCapturerTest : public testing::Test {
  public:
-  SharedMemory* CreateSharedMemory(size_t size);
-
   void SetUp() override {
     capturer_.reset(
         ScreenCapturer::Create(DesktopCaptureOptions::CreateDefault()));
@@ -54,9 +52,18 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemory);
 };
 
-SharedMemory* ScreenCapturerTest::CreateSharedMemory(size_t size) {
-  return new FakeSharedMemory(new char[size], size);
-}
+class FakeSharedMemoryFactory : public SharedMemoryFactory {
+ public:
+  FakeSharedMemoryFactory() {}
+  ~FakeSharedMemoryFactory() override {}
+
+  rtc::scoped_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
+    return rtc_make_scoped_ptr(new FakeSharedMemory(new char[size], size));
+  }
+
+ private:
+  RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
+};
 
 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
   webrtc::ScreenCapturer::ScreenList screens;
@@ -77,10 +84,6 @@
   EXPECT_CALL(callback_, OnCaptureCompleted(_))
       .WillOnce(SaveArg<0>(&frame));
 
-  EXPECT_CALL(callback_, CreateSharedMemory(_))
-      .Times(AnyNumber())
-      .WillRepeatedly(Return(static_cast<SharedMemory*>(NULL)));
-
   capturer_->Start(&callback_);
   capturer_->Capture(DesktopRegion());
 
@@ -109,11 +112,9 @@
   EXPECT_CALL(callback_, OnCaptureCompleted(_))
       .WillOnce(SaveArg<0>(&frame));
 
-  EXPECT_CALL(callback_, CreateSharedMemory(_))
-      .Times(AnyNumber())
-      .WillRepeatedly(Invoke(this, &ScreenCapturerTest::CreateSharedMemory));
-
   capturer_->Start(&callback_);
+  capturer_->SetSharedMemoryFactory(
+      rtc_make_scoped_ptr(new FakeSharedMemoryFactory()));
   capturer_->Capture(DesktopRegion());
 
   ASSERT_TRUE(frame);
diff --git a/webrtc/modules/desktop_capture/shared_memory.h b/webrtc/modules/desktop_capture/shared_memory.h
index 631f119..0490bc0 100644
--- a/webrtc/modules/desktop_capture/shared_memory.h
+++ b/webrtc/modules/desktop_capture/shared_memory.h
@@ -17,6 +17,7 @@
 #include <windows.h>
 #endif
 
+#include "webrtc/base/scoped_ptr.h"
 #include "webrtc/base/constructormagic.h"
 #include "webrtc/typedefs.h"
 
@@ -26,8 +27,8 @@
 // parameters of the buffer, but doesn't have any logic to allocate or destroy
 // the actual buffer. DesktopCapturer consumers that need to use shared memory
 // for video frames must extend this class with creation and destruction logic
-// specific for the target platform and then implement
-// DesktopCapturer::Delegate::CreateSharedMemory() as appropriate.
+// specific for the target platform and then call
+// DesktopCapturer::SetSharedMemoryFactory().
 class SharedMemory {
  public:
 #if defined(WEBRTC_WIN)
@@ -62,6 +63,18 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(SharedMemory);
 };
 
+// Interface used to create SharedMemory instances.
+class SharedMemoryFactory {
+ public:
+  SharedMemoryFactory() {}
+  virtual ~SharedMemoryFactory() {}
+
+  virtual rtc::scoped_ptr<SharedMemory> CreateSharedMemory(size_t size) = 0;
+
+ private:
+  RTC_DISALLOW_COPY_AND_ASSIGN(SharedMemoryFactory);
+};
+
 }  // namespace webrtc
 
 #endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_SHARED_MEMORY_H_
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc
index 3cf6487..19079bc 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc
@@ -12,6 +12,8 @@
 
 #include <assert.h>
 
+#include <utility>
+
 #include "webrtc/modules/desktop_capture/desktop_capture_options.h"
 #include "webrtc/modules/desktop_capture/desktop_frame.h"
 #include "webrtc/modules/desktop_capture/desktop_frame_win.h"
@@ -34,6 +36,22 @@
 
 const wchar_t kDwmapiLibraryName[] = L"dwmapi.dll";
 
+// SharedMemoryFactory that creates SharedMemory using the deprecated
+// DesktopCapturer::Callback::CreateSharedMemory().
+class CallbackSharedMemoryFactory : public SharedMemoryFactory {
+ public:
+  CallbackSharedMemoryFactory(DesktopCapturer::Callback* callback)
+      : callback_(callback) {}
+  ~CallbackSharedMemoryFactory() override {}
+
+  rtc::scoped_ptr<SharedMemory> CreateSharedMemory(size_t size) override {
+    return rtc_make_scoped_ptr(callback_->CreateSharedMemory(size));
+  }
+
+ private:
+  DesktopCapturer::Callback* callback_;
+};
+
 }  // namespace
 
 ScreenCapturerWinGdi::ScreenCapturerWinGdi(const DesktopCaptureOptions& options)
@@ -70,6 +88,11 @@
     FreeLibrary(dwmapi_library_);
 }
 
+void ScreenCapturerWinGdi::SetSharedMemoryFactory(
+    rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) {
+  shared_memory_factory_ = std::move(shared_memory_factory);
+}
+
 void ScreenCapturerWinGdi::Capture(const DesktopRegion& region) {
   TickTime capture_start_time = TickTime::Now();
 
@@ -148,6 +171,8 @@
   assert(callback);
 
   callback_ = callback;
+  if (!shared_memory_factory_)
+    shared_memory_factory_.reset(new CallbackSharedMemoryFactory(callback));
 
   // Vote to disable Aero composited desktop effects while capturing. Windows
   // will restore Aero automatically if the process exits. This has no effect
@@ -237,12 +262,8 @@
     assert(desktop_dc_ != NULL);
     assert(memory_dc_ != NULL);
 
-    size_t buffer_size = size.width() * size.height() *
-        DesktopFrame::kBytesPerPixel;
-    SharedMemory* shared_memory = callback_->CreateSharedMemory(buffer_size);
-
-    rtc::scoped_ptr<DesktopFrame> buffer(
-        DesktopFrameWin::Create(size, shared_memory, desktop_dc_));
+    rtc::scoped_ptr<DesktopFrame> buffer(DesktopFrameWin::Create(
+        size, shared_memory_factory_.get(), desktop_dc_));
     if (!buffer.get())
       return false;
     queue_.ReplaceCurrentFrame(buffer.release());
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h
index 202b9aa..a91e744 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h
@@ -34,6 +34,8 @@
 
   // Overridden from ScreenCapturer:
   void Start(Callback* callback) override;
+  void SetSharedMemoryFactory(
+      rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) override;
   void Capture(const DesktopRegion& region) override;
   bool GetScreenList(ScreenList* screens) override;
   bool SelectScreen(ScreenId id) override;
@@ -52,6 +54,7 @@
   void CaptureCursor();
 
   Callback* callback_;
+  rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory_;
   ScreenId current_screen_id_;
   std::wstring current_device_key_;
 
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc
index 066943d..29f0c74 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc
@@ -81,6 +81,11 @@
   InitializeMagnifier();
 }
 
+void ScreenCapturerWinMagnifier::SetSharedMemoryFactory(
+    rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) {
+  shared_memory_factory_ = std::move(shared_memory_factory);
+}
+
 void ScreenCapturerWinMagnifier::Capture(const DesktopRegion& region) {
   TickTime capture_start_time = TickTime::Now();
 
@@ -422,18 +427,12 @@
   // Note that we can't reallocate other buffers at this point, since the caller
   // may still be reading from them.
   if (!queue_.current_frame() || !queue_.current_frame()->size().equals(size)) {
-    size_t buffer_size =
-        size.width() * size.height() * DesktopFrame::kBytesPerPixel;
-    SharedMemory* shared_memory = callback_->CreateSharedMemory(buffer_size);
-
-    rtc::scoped_ptr<DesktopFrame> buffer;
-    if (shared_memory) {
-      buffer.reset(new SharedMemoryDesktopFrame(
-          size, size.width() * DesktopFrame::kBytesPerPixel, shared_memory));
-    } else {
-      buffer.reset(new BasicDesktopFrame(size));
-    }
-    queue_.ReplaceCurrentFrame(buffer.release());
+    rtc::scoped_ptr<DesktopFrame> frame =
+        shared_memory_factory_
+            ? SharedMemoryDesktopFrame::Create(size,
+                                               shared_memory_factory_.get())
+            : rtc::scoped_ptr<DesktopFrame>(new BasicDesktopFrame(size));
+    queue_.ReplaceCurrentFrame(frame.release());
   }
 }
 
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h
index f084e25..4a037be 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h
@@ -44,6 +44,8 @@
 
   // Overridden from ScreenCapturer:
   void Start(Callback* callback) override;
+  void SetSharedMemoryFactory(
+      rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory) override;
   void Capture(const DesktopRegion& region) override;
   bool GetScreenList(ScreenList* screens) override;
   bool SelectScreen(ScreenId id) override;
@@ -104,6 +106,7 @@
   rtc::scoped_ptr<ScreenCapturer> fallback_capturer_;
   bool fallback_capturer_started_;
   Callback* callback_;
+  rtc::scoped_ptr<SharedMemoryFactory> shared_memory_factory_;
   ScreenId current_screen_id_;
   std::wstring current_device_key_;
   HWND excluded_window_;
diff --git a/webrtc/modules/desktop_capture/window_capturer_unittest.cc b/webrtc/modules/desktop_capture/window_capturer_unittest.cc
index 445a4e9..45f2d1a 100644
--- a/webrtc/modules/desktop_capture/window_capturer_unittest.cc
+++ b/webrtc/modules/desktop_capture/window_capturer_unittest.cc
@@ -30,8 +30,6 @@
   void TearDown() override {}
 
   // DesktopCapturer::Callback interface
-  SharedMemory* CreateSharedMemory(size_t size) override { return NULL; }
-
   void OnCaptureCompleted(DesktopFrame* frame) override { frame_.reset(frame); }
 
  protected: