Use std::unique_ptr<> to pass frame ownership in DesktopCapturer impls.

Previously raw pointers were used for owned DesktopFrame instances.
Updated all screen and window capturer implementations to use
std::unique_ptr<>.

Also includes some other cleanups in the capturers:
 - s/NULL/nullptr
 - moved default initializers to class definition.

BUG=webrtc:5950

Review-Url: https://codereview.webrtc.org/1988783003
Cr-Commit-Position: refs/heads/master@{#13058}
diff --git a/webrtc/modules/desktop_capture/cropped_desktop_frame.cc b/webrtc/modules/desktop_capture/cropped_desktop_frame.cc
index 733fe9b..b26d5b0 100644
--- a/webrtc/modules/desktop_capture/cropped_desktop_frame.cc
+++ b/webrtc/modules/desktop_capture/cropped_desktop_frame.cc
@@ -19,7 +19,8 @@
 // A DesktopFrame that is a sub-rect of another DesktopFrame.
 class CroppedDesktopFrame : public DesktopFrame {
  public:
-  CroppedDesktopFrame(DesktopFrame* frame, const DesktopRect& rect);
+  CroppedDesktopFrame(std::unique_ptr<DesktopFrame> frame,
+                      const DesktopRect& rect);
 
  private:
   std::unique_ptr<DesktopFrame> frame_;
@@ -27,23 +28,23 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(CroppedDesktopFrame);
 };
 
-DesktopFrame*
-CreateCroppedDesktopFrame(DesktopFrame* frame, const DesktopRect& rect) {
-  if (!DesktopRect::MakeSize(frame->size()).ContainsRect(rect)) {
-    delete frame;
-    return NULL;
-  }
+std::unique_ptr<DesktopFrame> CreateCroppedDesktopFrame(
+    std::unique_ptr<DesktopFrame> frame,
+    const DesktopRect& rect) {
+  if (!DesktopRect::MakeSize(frame->size()).ContainsRect(rect))
+    return nullptr;
 
-  return new CroppedDesktopFrame(frame, rect);
+  return std::unique_ptr<DesktopFrame>(
+      new CroppedDesktopFrame(std::move(frame), rect));
 }
 
-CroppedDesktopFrame::CroppedDesktopFrame(DesktopFrame* frame,
+CroppedDesktopFrame::CroppedDesktopFrame(std::unique_ptr<DesktopFrame> frame,
                                          const DesktopRect& rect)
     : DesktopFrame(rect.size(),
                    frame->stride(),
                    frame->GetFrameDataAtPos(rect.top_left()),
-                   frame->shared_memory()),
-      frame_(frame) {
+                   frame->shared_memory()) {
+  frame_ = std::move(frame);
 }
 
 }  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/cropped_desktop_frame.h b/webrtc/modules/desktop_capture/cropped_desktop_frame.h
index 29449e2..42ae587 100644
--- a/webrtc/modules/desktop_capture/cropped_desktop_frame.h
+++ b/webrtc/modules/desktop_capture/cropped_desktop_frame.h
@@ -15,10 +15,11 @@
 
 namespace webrtc {
 
-// Always takes ownership of |frame|. Returns NULL if |rect| is not contained
-// by the bounds of |frame|.
-DesktopFrame* CreateCroppedDesktopFrame(DesktopFrame* frame,
-                                        const DesktopRect& rect);
+// Returns nullptr frame if |rect| is not contained by the bounds of |frame|.
+std::unique_ptr<DesktopFrame> CreateCroppedDesktopFrame(
+    std::unique_ptr<DesktopFrame> frame,
+    const DesktopRect& rect);
+
 }  // namespace webrtc
 
 #endif  // WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer.cc b/webrtc/modules/desktop_capture/cropping_window_capturer.cc
index cbe7d96..50aaeea 100644
--- a/webrtc/modules/desktop_capture/cropping_window_capturer.cc
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer.cc
@@ -74,31 +74,31 @@
   return window_capturer_->BringSelectedWindowToFront();
 }
 
-void CroppingWindowCapturer::OnCaptureCompleted(DesktopFrame* frame) {
-  std::unique_ptr<DesktopFrame> screen_frame(frame);
-
+void CroppingWindowCapturer::OnCaptureResult(
+    DesktopCapturer::Result result,
+    std::unique_ptr<DesktopFrame> screen_frame) {
   if (!ShouldUseScreenCapturer()) {
     LOG(LS_INFO) << "Window no longer on top when ScreenCapturer finishes";
     window_capturer_->Capture(DesktopRegion());
     return;
   }
 
-  if (!frame) {
+  if (result != Result::SUCCESS) {
     LOG(LS_WARNING) << "ScreenCapturer failed to capture a frame";
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(result, nullptr);
     return;
   }
 
   DesktopRect window_rect = GetWindowRectInVirtualScreen();
   if (window_rect.is_empty()) {
     LOG(LS_WARNING) << "Window rect is empty";
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
-  std::unique_ptr<DesktopFrame> window_frame(
-      CreateCroppedDesktopFrame(screen_frame.release(), window_rect));
-  callback_->OnCaptureCompleted(window_frame.release());
+  callback_->OnCaptureResult(
+      Result::SUCCESS,
+      CreateCroppedDesktopFrame(std::move(screen_frame), window_rect));
 }
 
 #if !defined(WEBRTC_WIN)
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer.h b/webrtc/modules/desktop_capture/cropping_window_capturer.h
index dfeb447..e2db7da 100644
--- a/webrtc/modules/desktop_capture/cropping_window_capturer.h
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer.h
@@ -42,7 +42,8 @@
 
   // DesktopCapturer::Callback implementation, passed to |screen_capturer_| to
   // intercept the capture result.
-  void OnCaptureCompleted(DesktopFrame* frame) override;
+  void OnCaptureResult(DesktopCapturer::Result result,
+                       std::unique_ptr<DesktopFrame> frame) override;
 
  protected:
   explicit CroppingWindowCapturer(const DesktopCaptureOptions& options);
diff --git a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc
index 4c6e27e..a4deda6 100644
--- a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc
+++ b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.cc
@@ -57,7 +57,7 @@
 class DesktopFrameWithCursor : public DesktopFrame {
  public:
   // Takes ownership of |frame|.
-  DesktopFrameWithCursor(DesktopFrame* frame,
+  DesktopFrameWithCursor(std::unique_ptr<DesktopFrame> frame,
                          const MouseCursor& cursor,
                          const DesktopVector& position);
   virtual ~DesktopFrameWithCursor();
@@ -71,15 +71,18 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(DesktopFrameWithCursor);
 };
 
-DesktopFrameWithCursor::DesktopFrameWithCursor(DesktopFrame* frame,
-                                               const MouseCursor& cursor,
-                                               const DesktopVector& position)
-    : DesktopFrame(frame->size(), frame->stride(),
-                   frame->data(), frame->shared_memory()),
-      original_frame_(frame) {
+DesktopFrameWithCursor::DesktopFrameWithCursor(
+    std::unique_ptr<DesktopFrame> frame,
+    const MouseCursor& cursor,
+    const DesktopVector& position)
+    : DesktopFrame(frame->size(),
+                   frame->stride(),
+                   frame->data(),
+                   frame->shared_memory()) {
   set_dpi(frame->dpi());
   set_capture_time_ms(frame->capture_time_ms());
   mutable_updated_region()->Swap(frame->mutable_updated_region());
+  original_frame_ = std::move(frame);
 
   DesktopVector image_pos = position.subtract(cursor.hotspot());
   DesktopRect target_rect = DesktopRect::MakeSize(cursor.image()->size());
@@ -152,14 +155,15 @@
   desktop_capturer_->SetExcludedWindow(window);
 }
 
-void DesktopAndCursorComposer::OnCaptureCompleted(DesktopFrame* frame) {
-  if (frame && cursor_.get() && cursor_state_ == MouseCursorMonitor::INSIDE) {
-    DesktopFrameWithCursor* frame_with_cursor =
-        new DesktopFrameWithCursor(frame, *cursor_, cursor_position_);
-    frame = frame_with_cursor;
+void DesktopAndCursorComposer::OnCaptureResult(
+    DesktopCapturer::Result result,
+    std::unique_ptr<DesktopFrame> frame) {
+  if (frame && cursor_ && cursor_state_ == MouseCursorMonitor::INSIDE) {
+    frame = std::unique_ptr<DesktopFrameWithCursor>(new DesktopFrameWithCursor(
+        std::move(frame), *cursor_, cursor_position_));
   }
 
-  callback_->OnCaptureCompleted(frame);
+  callback_->OnCaptureResult(result, std::move(frame));
 }
 
 void DesktopAndCursorComposer::OnMouseCursor(MouseCursor* cursor) {
diff --git a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h
index dcbe612..ef63402 100644
--- a/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h
+++ b/webrtc/modules/desktop_capture/desktop_and_cursor_composer.h
@@ -42,7 +42,8 @@
 
  private:
   // DesktopCapturer::Callback interface.
-  void OnCaptureCompleted(DesktopFrame* frame) override;
+  void OnCaptureResult(DesktopCapturer::Result result,
+                       std::unique_ptr<DesktopFrame> frame) override;
 
   // MouseCursorMonitor::Callback interface.
   void OnMouseCursor(MouseCursor* cursor) override;
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 6652a1a..9e89439 100644
--- a/webrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc
+++ b/webrtc/modules/desktop_capture/desktop_and_cursor_composer_unittest.cc
@@ -78,15 +78,17 @@
   void Start(Callback* callback) override { callback_ = callback; }
 
   void Capture(const DesktopRegion& region) override {
-    callback_->OnCaptureCompleted(next_frame_.release());
+    callback_->OnCaptureResult(
+        next_frame_ ? Result::SUCCESS : Result::ERROR_TEMPORARY,
+        std::move(next_frame_));
   }
 
-  void SetNextFrame(DesktopFrame* next_frame) {
-    next_frame_.reset(next_frame);
+  void SetNextFrame(std::unique_ptr<DesktopFrame> next_frame) {
+    next_frame_ = std::move(next_frame);
   }
 
  private:
-  Callback* callback_;
+  Callback* callback_ = nullptr;
 
   std::unique_ptr<DesktopFrame> next_frame_;
 };
@@ -165,11 +167,13 @@
   DesktopAndCursorComposerTest()
       : fake_screen_(new FakeScreenCapturer()),
         fake_cursor_(new FakeMouseMonitor()),
-        blender_(fake_screen_, fake_cursor_) {
-  }
+        blender_(fake_screen_, fake_cursor_) {}
 
   // DesktopCapturer::Callback interface
-  void OnCaptureCompleted(DesktopFrame* frame) override { frame_.reset(frame); }
+  void OnCaptureResult(DesktopCapturer::Result result,
+                       std::unique_ptr<DesktopFrame> frame) override {
+    frame_ = std::move(frame);
+  }
 
  protected:
   // Owned by |blender_|.
@@ -187,7 +191,7 @@
 
   fake_cursor_->SetHotspot(DesktopVector());
   fake_cursor_->SetState(MouseCursorMonitor::INSIDE, DesktopVector());
-  fake_screen_->SetNextFrame(NULL);
+  fake_screen_->SetNextFrame(nullptr);
 
   blender_.Capture(DesktopRegion());
 
diff --git a/webrtc/modules/desktop_capture/desktop_capturer.h b/webrtc/modules/desktop_capture/desktop_capturer.h
index ba70e01..80d9109 100644
--- a/webrtc/modules/desktop_capture/desktop_capturer.h
+++ b/webrtc/modules/desktop_capture/desktop_capturer.h
@@ -15,24 +15,45 @@
 
 #include <memory>
 
+#include "webrtc/modules/desktop_capture/desktop_frame.h"
 #include "webrtc/modules/desktop_capture/desktop_capture_types.h"
 #include "webrtc/modules/desktop_capture/shared_memory.h"
 
 namespace webrtc {
 
 class DesktopFrame;
-class DesktopRegion;
 
 // Abstract interface for screen and window capturers.
 class DesktopCapturer {
  public:
+  enum class Result {
+    // The frame was captured successfully.
+    SUCCESS,
+
+    // There was a temporary error. The caller should continue calling
+    // Capture(), in the expectation that it will eventually recover.
+    ERROR_TEMPORARY,
+
+    // Capture has failed and will keep failing if the caller tries calling
+    // Capture() again.
+    ERROR_PERMANENT,
+  };
+
   // Interface that must be implemented by the DesktopCapturer consumers.
   class Callback {
    public:
-    // 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
-    // (e.g. the window has been closed).
-    virtual void OnCaptureCompleted(DesktopFrame* frame) = 0;
+    // Called after a frame has been captured. |frame| is not nullptr if and
+    // only if |result| is SUCCESS.
+    virtual void OnCaptureResult(Result result,
+                                 std::unique_ptr<DesktopFrame> frame) {
+      OnCaptureCompleted(frame.release());
+    }
+
+    // Deprecated version of the method above that uses raw pointer instead of
+    // std::unique_ptr<>.
+    // TODO(sergeyu): Remove this method and make OnCaptureResult() pure
+    // virtual. crbug.com/webrtc/5950
+    virtual void OnCaptureCompleted(DesktopFrame* frame) { delete frame; };
 
    protected:
     virtual ~Callback() {}
diff --git a/webrtc/modules/desktop_capture/desktop_frame_win.cc b/webrtc/modules/desktop_capture/desktop_frame_win.cc
index 624b729..6adce92 100644
--- a/webrtc/modules/desktop_capture/desktop_frame_win.cc
+++ b/webrtc/modules/desktop_capture/desktop_frame_win.cc
@@ -30,7 +30,7 @@
 }
 
 // static
-DesktopFrameWin* DesktopFrameWin::Create(
+std::unique_ptr<DesktopFrameWin> DesktopFrameWin::Create(
     DesktopSize size,
     SharedMemoryFactory* shared_memory_factory,
     HDC hdc) {
@@ -60,9 +60,9 @@
     return nullptr;
   }
 
-  return new DesktopFrameWin(size, bytes_per_row,
-                             reinterpret_cast<uint8_t*>(data),
-                             std::move(shared_memory), bitmap);
+  return std::unique_ptr<DesktopFrameWin>(
+      new DesktopFrameWin(size, bytes_per_row, reinterpret_cast<uint8_t*>(data),
+                          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 3513e14..e9a374b 100644
--- a/webrtc/modules/desktop_capture/desktop_frame_win.h
+++ b/webrtc/modules/desktop_capture/desktop_frame_win.h
@@ -26,9 +26,9 @@
 class DesktopFrameWin : public DesktopFrame {
  public:
   virtual ~DesktopFrameWin();
-  static DesktopFrameWin* Create(DesktopSize size,
-                                 SharedMemoryFactory* shared_memory_factory,
-                                 HDC hdc);
+
+  static std::unique_ptr<DesktopFrameWin>
+  Create(DesktopSize size, SharedMemoryFactory* shared_memory_factory, HDC hdc);
 
   HBITMAP bitmap() { return bitmap_; }
 
diff --git a/webrtc/modules/desktop_capture/screen_capture_frame_queue.h b/webrtc/modules/desktop_capture/screen_capture_frame_queue.h
index 97f3b81..b7945b0 100644
--- a/webrtc/modules/desktop_capture/screen_capture_frame_queue.h
+++ b/webrtc/modules/desktop_capture/screen_capture_frame_queue.h
@@ -49,8 +49,8 @@
 
   // Replaces the current frame with a new one allocated by the caller. The
   // existing frame (if any) is destroyed. Takes ownership of |frame|.
-  void ReplaceCurrentFrame(FrameType* frame) {
-    frames_[current_].reset(frame);
+  void ReplaceCurrentFrame(std::unique_ptr<FrameType> frame) {
+    frames_[current_] = std::move(frame);
   }
 
   // Marks all frames obsolete and resets the previous frame pointer. No
diff --git a/webrtc/modules/desktop_capture/screen_capturer_mac.mm b/webrtc/modules/desktop_capture/screen_capturer_mac.mm
index bf6c729..b846b75 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_mac.mm
+++ b/webrtc/modules/desktop_capture/screen_capturer_mac.mm
@@ -96,15 +96,15 @@
 // caller should release the returned CFArrayRef.
 CFArrayRef CreateWindowListWithExclusion(CGWindowID window_to_exclude) {
   if (!window_to_exclude)
-    return NULL;
+    return nullptr;
 
   CFArrayRef all_windows = CGWindowListCopyWindowInfo(
       kCGWindowListOptionOnScreenOnly, kCGNullWindowID);
   if (!all_windows)
-    return NULL;
+    return nullptr;
 
-  CFMutableArrayRef returned_array = CFArrayCreateMutable(
-      NULL, CFArrayGetCount(all_windows), NULL);
+  CFMutableArrayRef returned_array =
+      CFArrayCreateMutable(nullptr, CFArrayGetCount(all_windows), nullptr);
 
   bool found = false;
   for (CFIndex i = 0; i < CFArrayGetCount(all_windows); ++i) {
@@ -126,7 +126,7 @@
 
   if (!found) {
     CFRelease(returned_array);
-    returned_array = NULL;
+    returned_array = nullptr;
   }
   return returned_array;
 }
@@ -143,7 +143,7 @@
   ids[0] = window;
 
   CFArrayRef window_id_array =
-      CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL);
+      CFArrayCreate(nullptr, reinterpret_cast<const void**>(&ids), 1, nullptr);
   CFArrayRef window_array =
       CGWindowListCreateDescriptionFromArray(window_id_array);
 
@@ -229,11 +229,11 @@
                                        void *user_parameter);
   void ReleaseBuffers();
 
-  DesktopFrame* CreateFrame();
+  std::unique_ptr<DesktopFrame> CreateFrame();
 
-  Callback* callback_;
+  Callback* callback_ = nullptr;
 
-  CGLContextObj cgl_context_;
+  CGLContextObj cgl_context_ = nullptr;
   ScopedPixelBufferObject pixel_buffer_object_;
 
   // Queue of the frames buffers.
@@ -244,13 +244,13 @@
 
   // Currently selected display, or 0 if the full desktop is selected. On OS X
   // 10.6 and before, this is always 0.
-  CGDirectDisplayID current_display_;
+  CGDirectDisplayID current_display_ = 0;
 
   // The physical pixel bounds of the current screen.
   DesktopRect screen_pixel_bounds_;
 
   // The dip to physical pixel scale of the current screen.
-  float dip_to_pixel_scale_;
+  float dip_to_pixel_scale_ = 1.0f;
 
   // A thread-safe list of invalid rectangles, and the size of the most
   // recently captured screen.
@@ -263,20 +263,20 @@
   rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor_;
 
   // Power management assertion to prevent the screen from sleeping.
-  IOPMAssertionID power_assertion_id_display_;
+  IOPMAssertionID power_assertion_id_display_ = kIOPMNullAssertionID;
 
   // Power management assertion to indicate that the user is active.
-  IOPMAssertionID power_assertion_id_user_;
+  IOPMAssertionID power_assertion_id_user_ = kIOPMNullAssertionID;
 
   // Dynamically link to deprecated APIs for Mac OS X 10.6 support.
-  void* app_services_library_;
-  CGDisplayBaseAddressFunc cg_display_base_address_;
-  CGDisplayBytesPerRowFunc cg_display_bytes_per_row_;
-  CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_;
-  void* opengl_library_;
-  CGLSetFullScreenFunc cgl_set_full_screen_;
+  void* app_services_library_ = nullptr;
+  CGDisplayBaseAddressFunc cg_display_base_address_ = nullptr;
+  CGDisplayBytesPerRowFunc cg_display_bytes_per_row_ = nullptr;
+  CGDisplayBitsPerPixelFunc cg_display_bits_per_pixel_ = nullptr;
+  void* opengl_library_ = nullptr;
+  CGLSetFullScreenFunc cgl_set_full_screen_ = nullptr;
 
-  CGWindowID excluded_window_;
+  CGWindowID excluded_window_ = 0;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerMac);
 };
@@ -285,16 +285,16 @@
 // stride.
 class InvertedDesktopFrame : public DesktopFrame {
  public:
-  // Takes ownership of |frame|.
-  InvertedDesktopFrame(DesktopFrame* frame)
+  InvertedDesktopFrame(std::unique_ptr<DesktopFrame> frame)
       : DesktopFrame(
-            frame->size(), -frame->stride(),
+            frame->size(),
+            -frame->stride(),
             frame->data() + (frame->size().height() - 1) * frame->stride(),
-            frame->shared_memory()),
-        original_frame_(frame) {
-    set_dpi(frame->dpi());
-    set_capture_time_ms(frame->capture_time_ms());
-    mutable_updated_region()->Swap(frame->mutable_updated_region());
+            frame->shared_memory()) {
+    original_frame_ = std::move(frame);
+    set_dpi(original_frame_->dpi());
+    set_capture_time_ms(original_frame_->capture_time_ms());
+    mutable_updated_region()->Swap(original_frame_->mutable_updated_region());
   }
   virtual ~InvertedDesktopFrame() {}
 
@@ -306,21 +306,7 @@
 
 ScreenCapturerMac::ScreenCapturerMac(
     rtc::scoped_refptr<DesktopConfigurationMonitor> desktop_config_monitor)
-    : callback_(NULL),
-      cgl_context_(NULL),
-      current_display_(0),
-      dip_to_pixel_scale_(1.0f),
-      desktop_config_monitor_(desktop_config_monitor),
-      power_assertion_id_display_(kIOPMNullAssertionID),
-      power_assertion_id_user_(kIOPMNullAssertionID),
-      app_services_library_(NULL),
-      cg_display_base_address_(NULL),
-      cg_display_bytes_per_row_(NULL),
-      cg_display_bits_per_pixel_(NULL),
-      opengl_library_(NULL),
-      cgl_set_full_screen_(NULL),
-      excluded_window_(0) {
-}
+    : desktop_config_monitor_(desktop_config_monitor) {}
 
 ScreenCapturerMac::~ScreenCapturerMac() {
   if (power_assertion_id_display_ != kIOPMNullAssertionID) {
@@ -353,7 +339,7 @@
   if (cgl_context_) {
     pixel_buffer_object_.Release();
     CGLDestroyContext(cgl_context_);
-    cgl_context_ = NULL;
+    cgl_context_ = nullptr;
   }
   // The buffers might be in use by the encoder, so don't delete them here.
   // Instead, mark them as "needs update"; next time the buffers are used by
@@ -419,7 +405,7 @@
     // APIS currently crash on 10.6.8 if there is no monitor attached.
     if (!CgBlitPostLion(*current_frame, region)) {
       desktop_config_monitor_->Unlock();
-      callback_->OnCaptureCompleted(NULL);
+      callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
       return;
     }
   } else if (cgl_context_) {
@@ -435,11 +421,11 @@
     CgBlitPreLion(*current_frame, region);
   }
 
-  DesktopFrame* new_frame = queue_.current_frame()->Share();
+  std::unique_ptr<DesktopFrame> new_frame = queue_.current_frame()->Share();
   *new_frame->mutable_updated_region() = region;
 
   if (flip)
-    new_frame = new InvertedDesktopFrame(new_frame);
+    new_frame.reset(new InvertedDesktopFrame(std::move(new_frame)));
 
   helper_.set_size_most_recent(new_frame->size());
 
@@ -447,10 +433,9 @@
   // and accessing display structures.
   desktop_config_monitor_->Unlock();
 
-  new_frame->set_capture_time_ms(
-      (rtc::TimeNanos() - capture_start_time_nanos) /
-      rtc::kNumNanosecsPerMillisec);
-  callback_->OnCaptureCompleted(new_frame);
+  new_frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) /
+                                 rtc::kNumNanosecsPerMillisec);
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(new_frame));
 }
 
 void ScreenCapturerMac::SetExcludedWindow(WindowId window) {
@@ -534,7 +519,7 @@
                GL_UNSIGNED_BYTE, 0);
   GLubyte* ptr = static_cast<GLubyte*>(
       glMapBufferARB(GL_PIXEL_PACK_BUFFER_ARB, GL_READ_ONLY_ARB));
-  if (ptr == NULL) {
+  if (!ptr) {
     // If the buffer can't be mapped, assume that it's no longer valid and
     // release it.
     pixel_buffer_object_.Release();
@@ -642,8 +627,7 @@
   // TODO(wez): Get rid of this as per crbug.com/145064, or implement
   // crbug.com/92354.
   if (queue_.previous_frame()) {
-    memcpy(frame.data(),
-           queue_.previous_frame()->data(),
+    memcpy(frame.data(), queue_.previous_frame()->data(),
            frame.stride() * frame.size().height());
   }
 
@@ -692,7 +676,7 @@
     copy_region.Translate(-display_bounds.left(), -display_bounds.top());
 
     DesktopRect excluded_window_bounds;
-    CGImageRef excluded_image = NULL;
+    CGImageRef excluded_image = nullptr;
     if (excluded_window_ && window_list) {
       // Get the region of the excluded window relative the primary display.
       excluded_window_bounds = GetExcludedWindowPixelBounds(
@@ -710,7 +694,7 @@
 
     // Create an image containing a snapshot of the display.
     CGImageRef image = CGDisplayCreateImage(display_config.id);
-    if (image == NULL) {
+    if (!image) {
       if (excluded_image)
         CFRelease(excluded_image);
       continue;
@@ -874,13 +858,13 @@
     (CGLPixelFormatAttribute)CGDisplayIDToOpenGLDisplayMask(mainDevice),
     (CGLPixelFormatAttribute)0
   };
-  CGLPixelFormatObj pixel_format = NULL;
+  CGLPixelFormatObj pixel_format = nullptr;
   GLint matching_pixel_format_count = 0;
   CGLError err = CGLChoosePixelFormat(attributes,
                                       &pixel_format,
                                       &matching_pixel_format_count);
   assert(err == kCGLNoError);
-  err = CGLCreateContext(pixel_format, NULL, &cgl_context_);
+  err = CGLCreateContext(pixel_format, nullptr, &cgl_context_);
   assert(err == kCGLNoError);
   CGLDestroyPixelFormat(pixel_format);
   (*cgl_set_full_screen_)(cgl_context_);
@@ -969,13 +953,12 @@
   capturer->ScreenUpdateMove(delta, count, rect_array);
 }
 
-DesktopFrame* ScreenCapturerMac::CreateFrame() {
+std::unique_ptr<DesktopFrame> ScreenCapturerMac::CreateFrame() {
   std::unique_ptr<DesktopFrame> frame(
       new BasicDesktopFrame(screen_pixel_bounds_.size()));
-
   frame->set_dpi(DesktopVector(kStandardDPI * dip_to_pixel_scale_,
                                kStandardDPI * dip_to_pixel_scale_));
-  return frame.release();
+  return frame;
 }
 
 }  // namespace
@@ -983,7 +966,7 @@
 // static
 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) {
   if (!options.configuration_monitor())
-    return NULL;
+    return nullptr;
 
   std::unique_ptr<ScreenCapturerMac> capturer(
       new ScreenCapturerMac(options.configuration_monitor()));
diff --git a/webrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc b/webrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc
index 815c7f5..47e7219 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc
+++ b/webrtc/modules/desktop_capture/screen_capturer_mac_unittest.cc
@@ -32,11 +32,13 @@
 class ScreenCapturerMacTest : public testing::Test {
  public:
   // Verifies that the whole screen is initially dirty.
-  void CaptureDoneCallback1(DesktopFrame* frame);
+  void CaptureDoneCallback1(DesktopCapturer::Result result,
+                            std::unique_ptr<DesktopFrame>* frame);
 
   // Verifies that a rectangle explicitly marked as dirty is propagated
   // correctly.
-  void CaptureDoneCallback2(DesktopFrame* frame);
+  void CaptureDoneCallback2(DesktopCapturer::Result result,
+                            std::unique_ptr<DesktopFrame>* frame);
 
  protected:
   void SetUp() override {
@@ -49,37 +51,40 @@
 };
 
 void ScreenCapturerMacTest::CaptureDoneCallback1(
-    DesktopFrame* frame) {
-  std::unique_ptr<DesktopFrame> owned_frame(frame);
+    DesktopCapturer::Result result,
+    std::unique_ptr<DesktopFrame>* frame) {
+  EXPECT_EQ(result, DesktopCapturer::Result::SUCCESS);
 
   MacDesktopConfiguration config = MacDesktopConfiguration::GetCurrent(
       MacDesktopConfiguration::BottomLeftOrigin);
 
   // Verify that the region contains full frame.
-  DesktopRegion::Iterator it(frame->updated_region());
+  DesktopRegion::Iterator it((*frame)->updated_region());
   EXPECT_TRUE(!it.IsAtEnd() && it.rect().equals(config.pixel_bounds));
 }
 
 void ScreenCapturerMacTest::CaptureDoneCallback2(
-    DesktopFrame* frame) {
-  std::unique_ptr<DesktopFrame> owned_frame(frame);
+    DesktopCapturer::Result result,
+    std::unique_ptr<DesktopFrame>* frame) {
+  EXPECT_EQ(result, DesktopCapturer::Result::SUCCESS);
 
   MacDesktopConfiguration config = MacDesktopConfiguration::GetCurrent(
       MacDesktopConfiguration::BottomLeftOrigin);
   int width = config.pixel_bounds.width();
   int height = config.pixel_bounds.height();
 
-  EXPECT_EQ(width, frame->size().width());
-  EXPECT_EQ(height, frame->size().height());
-  EXPECT_TRUE(frame->data() != NULL);
+  EXPECT_EQ(width, (*frame)->size().width());
+  EXPECT_EQ(height, (*frame)->size().height());
+  EXPECT_TRUE((*frame)->data() != NULL);
   // Depending on the capture method, the screen may be flipped or not, so
   // the stride may be positive or negative.
   EXPECT_EQ(static_cast<int>(sizeof(uint32_t) * width),
-            abs(frame->stride()));
+            abs((*frame)->stride()));
 }
 
 TEST_F(ScreenCapturerMacTest, Capture) {
-  EXPECT_CALL(callback_, OnCaptureCompleted(_))
+  EXPECT_CALL(callback_,
+              OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
       .Times(2)
       .WillOnce(Invoke(this, &ScreenCapturerMacTest::CaptureDoneCallback1))
       .WillOnce(Invoke(this, &ScreenCapturerMacTest::CaptureDoneCallback2));
diff --git a/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h b/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h
index 7264249..1f17e8c 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h
+++ b/webrtc/modules/desktop_capture/screen_capturer_mock_objects.h
@@ -36,7 +36,13 @@
   MockScreenCapturerCallback() {}
   virtual ~MockScreenCapturerCallback() {}
 
-  MOCK_METHOD1(OnCaptureCompleted, void(DesktopFrame*));
+  MOCK_METHOD2(OnCaptureResultPtr,
+               void(DesktopCapturer::Result result,
+                    std::unique_ptr<DesktopFrame>* frame));
+  void OnCaptureResult(DesktopCapturer::Result result,
+                       std::unique_ptr<DesktopFrame> frame) override {
+    OnCaptureResultPtr(result, &frame);
+  }
 
  private:
   RTC_DISALLOW_COPY_AND_ASSIGN(MockScreenCapturerCallback);
diff --git a/webrtc/modules/desktop_capture/screen_capturer_unittest.cc b/webrtc/modules/desktop_capture/screen_capturer_unittest.cc
index bc87ed3..4d7799c 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_unittest.cc
+++ b/webrtc/modules/desktop_capture/screen_capturer_unittest.cc
@@ -23,7 +23,6 @@
 using ::testing::_;
 using ::testing::AnyNumber;
 using ::testing::Return;
-using ::testing::SaveArg;
 
 const int kTestSharedMemoryId = 123;
 
@@ -69,6 +68,10 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(FakeSharedMemoryFactory);
 };
 
+ACTION_P(SaveUniquePtrArg, dest) {
+  *dest = std::move(*arg1);
+}
+
 TEST_F(ScreenCapturerTest, GetScreenListAndSelectScreen) {
   webrtc::ScreenCapturer::ScreenList screens;
   EXPECT_TRUE(capturer_->GetScreenList(&screens));
@@ -84,9 +87,10 @@
 
 TEST_F(ScreenCapturerTest, Capture) {
   // Assume that Start() treats the screen as invalid initially.
-  DesktopFrame* frame = NULL;
-  EXPECT_CALL(callback_, OnCaptureCompleted(_))
-      .WillOnce(SaveArg<0>(&frame));
+  std::unique_ptr<DesktopFrame> frame;
+  EXPECT_CALL(callback_,
+              OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
+      .WillOnce(SaveUniquePtrArg(&frame));
 
   capturer_->Start(&callback_);
   capturer_->Capture(DesktopRegion());
@@ -105,16 +109,15 @@
   EXPECT_TRUE(it.rect().equals(DesktopRect::MakeSize(frame->size())));
   it.Advance();
   EXPECT_TRUE(it.IsAtEnd());
-
-  delete frame;
 }
 
 #if defined(WEBRTC_WIN)
 
 TEST_F(ScreenCapturerTest, UseSharedBuffers) {
-  DesktopFrame* frame = NULL;
-  EXPECT_CALL(callback_, OnCaptureCompleted(_))
-      .WillOnce(SaveArg<0>(&frame));
+  std::unique_ptr<DesktopFrame> frame;
+  EXPECT_CALL(callback_,
+              OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
+      .WillOnce(SaveUniquePtrArg(&frame));
 
   capturer_->Start(&callback_);
   capturer_->SetSharedMemoryFactory(
@@ -124,8 +127,6 @@
   ASSERT_TRUE(frame);
   ASSERT_TRUE(frame->shared_memory());
   EXPECT_EQ(frame->shared_memory()->id(), kTestSharedMemoryId);
-
-  delete frame;
 }
 
 TEST_F(ScreenCapturerTest, UseMagnifier) {
@@ -133,13 +134,14 @@
   options.set_allow_use_magnification_api(true);
   capturer_.reset(ScreenCapturer::Create(options));
 
-  DesktopFrame* frame = NULL;
-  EXPECT_CALL(callback_, OnCaptureCompleted(_)).WillOnce(SaveArg<0>(&frame));
+  std::unique_ptr<DesktopFrame> frame;
+  EXPECT_CALL(callback_,
+              OnCaptureResultPtr(DesktopCapturer::Result::SUCCESS, _))
+      .WillOnce(SaveUniquePtrArg(&frame));
 
   capturer_->Start(&callback_);
   capturer_->Capture(DesktopRegion());
   ASSERT_TRUE(frame);
-  delete frame;
 }
 
 #endif  // defined(WEBRTC_WIN)
diff --git a/webrtc/modules/desktop_capture/screen_capturer_x11.cc b/webrtc/modules/desktop_capture/screen_capturer_x11.cc
index 5540e68..57c2e5f 100644
--- a/webrtc/modules/desktop_capture/screen_capturer_x11.cc
+++ b/webrtc/modules/desktop_capture/screen_capturer_x11.cc
@@ -66,7 +66,7 @@
   // from HandleXEvent(). In the non-DAMAGE case, this captures the
   // whole screen, then calculates some invalid rectangles that include any
   // differences between this and the previous capture.
-  DesktopFrame* CaptureScreen();
+  std::unique_ptr<DesktopFrame> CaptureScreen();
 
   // Called when the screen configuration is changed.
   void ScreenConfigurationChanged();
@@ -82,23 +82,23 @@
 
   DesktopCaptureOptions options_;
 
-  Callback* callback_;
+  Callback* callback_ = nullptr;
 
   // X11 graphics context.
-  GC gc_;
-  Window root_window_;
+  GC gc_ = nullptr;
+  Window root_window_ = BadValue;
 
   // XFixes.
-  bool has_xfixes_;
-  int xfixes_event_base_;
-  int xfixes_error_base_;
+  bool has_xfixes_ = false;
+  int xfixes_event_base_ = -1;
+  int xfixes_error_base_ = -1;
 
   // XDamage information.
-  bool use_damage_;
-  Damage damage_handle_;
-  int damage_event_base_;
-  int damage_error_base_;
-  XserverRegion damage_region_;
+  bool use_damage_ = false;
+  Damage damage_handle_ = 0;
+  int damage_event_base_ = -1;
+  int damage_error_base_ = -1;
+  XserverRegion damage_region_ = 0;
 
   // Access to the X Server's pixel buffer.
   XServerPixelBuffer x_server_pixel_buffer_;
@@ -120,18 +120,7 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerLinux);
 };
 
-ScreenCapturerLinux::ScreenCapturerLinux()
-    : callback_(NULL),
-      gc_(NULL),
-      root_window_(BadValue),
-      has_xfixes_(false),
-      xfixes_event_base_(-1),
-      xfixes_error_base_(-1),
-      use_damage_(false),
-      damage_handle_(0),
-      damage_event_base_(-1),
-      damage_error_base_(-1),
-      damage_region_(0) {
+ScreenCapturerLinux::ScreenCapturerLinux() {
   helper_.SetLogGridSize(4);
 }
 
@@ -249,7 +238,7 @@
   // in a good shape.
   if (!x_server_pixel_buffer_.is_initialized()) {
      // We failed to initialize pixel buffer.
-     callback_->OnCaptureCompleted(NULL);
+     callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
      return;
   }
 
@@ -257,29 +246,26 @@
   // Note that we can't reallocate other buffers at this point, since the caller
   // may still be reading from them.
   if (!queue_.current_frame()) {
-    std::unique_ptr<DesktopFrame> frame(
-        new BasicDesktopFrame(x_server_pixel_buffer_.window_size()));
-    queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(frame.release()));
+    queue_.ReplaceCurrentFrame(
+        SharedDesktopFrame::Wrap(std::unique_ptr<DesktopFrame>(
+            new BasicDesktopFrame(x_server_pixel_buffer_.window_size()))));
   }
 
   // Refresh the Differ helper used by CaptureFrame(), if needed.
   DesktopFrame* frame = queue_.current_frame();
-  if (!use_damage_ && (
-      !differ_.get() ||
-      (differ_->width() != frame->size().width()) ||
-      (differ_->height() != frame->size().height()) ||
-      (differ_->bytes_per_row() != frame->stride()))) {
+  if (!use_damage_ &&
+      (!differ_ || (differ_->width() != frame->size().width()) ||
+       (differ_->height() != frame->size().height()) ||
+       (differ_->bytes_per_row() != frame->stride()))) {
     differ_.reset(new Differ(frame->size().width(), frame->size().height(),
-                             DesktopFrame::kBytesPerPixel,
-                             frame->stride()));
+                             DesktopFrame::kBytesPerPixel, frame->stride()));
   }
 
-  DesktopFrame* result = CaptureScreen();
+  std::unique_ptr<DesktopFrame> result = CaptureScreen();
   last_invalid_region_ = result->updated_region();
-  result->set_capture_time_ms(
-      (rtc::TimeNanos() - capture_start_time_nanos) /
-      rtc::kNumNanosecsPerMillisec);
-  callback_->OnCaptureCompleted(result);
+  result->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) /
+                              rtc::kNumNanosecsPerMillisec);
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
 }
 
 bool ScreenCapturerLinux::GetScreenList(ScreenList* screens) {
@@ -311,8 +297,8 @@
   return false;
 }
 
-DesktopFrame* ScreenCapturerLinux::CaptureScreen() {
-  DesktopFrame* frame = queue_.current_frame()->Share();
+std::unique_ptr<DesktopFrame> ScreenCapturerLinux::CaptureScreen() {
+  std::unique_ptr<SharedDesktopFrame> frame = queue_.current_frame()->Share();
   assert(x_server_pixel_buffer_.window_size().equals(frame->size()));
 
   // Pass the screen size to the helper, so it can clip the invalid region if it
@@ -354,18 +340,18 @@
 
     for (DesktopRegion::Iterator it(*updated_region);
          !it.IsAtEnd(); it.Advance()) {
-      x_server_pixel_buffer_.CaptureRect(it.rect(), frame);
+      x_server_pixel_buffer_.CaptureRect(it.rect(), frame.get());
     }
   } else {
     // Doing full-screen polling, or this is the first capture after a
     // screen-resolution change.  In either case, need a full-screen capture.
     DesktopRect screen_rect = DesktopRect::MakeSize(frame->size());
-    x_server_pixel_buffer_.CaptureRect(screen_rect, frame);
+    x_server_pixel_buffer_.CaptureRect(screen_rect, frame.get());
 
     if (queue_.previous_frame()) {
       // Full-screen polling, so calculate the invalid rects here, based on the
       // changed pixels between current and previous buffers.
-      RTC_DCHECK(differ_.get() != NULL);
+      RTC_DCHECK(differ_);
       RTC_DCHECK(queue_.previous_frame()->data());
       differ_->CalcDirtyRegion(queue_.previous_frame()->data(),
                                frame->data(), updated_region);
@@ -378,7 +364,7 @@
     }
   }
 
-  return frame;
+  return std::move(frame);
 }
 
 void ScreenCapturerLinux::ScreenConfigurationChanged() {
@@ -415,7 +401,7 @@
 void ScreenCapturerLinux::DeinitXlib() {
   if (gc_) {
     XFreeGC(display(), gc_);
-    gc_ = NULL;
+    gc_ = nullptr;
   }
 
   x_server_pixel_buffer_.Release();
@@ -438,7 +424,7 @@
 // static
 ScreenCapturer* ScreenCapturer::Create(const DesktopCaptureOptions& options) {
   if (!options.x_display())
-    return NULL;
+    return nullptr;
 
   std::unique_ptr<ScreenCapturerLinux> capturer(new ScreenCapturerLinux());
   if (!capturer->Init(options))
diff --git a/webrtc/modules/desktop_capture/shared_desktop_frame.cc b/webrtc/modules/desktop_capture/shared_desktop_frame.cc
index 8d10827..e069a54 100644
--- a/webrtc/modules/desktop_capture/shared_desktop_frame.cc
+++ b/webrtc/modules/desktop_capture/shared_desktop_frame.cc
@@ -17,49 +17,25 @@
 
 namespace webrtc {
 
-class SharedDesktopFrame::Core {
- public:
-  Core(DesktopFrame* frame) : frame_(frame) {}
-
-  DesktopFrame* frame() { return frame_.get(); }
-
-  bool HasOneRef() { return ref_count_.Value() == 1; }
-
-  virtual int32_t AddRef() {
-    return ++ref_count_;
-  }
-
-  virtual int32_t Release() {
-    int32_t ref_count;
-    ref_count = --ref_count_;
-    if (ref_count == 0)
-      delete this;
-    return ref_count;
-  }
-
- private:
-  virtual ~Core() {}
-
-  Atomic32 ref_count_;
-  std::unique_ptr<DesktopFrame> frame_;
-
-  RTC_DISALLOW_COPY_AND_ASSIGN(Core);
-};
-
 SharedDesktopFrame::~SharedDesktopFrame() {}
 
 // static
+std::unique_ptr<SharedDesktopFrame> SharedDesktopFrame::Wrap(
+    std::unique_ptr<DesktopFrame> desktop_frame) {
+  return std::unique_ptr<SharedDesktopFrame>(
+      new SharedDesktopFrame(new Core(desktop_frame.release())));
+}
+
 SharedDesktopFrame* SharedDesktopFrame::Wrap(DesktopFrame* desktop_frame) {
-  rtc::scoped_refptr<Core> core(new Core(desktop_frame));
-  return new SharedDesktopFrame(core);
+  return Wrap(std::unique_ptr<DesktopFrame>(desktop_frame)).release();
 }
 
 DesktopFrame* SharedDesktopFrame::GetUnderlyingFrame() {
-  return core_->frame();
+  return core_->get();
 }
 
-SharedDesktopFrame* SharedDesktopFrame::Share() {
-  SharedDesktopFrame* result = new SharedDesktopFrame(core_);
+std::unique_ptr<SharedDesktopFrame> SharedDesktopFrame::Share() {
+  std::unique_ptr<SharedDesktopFrame> result(new SharedDesktopFrame(core_));
   result->set_dpi(dpi());
   result->set_capture_time_ms(capture_time_ms());
   *result->mutable_updated_region() = updated_region();
@@ -71,11 +47,10 @@
 }
 
 SharedDesktopFrame::SharedDesktopFrame(rtc::scoped_refptr<Core> core)
-    : DesktopFrame(core->frame()->size(),
-                   core->frame()->stride(),
-                   core->frame()->data(),
-                   core->frame()->shared_memory()),
-      core_(core) {
-}
+    : DesktopFrame((*core)->size(),
+                   (*core)->stride(),
+                   (*core)->data(),
+                   (*core)->shared_memory()),
+      core_(core) {}
 
 }  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/shared_desktop_frame.h b/webrtc/modules/desktop_capture/shared_desktop_frame.h
index 4f6a2bb..d9a521b 100644
--- a/webrtc/modules/desktop_capture/shared_desktop_frame.h
+++ b/webrtc/modules/desktop_capture/shared_desktop_frame.h
@@ -12,6 +12,7 @@
 #define WEBRTC_MODULES_DESKTOP_CAPTURE_SHARED_DESKTOP_FRAME_H_
 
 #include "webrtc/base/constructormagic.h"
+#include "webrtc/base/refcount.h"
 #include "webrtc/base/scoped_ref_ptr.h"
 #include "webrtc/modules/desktop_capture/desktop_frame.h"
 
@@ -23,20 +24,25 @@
  public:
   virtual ~SharedDesktopFrame();
 
+  static std::unique_ptr<SharedDesktopFrame> Wrap(
+      std::unique_ptr<DesktopFrame> desktop_frame);
+
+  // Deprecated.
+  // TODO(sergeyu): remove this method.
   static SharedDesktopFrame* Wrap(DesktopFrame* desktop_frame);
 
   // Returns the underlying instance of DesktopFrame.
   DesktopFrame* GetUnderlyingFrame();
 
   // Creates a clone of this object.
-  SharedDesktopFrame* Share();
+  std::unique_ptr<SharedDesktopFrame> Share();
 
   // Checks if the frame is currently shared. If it returns false it's
   // guaranteed that there are no clones of the object.
   bool IsShared();
 
  private:
-  class Core;
+  typedef rtc::RefCountedObject<std::unique_ptr<DesktopFrame>> Core;
 
   SharedDesktopFrame(rtc::scoped_refptr<Core> core);
 
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc
index 8a2e77c..bdada9e 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.cc
@@ -413,28 +413,27 @@
   _com_error error = g_container->output1->DuplicateOutput(
       static_cast<IUnknown*>(g_container->device),
       g_container->duplication.GetAddressOf());
-  if (error.Error() == S_OK && g_container->duplication) {
-    memset(&g_container->duplication_desc, 0, sizeof(DXGI_OUTDUPL_DESC));
-    g_container->duplication->GetDesc(&g_container->duplication_desc);
-    if (g_container->duplication_desc.ModeDesc.Format !=
-        DXGI_FORMAT_B8G8R8A8_UNORM) {
-      g_container->duplication.Reset();
-      LOG(LS_ERROR) << "IDXGIDuplicateOutput does not use RGBA (8 bit) "
-                       "format, which is required by downstream components, "
-                       "format is "
-                    << g_container->duplication_desc.ModeDesc.Format;
-      return false;
-    }
-    return true;
-  } else {
-    // Make sure we have correct signal and duplicate the output next time.
+  if (error.Error() != S_OK || !g_container->duplication) {
     g_container->duplication.Reset();
     LOG(LS_WARNING) << "Failed to duplicate output from IDXGIOutput1, error "
                     << error.ErrorMessage() << ", with code "
                     << error.Error();
+    return false;
   }
 
-  return false;
+  memset(&g_container->duplication_desc, 0, sizeof(DXGI_OUTDUPL_DESC));
+  g_container->duplication->GetDesc(&g_container->duplication_desc);
+  if (g_container->duplication_desc.ModeDesc.Format !=
+      DXGI_FORMAT_B8G8R8A8_UNORM) {
+    g_container->duplication.Reset();
+    LOG(LS_ERROR) << "IDXGIDuplicateOutput does not use RGBA (8 bit) "
+                     "format, which is required by downstream components, "
+                     "format is "
+                  << g_container->duplication_desc.ModeDesc.Format;
+    return false;
+  }
+
+  return true;
 }
 
 bool ScreenCapturerWinDirectx::ForceDuplicateOutput() {
@@ -458,8 +457,8 @@
 
   // Texture instance won't change forever.
   while (!surfaces_.current_frame()) {
-    surfaces_.ReplaceCurrentFrame(
-        new rtc::scoped_refptr<Texture>(new Texture()));
+    surfaces_.ReplaceCurrentFrame(std::unique_ptr<rtc::scoped_refptr<Texture>>(
+        new rtc::scoped_refptr<Texture>(new Texture())));
     surfaces_.MoveToNextFrame();
   }
 }
@@ -593,9 +592,9 @@
         return std::unique_ptr<DesktopFrame>();
       }
       frames_.ReplaceCurrentFrame(
-          SharedDesktopFrame::Wrap(new_frame.release()));
+          SharedDesktopFrame::Wrap(std::move(new_frame)));
     }
-    result.reset(frames_.current_frame()->Share());
+    result = frames_.current_frame()->Share();
 
     std::unique_ptr<DesktopFrame> frame(
         new DxgiDesktopFrame(*surfaces_.current_frame()));
@@ -620,9 +619,8 @@
   RTC_DCHECK(callback_);
 
   if (!g_container->duplication && !DuplicateOutput()) {
-    // Receive a capture request when application is shutting down, or between
-    // mode change.
-    callback_->OnCaptureCompleted(nullptr);
+    // Failed to initialize desktop duplication.
+    callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
     return;
   }
 
@@ -656,7 +654,7 @@
     if (ForceDuplicateOutput()) {
       EmitCurrentFrame();
     } else {
-      callback_->OnCaptureCompleted(nullptr);
+      callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     }
     return;
   }
@@ -677,14 +675,14 @@
     g_container->duplication->ReleaseFrame();
   }
   if (!result) {
-    callback_->OnCaptureCompleted(nullptr);
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
   result->set_capture_time_ms(
       (rtc::TimeNanos() - capture_start_time_nanos) /
       rtc::kNumNanosecsPerMillisec);
-  callback_->OnCaptureCompleted(result.release());
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(result));
 }
 
 bool ScreenCapturerWinDirectx::GetScreenList(ScreenList* screens) {
@@ -699,7 +697,7 @@
 void ScreenCapturerWinDirectx::EmitCurrentFrame() {
   if (!surfaces_.current_frame()->get()->bits()) {
     // At the very begining, we have not captured any frames.
-    callback_->OnCaptureCompleted(nullptr);
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
@@ -708,12 +706,12 @@
     // queue. If there is not an existing frame (at the very begining), we can
     // only return a nullptr.
     if (frames_.current_frame()) {
-      std::unique_ptr<SharedDesktopFrame> frame(
-          frames_.current_frame()->Share());
+      std::unique_ptr<SharedDesktopFrame> frame =
+          frames_.current_frame()->Share();
       frame->mutable_updated_region()->Clear();
-      callback_->OnCaptureCompleted(frame.release());
+      callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
     } else {
-      callback_->OnCaptureCompleted(nullptr);
+      callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     }
     return;
   }
@@ -722,7 +720,7 @@
   // queue.
   std::unique_ptr<DesktopFrame> frame(
       new DxgiDesktopFrame(*surfaces_.current_frame()));
-  callback_->OnCaptureCompleted(frame.release());
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
 }
 
 }  // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h
index 3d33ea6..d477991 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_directx.h
@@ -82,9 +82,7 @@
                                              const char* stage);
 
   // Processes one frame received from AcquireNextFrame function, returns a
-  // nullptr if anything wrong, and Capture function will call
-  // callback_->OnCaptureCompleted(nullptr), otherwise
-  // callback_->OnCaptureCompleted(frame) will be called.
+  // nullptr if anything wrong.
   std::unique_ptr<DesktopFrame> ProcessFrame(
       const DXGI_OUTDUPL_FRAME_INFO& frame_info,
       IDXGIResource* resource);
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 9df2e5f..31fbf4b 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.cc
@@ -39,14 +39,8 @@
 
 }  // namespace
 
-ScreenCapturerWinGdi::ScreenCapturerWinGdi(const DesktopCaptureOptions& options)
-    : callback_(NULL),
-      current_screen_id_(kFullDesktopScreenId),
-      desktop_dc_(NULL),
-      memory_dc_(NULL),
-      dwmapi_library_(NULL),
-      composition_func_(NULL),
-      set_thread_execution_state_failed_(false) {
+ScreenCapturerWinGdi::ScreenCapturerWinGdi(
+    const DesktopCaptureOptions& options) {
   if (options.disable_effects()) {
     // Load dwmapi.dll dynamically since it is not available on XP.
     if (!dwmapi_library_)
@@ -97,7 +91,7 @@
   PrepareCaptureResources();
 
   if (!CaptureImage()) {
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
@@ -130,7 +124,7 @@
   helper_.set_size_most_recent(current_frame->size());
 
   // Emit the current frame.
-  DesktopFrame* frame = queue_.current_frame()->Share();
+  std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share();
   frame->set_dpi(DesktopVector(
       GetDeviceCaps(desktop_dc_, LOGPIXELSX),
       GetDeviceCaps(desktop_dc_, LOGPIXELSY)));
@@ -139,7 +133,7 @@
   frame->set_capture_time_ms(
       (rtc::TimeNanos() - capture_start_time_nanos) /
       rtc::kNumNanosecsPerMillisec);
-  callback_->OnCaptureCompleted(frame);
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
 }
 
 bool ScreenCapturerWinGdi::GetScreenList(ScreenList* screens) {
@@ -170,16 +164,16 @@
   // Switch to the desktop receiving user input if different from the current
   // one.
   std::unique_ptr<Desktop> input_desktop(Desktop::GetInputDesktop());
-  if (input_desktop.get() != NULL && !desktop_.IsSame(*input_desktop)) {
+  if (input_desktop && !desktop_.IsSame(*input_desktop)) {
     // Release GDI resources otherwise SetThreadDesktop will fail.
     if (desktop_dc_) {
       ReleaseDC(NULL, desktop_dc_);
-      desktop_dc_ = NULL;
+      desktop_dc_ = nullptr;
     }
 
     if (memory_dc_) {
       DeleteDC(memory_dc_);
-      memory_dc_ = NULL;
+      memory_dc_ = nullptr;
     }
 
     // If SetThreadDesktop() fails, the thread is still assigned a desktop.
@@ -188,7 +182,7 @@
 
     // Re-assert our vote to disable Aero.
     // See crbug.com/124018 and crbug.com/129906.
-    if (composition_func_ != NULL) {
+    if (composition_func_) {
       (*composition_func_)(DWM_EC_DISABLECOMPOSITION);
     }
   }
@@ -203,20 +197,20 @@
   if (!screen_rect.equals(desktop_dc_rect_)) {
     if (desktop_dc_) {
       ReleaseDC(NULL, desktop_dc_);
-      desktop_dc_ = NULL;
+      desktop_dc_ = nullptr;
     }
     if (memory_dc_) {
       DeleteDC(memory_dc_);
-      memory_dc_ = NULL;
+      memory_dc_ = nullptr;
     }
     desktop_dc_rect_ = DesktopRect();
   }
 
-  if (desktop_dc_ == NULL) {
-    assert(memory_dc_ == NULL);
+  if (!desktop_dc_) {
+    assert(!memory_dc_);
 
     // Create GDI device contexts to capture from the desktop into memory.
-    desktop_dc_ = GetDC(NULL);
+    desktop_dc_ = GetDC(nullptr);
     if (!desktop_dc_)
       abort();
     memory_dc_ = CreateCompatibleDC(desktop_dc_);
@@ -244,14 +238,14 @@
   // may still be reading from them.
   if (!queue_.current_frame() ||
       !queue_.current_frame()->size().equals(screen_rect.size())) {
-    assert(desktop_dc_ != NULL);
-    assert(memory_dc_ != NULL);
+    assert(desktop_dc_);
+    assert(memory_dc_);
 
-    std::unique_ptr<DesktopFrame> buffer(DesktopFrameWin::Create(
-        size, shared_memory_factory_.get(), desktop_dc_));
+    std::unique_ptr<DesktopFrame> buffer = DesktopFrameWin::Create(
+        size, shared_memory_factory_.get(), desktop_dc_);
     if (!buffer)
       return false;
-    queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(buffer.release()));
+    queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(buffer)));
   }
 
   // Select the target bitmap into the memory dc and copy the rect from desktop
@@ -259,11 +253,9 @@
   DesktopFrameWin* current = static_cast<DesktopFrameWin*>(
       queue_.current_frame()->GetUnderlyingFrame());
   HGDIOBJ previous_object = SelectObject(memory_dc_, current->bitmap());
-  if (previous_object != NULL) {
-    BitBlt(memory_dc_,
-           0, 0, screen_rect.width(), screen_rect.height(),
-           desktop_dc_,
-           screen_rect.left(), screen_rect.top(),
+  if (previous_object) {
+    BitBlt(memory_dc_, 0, 0, screen_rect.width(), screen_rect.height(),
+           desktop_dc_, screen_rect.left(), screen_rect.top(),
            SRCCOPY | CAPTUREBLT);
 
     // Select back the previously selected object to that the device contect
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 5a50580..3c855e4 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_gdi.h
@@ -56,9 +56,9 @@
   // Capture the current cursor shape.
   void CaptureCursor();
 
-  Callback* callback_;
+  Callback* callback_ = nullptr;
   std::unique_ptr<SharedMemoryFactory> shared_memory_factory_;
-  ScreenId current_screen_id_;
+  ScreenId current_screen_id_ = kFullDesktopScreenId;
   std::wstring current_device_key_;
 
   // A thread-safe list of invalid rectangles, and the size of the most
@@ -68,8 +68,8 @@
   ScopedThreadDesktop desktop_;
 
   // GDI resources used for screen capture.
-  HDC desktop_dc_;
-  HDC memory_dc_;
+  HDC desktop_dc_ = NULL;
+  HDC memory_dc_ = NULL;
 
   // Queue of the frames buffers.
   ScreenCaptureFrameQueue<SharedDesktopFrame> queue_;
@@ -81,11 +81,11 @@
   // Class to calculate the difference between two screen bitmaps.
   std::unique_ptr<Differ> differ_;
 
-  HMODULE dwmapi_library_;
-  DwmEnableCompositionFunc composition_func_;
+  HMODULE dwmapi_library_ = NULL;
+  DwmEnableCompositionFunc composition_func_ = nullptr;
 
   // Used to suppress duplicate logging of SetThreadExecutionState errors.
-  bool set_thread_execution_state_failed_;
+  bool set_thread_execution_state_failed_ = false;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerWinGdi);
 };
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 6b4308b..7fdc8eb 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.cc
@@ -39,23 +39,7 @@
 
 ScreenCapturerWinMagnifier::ScreenCapturerWinMagnifier(
     std::unique_ptr<ScreenCapturer> fallback_capturer)
-    : fallback_capturer_(std::move(fallback_capturer)),
-      fallback_capturer_started_(false),
-      callback_(NULL),
-      current_screen_id_(kFullDesktopScreenId),
-      excluded_window_(NULL),
-      set_thread_execution_state_failed_(false),
-      desktop_dc_(NULL),
-      mag_lib_handle_(NULL),
-      mag_initialize_func_(NULL),
-      mag_uninitialize_func_(NULL),
-      set_window_source_func_(NULL),
-      set_window_filter_list_func_(NULL),
-      set_image_scaling_callback_func_(NULL),
-      host_window_(NULL),
-      magnifier_window_(NULL),
-      magnifier_initialized_(false),
-      magnifier_capture_succeeded_(true) {}
+    : fallback_capturer_(std::move(fallback_capturer)) {}
 
 ScreenCapturerWinMagnifier::~ScreenCapturerWinMagnifier() {
   // DestroyWindow must be called before MagUninitialize. magnifier_window_ is
@@ -162,15 +146,14 @@
   helper_.set_size_most_recent(current_frame->size());
 
   // Emit the current frame.
-  DesktopFrame* frame = queue_.current_frame()->Share();
+  std::unique_ptr<DesktopFrame> frame = queue_.current_frame()->Share();
   frame->set_dpi(DesktopVector(GetDeviceCaps(desktop_dc_, LOGPIXELSX),
                                GetDeviceCaps(desktop_dc_, LOGPIXELSY)));
   frame->mutable_updated_region()->Clear();
   helper_.TakeInvalidRegion(frame->mutable_updated_region());
-  frame->set_capture_time_ms(
-      (rtc::TimeNanos() - capture_start_time_nanos) /
-      rtc::kNumNanosecsPerMillisec);
-  callback_->OnCaptureCompleted(frame);
+  frame->set_capture_time_ms((rtc::TimeNanos() - capture_start_time_nanos) /
+                             rtc::kNumNanosecsPerMillisec);
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
 }
 
 bool ScreenCapturerWinMagnifier::GetScreenList(ScreenList* screens) {
@@ -204,11 +187,8 @@
 
   // Set the magnifier control to cover the captured rect. The content of the
   // magnifier control will be the captured image.
-  BOOL result = SetWindowPos(magnifier_window_,
-                             NULL,
-                             rect.left(), rect.top(),
-                             rect.width(), rect.height(),
-                             0);
+  BOOL result = SetWindowPos(magnifier_window_, NULL, rect.left(), rect.top(),
+                             rect.width(), rect.height(), 0);
   if (!result) {
     LOG_F(LS_WARNING) << "Failed to call SetWindowPos: " << GetLastError()
                       << ". Rect = {" << rect.left() << ", " << rect.top()
@@ -257,7 +237,7 @@
 bool ScreenCapturerWinMagnifier::InitializeMagnifier() {
   assert(!magnifier_initialized_);
 
-  desktop_dc_ = GetDC(NULL);
+  desktop_dc_ = GetDC(nullptr);
 
   mag_lib_handle_ = LoadLibrary(L"Magnification.dll");
   if (!mag_lib_handle_)
@@ -291,7 +271,7 @@
     return false;
   }
 
-  HMODULE hInstance = NULL;
+  HMODULE hInstance = nullptr;
   result = GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
                                   GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
                               reinterpret_cast<char*>(&DefWindowProc),
@@ -309,22 +289,16 @@
   wcex.cbSize = sizeof(WNDCLASSEX);
   wcex.lpfnWndProc = &DefWindowProc;
   wcex.hInstance = hInstance;
-  wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
+  wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
   wcex.lpszClassName = kMagnifierHostClass;
 
   // Ignore the error which may happen when the class is already registered.
   RegisterClassEx(&wcex);
 
   // Create the host window.
-  host_window_ = CreateWindowEx(WS_EX_LAYERED,
-                                kMagnifierHostClass,
-                                kHostWindowName,
-                                0,
-                                0, 0, 0, 0,
-                                NULL,
-                                NULL,
-                                hInstance,
-                                NULL);
+  host_window_ =
+      CreateWindowEx(WS_EX_LAYERED, kMagnifierHostClass, kHostWindowName, 0, 0,
+                     0, 0, 0, nullptr, nullptr, hInstance, nullptr);
   if (!host_window_) {
     mag_uninitialize_func_();
     LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: "
@@ -333,14 +307,9 @@
   }
 
   // Create the magnifier control.
-  magnifier_window_ = CreateWindow(kMagnifierWindowClass,
-                                   kMagnifierWindowName,
-                                   WS_CHILD | WS_VISIBLE,
-                                   0, 0, 0, 0,
-                                   host_window_,
-                                   NULL,
-                                   hInstance,
-                                   NULL);
+  magnifier_window_ = CreateWindow(kMagnifierWindowClass, kMagnifierWindowName,
+                                   WS_CHILD | WS_VISIBLE, 0, 0, 0, 0,
+                                   host_window_, nullptr, hInstance, nullptr);
   if (!magnifier_window_) {
     mag_uninitialize_func_();
     LOG_F(LS_WARNING) << "Failed to initialize ScreenCapturerWinMagnifier: "
@@ -433,7 +402,7 @@
             ? SharedMemoryDesktopFrame::Create(size,
                                                shared_memory_factory_.get())
             : std::unique_ptr<DesktopFrame>(new BasicDesktopFrame(size));
-    queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(frame.release()));
+    queue_.ReplaceCurrentFrame(SharedDesktopFrame::Wrap(std::move(frame)));
   }
 }
 
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 623c8a3..1a90791 100644
--- a/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h
+++ b/webrtc/modules/desktop_capture/win/screen_capturer_win_magnifier.h
@@ -106,12 +106,12 @@
   static Atomic32 tls_index_;
 
   std::unique_ptr<ScreenCapturer> fallback_capturer_;
-  bool fallback_capturer_started_;
-  Callback* callback_;
+  bool fallback_capturer_started_ = false;
+  Callback* callback_ = nullptr;
   std::unique_ptr<SharedMemoryFactory> shared_memory_factory_;
-  ScreenId current_screen_id_;
+  ScreenId current_screen_id_ = kFullDesktopScreenId;
   std::wstring current_device_key_;
-  HWND excluded_window_;
+  HWND excluded_window_ = NULL;
 
   // A thread-safe list of invalid rectangles, and the size of the most
   // recently captured screen.
@@ -124,31 +124,31 @@
   std::unique_ptr<Differ> differ_;
 
   // Used to suppress duplicate logging of SetThreadExecutionState errors.
-  bool set_thread_execution_state_failed_;
+  bool set_thread_execution_state_failed_ = false;
 
   ScopedThreadDesktop desktop_;
 
   // Used for getting the screen dpi.
-  HDC desktop_dc_;
+  HDC desktop_dc_ = NULL;
 
-  HMODULE mag_lib_handle_;
-  MagInitializeFunc mag_initialize_func_;
-  MagUninitializeFunc mag_uninitialize_func_;
-  MagSetWindowSourceFunc set_window_source_func_;
-  MagSetWindowFilterListFunc set_window_filter_list_func_;
-  MagSetImageScalingCallbackFunc set_image_scaling_callback_func_;
+  HMODULE mag_lib_handle_ = NULL;
+  MagInitializeFunc mag_initialize_func_ = nullptr;
+  MagUninitializeFunc mag_uninitialize_func_ = nullptr;
+  MagSetWindowSourceFunc set_window_source_func_ = nullptr;
+  MagSetWindowFilterListFunc set_window_filter_list_func_ = nullptr;
+  MagSetImageScalingCallbackFunc set_image_scaling_callback_func_ = nullptr;
 
   // The hidden window hosting the magnifier control.
-  HWND host_window_;
+  HWND host_window_ = NULL;
   // The magnifier control that captures the screen.
-  HWND magnifier_window_;
+  HWND magnifier_window_ = NULL;
 
   // True if the magnifier control has been successfully initialized.
-  bool magnifier_initialized_;
+  bool magnifier_initialized_ = false;
 
   // True if the last OnMagImageScalingCallback was called and handled
   // successfully. Reset at the beginning of each CaptureImage call.
-  bool magnifier_capture_succeeded_;
+  bool magnifier_capture_succeeded_ = true;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(ScreenCapturerWinMagnifier);
 };
diff --git a/webrtc/modules/desktop_capture/window_capturer_mac.mm b/webrtc/modules/desktop_capture/window_capturer_mac.mm
index ac5fdb6..cbdf14b 100644
--- a/webrtc/modules/desktop_capture/window_capturer_mac.mm
+++ b/webrtc/modules/desktop_capture/window_capturer_mac.mm
@@ -32,7 +32,7 @@
 // Returns true if the window exists.
 bool IsWindowValid(CGWindowID id) {
   CFArrayRef window_id_array =
-      CFArrayCreate(NULL, reinterpret_cast<const void **>(&id), 1, NULL);
+      CFArrayCreate(nullptr, reinterpret_cast<const void**>(&id), 1, nullptr);
   CFArrayRef window_array =
       CGWindowListCreateDescriptionFromArray(window_id_array);
   bool valid = window_array && CFArrayGetCount(window_array);
@@ -58,10 +58,10 @@
   void Capture(const DesktopRegion& region) override;
 
  private:
-  Callback* callback_;
+  Callback* callback_ = nullptr;
 
   // The window being captured.
-  CGWindowID window_id_;
+  CGWindowID window_id_ = 0;
 
   rtc::scoped_refptr<FullScreenChromeWindowDetector>
       full_screen_chrome_window_detector_;
@@ -69,15 +69,12 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerMac);
 };
 
-WindowCapturerMac::WindowCapturerMac(rtc::scoped_refptr<
-    FullScreenChromeWindowDetector> full_screen_chrome_window_detector)
-    : callback_(NULL),
-      window_id_(0),
-      full_screen_chrome_window_detector_(full_screen_chrome_window_detector) {
-}
+WindowCapturerMac::WindowCapturerMac(
+    rtc::scoped_refptr<FullScreenChromeWindowDetector>
+        full_screen_chrome_window_detector)
+    : full_screen_chrome_window_detector_(full_screen_chrome_window_detector) {}
 
-WindowCapturerMac::~WindowCapturerMac() {
-}
+WindowCapturerMac::~WindowCapturerMac() {}
 
 bool WindowCapturerMac::GetWindowList(WindowList* windows) {
   // Only get on screen, non-desktop windows.
@@ -142,11 +139,11 @@
   CGWindowID ids[1];
   ids[0] = window_id_;
   CFArrayRef window_id_array =
-      CFArrayCreate(NULL, reinterpret_cast<const void **>(&ids), 1, NULL);
+      CFArrayCreate(nullptr, reinterpret_cast<const void**>(&ids), 1, nullptr);
 
   CFArrayRef window_array =
       CGWindowListCreateDescriptionFromArray(window_id_array);
-  if (window_array == NULL || 0 == CFArrayGetCount(window_array)) {
+  if (!window_array || 0 == CFArrayGetCount(window_array)) {
     // Could not find the window. It might have been closed.
     LOG(LS_INFO) << "Window not found";
     CFRelease(window_id_array);
@@ -181,7 +178,7 @@
 
 void WindowCapturerMac::Capture(const DesktopRegion& region) {
   if (!IsWindowValid(window_id_)) {
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
     return;
   }
 
@@ -199,7 +196,7 @@
       on_screen_window, kCGWindowImageBoundsIgnoreFraming);
 
   if (!window_image) {
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
@@ -207,7 +204,7 @@
   if (bits_per_pixel != 32) {
     LOG(LS_ERROR) << "Unsupported window image depth: " << bits_per_pixel;
     CFRelease(window_image);
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
     return;
   }
 
@@ -215,8 +212,8 @@
   int height = CGImageGetHeight(window_image);
   CGDataProviderRef provider = CGImageGetDataProvider(window_image);
   CFDataRef cf_data = CGDataProviderCopyData(provider);
-  DesktopFrame* frame = new BasicDesktopFrame(
-      DesktopSize(width, height));
+  std::unique_ptr<DesktopFrame> frame(
+      new BasicDesktopFrame(DesktopSize(width, height)));
 
   int src_stride = CGImageGetBytesPerRow(window_image);
   const uint8_t* src_data = CFDataGetBytePtr(cf_data);
@@ -231,7 +228,7 @@
   frame->mutable_updated_region()->SetRect(
       DesktopRect::MakeSize(frame->size()));
 
-  callback_->OnCaptureCompleted(frame);
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
 
   if (full_screen_chrome_window_detector_)
     full_screen_chrome_window_detector_->UpdateWindowListIfNeeded(window_id_);
diff --git a/webrtc/modules/desktop_capture/window_capturer_null.cc b/webrtc/modules/desktop_capture/window_capturer_null.cc
index 5f32c3d..3fe21cf 100755
--- a/webrtc/modules/desktop_capture/window_capturer_null.cc
+++ b/webrtc/modules/desktop_capture/window_capturer_null.cc
@@ -34,17 +34,13 @@
   void Capture(const DesktopRegion& region) override;
 
  private:
-  Callback* callback_;
+  Callback* callback_ = nullptr;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerNull);
 };
 
-WindowCapturerNull::WindowCapturerNull()
-    : callback_(NULL) {
-}
-
-WindowCapturerNull::~WindowCapturerNull() {
-}
+WindowCapturerNull::WindowCapturerNull() {}
+WindowCapturerNull::~WindowCapturerNull() {}
 
 bool WindowCapturerNull::GetWindowList(WindowList* windows) {
   // Not implemented yet.
@@ -70,7 +66,7 @@
 
 void WindowCapturerNull::Capture(const DesktopRegion& region) {
   // Not implemented yet.
-  callback_->OnCaptureCompleted(NULL);
+  callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
 }
 
 }  // namespace
diff --git a/webrtc/modules/desktop_capture/window_capturer_unittest.cc b/webrtc/modules/desktop_capture/window_capturer_unittest.cc
index 32b8b8f..d2d326e 100644
--- a/webrtc/modules/desktop_capture/window_capturer_unittest.cc
+++ b/webrtc/modules/desktop_capture/window_capturer_unittest.cc
@@ -31,7 +31,10 @@
   void TearDown() override {}
 
   // DesktopCapturer::Callback interface
-  void OnCaptureCompleted(DesktopFrame* frame) override { frame_.reset(frame); }
+  void OnCaptureResult(DesktopCapturer::Result result,
+                       std::unique_ptr<DesktopFrame> frame) override {
+    frame_ = std::move(frame);
+  }
 
  protected:
   std::unique_ptr<WindowCapturer> capturer_;
diff --git a/webrtc/modules/desktop_capture/window_capturer_win.cc b/webrtc/modules/desktop_capture/window_capturer_win.cc
index 7023243..c7c312a 100644
--- a/webrtc/modules/desktop_capture/window_capturer_win.cc
+++ b/webrtc/modules/desktop_capture/window_capturer_win.cc
@@ -95,11 +95,11 @@
   void Capture(const DesktopRegion& region) override;
 
  private:
-  Callback* callback_;
+  Callback* callback_ = nullptr;
 
-  // HWND and HDC for the currently selected window or NULL if window is not
+  // HWND and HDC for the currently selected window or nullptr if window is not
   // selected.
-  HWND window_;
+  HWND window_ = nullptr;
 
   DesktopSize previous_size_;
 
@@ -112,13 +112,8 @@
   RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerWin);
 };
 
-WindowCapturerWin::WindowCapturerWin()
-    : callback_(NULL),
-      window_(NULL) {
-}
-
-WindowCapturerWin::~WindowCapturerWin() {
-}
+WindowCapturerWin::WindowCapturerWin() {}
+WindowCapturerWin::~WindowCapturerWin() {}
 
 bool WindowCapturerWin::GetWindowList(WindowList* windows) {
   WindowList result;
@@ -168,13 +163,13 @@
 void WindowCapturerWin::Capture(const DesktopRegion& region) {
   if (!window_) {
     LOG(LS_ERROR) << "Window hasn't been selected: " << GetLastError();
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
     return;
   }
 
   // Stop capturing if the window has been closed.
   if (!IsWindow(window_)) {
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
     return;
   }
 
@@ -182,12 +177,13 @@
   // behavior on mace. Window can be temporarily invisible during the
   // transition of full screen mode on/off.
   if (IsIconic(window_) || !IsWindowVisible(window_)) {
-    BasicDesktopFrame* frame = new BasicDesktopFrame(DesktopSize(1, 1));
+    std::unique_ptr<DesktopFrame> frame(
+        new BasicDesktopFrame(DesktopSize(1, 1)));
     memset(frame->data(), 0, frame->stride() * frame->size().height());
 
     previous_size_ = frame->size();
     window_size_map_[window_] = previous_size_;
-    callback_->OnCaptureCompleted(frame);
+    callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
     return;
   }
 
@@ -195,22 +191,22 @@
   DesktopRect cropped_rect;
   if (!GetCroppedWindowRect(window_, &cropped_rect, &original_rect)) {
     LOG(LS_WARNING) << "Failed to get window info: " << GetLastError();
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
   HDC window_dc = GetWindowDC(window_);
   if (!window_dc) {
     LOG(LS_WARNING) << "Failed to get window DC: " << GetLastError();
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
   std::unique_ptr<DesktopFrameWin> frame(
-      DesktopFrameWin::Create(cropped_rect.size(), NULL, window_dc));
+      DesktopFrameWin::Create(cropped_rect.size(), nullptr, window_dc));
   if (!frame.get()) {
     ReleaseDC(window_, window_dc);
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
     return;
   }
 
@@ -263,7 +259,7 @@
     frame.reset();
   }
 
-  callback_->OnCaptureCompleted(frame.release());
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
 }
 
 }  // namespace
diff --git a/webrtc/modules/desktop_capture/window_capturer_x11.cc b/webrtc/modules/desktop_capture/window_capturer_x11.cc
old mode 100755
new mode 100644
index 8ead981..d88585b
--- a/webrtc/modules/desktop_capture/window_capturer_x11.cc
+++ b/webrtc/modules/desktop_capture/window_capturer_x11.cc
@@ -36,10 +36,7 @@
 template <class PropertyType>
 class XWindowProperty {
  public:
-  XWindowProperty(Display* display, Window window, Atom property)
-      : is_valid_(false),
-        size_(0),
-        data_(NULL) {
+  XWindowProperty(Display* display, Window window, Atom property) {
     const int kBitsPerByte = 8;
     Atom actual_type;
     int actual_format;
@@ -49,7 +46,7 @@
                                     &actual_format, &size_,
                                     &bytes_after, &data_);
     if (status != Success) {
-      data_ = NULL;
+      data_ = nullptr;
       return;
     }
     if (sizeof(PropertyType) * kBitsPerByte != actual_format) {
@@ -78,9 +75,9 @@
   }
 
  private:
-  bool is_valid_;
-  unsigned long size_;  // NOLINT: type required by XGetWindowProperty
-  unsigned char* data_;
+  bool is_valid_ = false;
+  unsigned long size_ = 0;  // NOLINT: type required by XGetWindowProperty
+  unsigned char* data_ = nullptr;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(XWindowProperty);
 };
@@ -117,26 +114,23 @@
   // Returns window title for the specified X |window|.
   bool GetWindowTitle(::Window window, std::string* title);
 
-  Callback* callback_;
+  Callback* callback_ = nullptr;
 
   rtc::scoped_refptr<SharedXDisplay> x_display_;
 
   Atom wm_state_atom_;
   Atom window_type_atom_;
   Atom normal_window_type_atom_;
-  bool has_composite_extension_;
+  bool has_composite_extension_ = false;
 
-  ::Window selected_window_;
+  ::Window selected_window_ = 0;
   XServerPixelBuffer x_server_pixel_buffer_;
 
   RTC_DISALLOW_COPY_AND_ASSIGN(WindowCapturerLinux);
 };
 
 WindowCapturerLinux::WindowCapturerLinux(const DesktopCaptureOptions& options)
-    : callback_(NULL),
-      x_display_(options.x_display()),
-      has_composite_extension_(false),
-      selected_window_(0) {
+    : x_display_(options.x_display()) {
   // Create Atoms so we don't need to do it every time they are used.
   wm_state_atom_ = XInternAtom(display(), "WM_STATE", True);
   window_type_atom_ = XInternAtom(display(), "_NET_WM_WINDOW_TYPE", True);
@@ -280,7 +274,7 @@
 void WindowCapturerLinux::Capture(const DesktopRegion& region) {
   if (!x_server_pixel_buffer_.IsWindowValid()) {
     LOG(LS_INFO) << "The window is no longer valid.";
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
     return;
   }
 
@@ -291,21 +285,21 @@
     // visible on screen and not covered by any other window. This is not
     // something we want so instead, just bail out.
     LOG(LS_INFO) << "No Xcomposite extension detected.";
-    callback_->OnCaptureCompleted(NULL);
+    callback_->OnCaptureResult(Result::ERROR_PERMANENT, nullptr);
     return;
   }
 
-  DesktopFrame* frame =
-      new BasicDesktopFrame(x_server_pixel_buffer_.window_size());
+  std::unique_ptr<DesktopFrame> frame(
+      new BasicDesktopFrame(x_server_pixel_buffer_.window_size()));
 
   x_server_pixel_buffer_.Synchronize();
   x_server_pixel_buffer_.CaptureRect(DesktopRect::MakeSize(frame->size()),
-                                     frame);
+                                     frame.get());
 
   frame->mutable_updated_region()->SetRect(
       DesktopRect::MakeSize(frame->size()));
 
-  callback_->OnCaptureCompleted(frame);
+  callback_->OnCaptureResult(Result::SUCCESS, std::move(frame));
 }
 
 bool WindowCapturerLinux::HandleXEvent(const XEvent& event) {
@@ -399,12 +393,12 @@
   int status;
   bool result = false;
   XTextProperty window_name;
-  window_name.value = NULL;
+  window_name.value = nullptr;
   if (window) {
     status = XGetWMName(display(), window, &window_name);
     if (status && window_name.value && window_name.nitems) {
       int cnt;
-      char **list = NULL;
+      char** list = nullptr;
       status = Xutf8TextPropertyToTextList(display(), &window_name, &list,
                                            &cnt);
       if (status >= Success && cnt && *list) {
@@ -429,7 +423,7 @@
 // static
 WindowCapturer* WindowCapturer::Create(const DesktopCaptureOptions& options) {
   if (!options.x_display())
-    return NULL;
+    return nullptr;
   return new WindowCapturerLinux(options);
 }