Use ScreenCapturer to capture the whole and clip to the window rect when the shared window is on the top.
BUG=crbug/403703, crbug/316603
R=wez@chromium.org
Review URL: https://webrtc-codereview.appspot.com/22759004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@7684 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/base/win32.h b/webrtc/base/win32.h
index bf5da25..07e1e1e 100644
--- a/webrtc/base/win32.h
+++ b/webrtc/base/win32.h
@@ -110,6 +110,13 @@
(major == kWindows2000 && minor >= 1)));
}
+inline bool IsWindows8OrLater() {
+ int major, minor;
+ return (GetOsVersion(&major, &minor, NULL) &&
+ (major > kWindowsVista ||
+ (major == kWindowsVista && minor >= 2)));
+}
+
// Determine the current integrity level of the process.
bool GetCurrentProcessIntegrityLevel(int* level);
@@ -125,5 +132,5 @@
} // namespace rtc
-#endif // WEBRTC_WIN
+#endif // WEBRTC_WIN
#endif // WEBRTC_BASE_WIN32_H_
diff --git a/webrtc/modules/desktop_capture/BUILD.gn b/webrtc/modules/desktop_capture/BUILD.gn
index 9067177..6c8d9e2 100644
--- a/webrtc/modules/desktop_capture/BUILD.gn
+++ b/webrtc/modules/desktop_capture/BUILD.gn
@@ -14,6 +14,11 @@
source_set("desktop_capture") {
sources = [
+ "cropped_desktop_frame.cc",
+ "cropped_desktop_frame.h",
+ "cropping_window_capturer.cc",
+ "cropping_window_capturer.h",
+ "cropping_window_capturer_win.cc",
"desktop_and_cursor_composer.cc",
"desktop_and_cursor_composer.h",
"desktop_capture_types.h",
diff --git a/webrtc/modules/desktop_capture/cropped_desktop_frame.cc b/webrtc/modules/desktop_capture/cropped_desktop_frame.cc
new file mode 100644
index 0000000..0216768
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropped_desktop_frame.cc
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/desktop_capture/cropped_desktop_frame.h"
+
+namespace webrtc {
+
+// A DesktopFrame that is a sub-rect of another DesktopFrame.
+class CroppedDesktopFrame : public DesktopFrame {
+ public:
+ CroppedDesktopFrame(DesktopFrame* frame, const DesktopRect& rect);
+
+ private:
+ scoped_ptr<DesktopFrame> frame_;
+
+ DISALLOW_COPY_AND_ASSIGN(CroppedDesktopFrame);
+};
+
+DesktopFrame*
+CreateCroppedDesktopFrame(DesktopFrame* frame, const DesktopRect& rect) {
+ if (!DesktopRect::MakeSize(frame->size()).ContainsRect(rect)) {
+ delete frame;
+ return NULL;
+ }
+
+ return new CroppedDesktopFrame(frame, rect);
+}
+
+CroppedDesktopFrame::CroppedDesktopFrame(DesktopFrame* frame,
+ const DesktopRect& rect)
+ : DesktopFrame(rect.size(),
+ frame->stride(),
+ frame->GetFrameDataAtPos(rect.top_left()),
+ frame->shared_memory()),
+ frame_(frame) {
+}
+
+} // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/cropped_desktop_frame.h b/webrtc/modules/desktop_capture/cropped_desktop_frame.h
new file mode 100644
index 0000000..29449e2
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropped_desktop_frame.h
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_
+#define WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPED_DESKTOP_FRAME_H_
+
+#include "webrtc/modules/desktop_capture/desktop_frame.h"
+
+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);
+} // 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
new file mode 100644
index 0000000..f78b26b
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer.cc
@@ -0,0 +1,111 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/desktop_capture/cropping_window_capturer.h"
+
+#include "webrtc/modules/desktop_capture/cropped_desktop_frame.h"
+#include "webrtc/system_wrappers/interface/logging.h"
+
+namespace webrtc {
+
+CroppingWindowCapturer::CroppingWindowCapturer(
+ const DesktopCaptureOptions& options)
+ : options_(options),
+ callback_(NULL),
+ window_capturer_(WindowCapturer::Create(options)),
+ selected_window_(kNullWindowId),
+ excluded_window_(kNullWindowId) {
+}
+
+CroppingWindowCapturer::~CroppingWindowCapturer() {}
+
+void CroppingWindowCapturer::Start(DesktopCapturer::Callback* callback) {
+ callback_ = callback;
+ window_capturer_->Start(callback);
+}
+
+void CroppingWindowCapturer::Capture(const DesktopRegion& region) {
+ if (ShouldUseScreenCapturer()) {
+ if (!screen_capturer_.get()) {
+ screen_capturer_.reset(ScreenCapturer::Create(options_));
+ if (excluded_window_) {
+ screen_capturer_->SetExcludedWindow(excluded_window_);
+ }
+ screen_capturer_->Start(this);
+ }
+ screen_capturer_->Capture(region);
+ } else {
+ window_capturer_->Capture(region);
+ }
+}
+
+void CroppingWindowCapturer::SetExcludedWindow(WindowId window) {
+ excluded_window_ = window;
+ if (screen_capturer_.get()) {
+ screen_capturer_->SetExcludedWindow(window);
+ }
+}
+
+bool CroppingWindowCapturer::GetWindowList(WindowList* windows) {
+ return window_capturer_->GetWindowList(windows);
+}
+
+bool CroppingWindowCapturer::SelectWindow(WindowId id) {
+ if (window_capturer_->SelectWindow(id)) {
+ selected_window_ = id;
+ return true;
+ }
+ return false;
+}
+
+bool CroppingWindowCapturer::BringSelectedWindowToFront() {
+ return window_capturer_->BringSelectedWindowToFront();
+}
+
+SharedMemory* CroppingWindowCapturer::CreateSharedMemory(size_t size) {
+ return callback_->CreateSharedMemory(size);
+}
+
+void CroppingWindowCapturer::OnCaptureCompleted(DesktopFrame* frame) {
+ scoped_ptr<DesktopFrame> screen_frame(frame);
+
+ if (!ShouldUseScreenCapturer()) {
+ LOG(LS_INFO) << "Window no longer on top when ScreenCapturer finishes";
+ window_capturer_->Capture(DesktopRegion());
+ return;
+ }
+
+ if (!frame) {
+ LOG(LS_WARNING) << "ScreenCapturer failed to capture a frame";
+ callback_->OnCaptureCompleted(NULL);
+ return;
+ }
+
+ DesktopRect window_rect = GetWindowRectInVirtualScreen();
+ if (window_rect.is_empty()) {
+ LOG(LS_WARNING) << "Window rect is empty";
+ callback_->OnCaptureCompleted(NULL);
+ return;
+ }
+
+ scoped_ptr<DesktopFrame> window_frame(
+ CreateCroppedDesktopFrame(screen_frame.release(), window_rect));
+ callback_->OnCaptureCompleted(window_frame.release());
+}
+
+#if !defined(OS_WIN)
+// static
+WindowCapturer*
+CroppingWindowCapturer::Create(const DesktopCaptureOptions& options) {
+ return WindowCapturer::Create(options);
+}
+#endif
+
+} // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer.h b/webrtc/modules/desktop_capture/cropping_window_capturer.h
new file mode 100644
index 0000000..2a5154e
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer.h
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#ifndef WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_
+#define WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_
+
+#include "webrtc/modules/desktop_capture/desktop_capture_options.h"
+#include "webrtc/modules/desktop_capture/screen_capturer.h"
+#include "webrtc/modules/desktop_capture/window_capturer.h"
+#include "webrtc/system_wrappers/interface/scoped_ptr.h"
+
+namespace webrtc {
+
+// WindowCapturer implementation that uses a screen capturer to capture the
+// whole screen and crops the video frame to the window area when the captured
+// window is on top.
+class CroppingWindowCapturer : public WindowCapturer,
+ public DesktopCapturer::Callback {
+ public:
+ static WindowCapturer* Create(const DesktopCaptureOptions& options);
+ virtual ~CroppingWindowCapturer();
+
+ // DesktopCapturer implementation.
+ virtual void Start(DesktopCapturer::Callback* callback) OVERRIDE;
+ virtual void Capture(const DesktopRegion& region) OVERRIDE;
+ virtual void SetExcludedWindow(WindowId window) OVERRIDE;
+
+ // WindowCapturer implementation.
+ virtual bool GetWindowList(WindowList* windows) OVERRIDE;
+ virtual bool SelectWindow(WindowId id) OVERRIDE;
+ virtual bool BringSelectedWindowToFront() OVERRIDE;
+
+ // DesktopCapturer::Callback implementation, passed to |screen_capturer_| to
+ // intercept the capture result.
+ virtual SharedMemory* CreateSharedMemory(size_t size) OVERRIDE;
+ virtual void OnCaptureCompleted(DesktopFrame* frame) OVERRIDE;
+
+ protected:
+ explicit CroppingWindowCapturer(const DesktopCaptureOptions& options);
+
+ // The platform implementation should override these methods.
+
+ // Returns true if it is OK to capture the whole screen and crop to the
+ // selected window, i.e. the selected window is opaque, rectangular, and not
+ // occluded.
+ virtual bool ShouldUseScreenCapturer() = 0;
+
+ // Returns the window area relative to the top left of the virtual screen
+ // within the bounds of the virtual screen.
+ virtual DesktopRect GetWindowRectInVirtualScreen() = 0;
+
+ WindowId selected_window() const { return selected_window_; }
+ WindowId excluded_window() const { return excluded_window_; }
+
+ private:
+ DesktopCaptureOptions options_;
+ DesktopCapturer::Callback* callback_;
+ scoped_ptr<WindowCapturer> window_capturer_;
+ scoped_ptr<ScreenCapturer> screen_capturer_;
+ WindowId selected_window_;
+ WindowId excluded_window_;
+};
+
+} // namespace webrtc
+
+#endif // WEBRTC_MODULES_DESKTOP_CAPTURE_CROPPING_WINDOW_CAPTURER_H_
+
diff --git a/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc b/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc
new file mode 100644
index 0000000..fc1858e
--- /dev/null
+++ b/webrtc/modules/desktop_capture/cropping_window_capturer_win.cc
@@ -0,0 +1,216 @@
+/*
+ * Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
+ *
+ * Use of this source code is governed by a BSD-style license
+ * that can be found in the LICENSE file in the root of the source
+ * tree. An additional intellectual property rights grant can be found
+ * in the file PATENTS. All contributing project authors may
+ * be found in the AUTHORS file in the root of the source tree.
+ */
+
+#include "webrtc/modules/desktop_capture/cropping_window_capturer.h"
+
+#include "webrtc/base/win32.h"
+#include "webrtc/modules/desktop_capture/win/scoped_gdi_object.h"
+#include "webrtc/modules/desktop_capture/win/screen_capture_utils.h"
+#include "webrtc/modules/desktop_capture/win/window_capture_utils.h"
+#include "webrtc/system_wrappers/interface/logging.h"
+
+namespace webrtc {
+
+namespace {
+
+// Used to pass input/output data during the EnumWindow call for verifying if
+// the selected window is on top.
+struct TopWindowVerifierContext {
+ TopWindowVerifierContext(HWND selected_window, HWND excluded_window)
+ : selected_window(selected_window),
+ excluded_window(excluded_window),
+ is_top_window(false),
+ selected_window_process_id(0) {}
+
+ HWND selected_window;
+ HWND excluded_window;
+ bool is_top_window;
+ DWORD selected_window_process_id;
+ DesktopRect selected_window_rect;
+};
+
+// The function is called during EnumWindow for every window enumerated and is
+// responsible for verifying if the selected window is on top.
+BOOL CALLBACK TopWindowVerifier(HWND hwnd, LPARAM param) {
+ TopWindowVerifierContext* context =
+ reinterpret_cast<TopWindowVerifierContext*>(param);
+
+ if (hwnd == context->selected_window) {
+ context->is_top_window = true;
+ return FALSE;
+ }
+
+ // Ignore the excluded window.
+ if (hwnd == context->excluded_window) {
+ return TRUE;
+ }
+
+ // Ignore hidden or minimized window.
+ if (IsIconic(hwnd) || !IsWindowVisible(hwnd)) {
+ return TRUE;
+ }
+
+ // Ignore descendant/owned windows since we want to capture them.
+ // This check does not work for tooltips and context menus. Drop down menus
+ // and popup windows are fine.
+ if (GetAncestor(hwnd, GA_ROOTOWNER) == context->selected_window) {
+ return TRUE;
+ }
+
+ // If |hwnd| has no title and belongs to the same process, assume it's a
+ // tooltip or context menu from the selected window and ignore it.
+ const size_t kTitleLength = 32;
+ WCHAR window_title[kTitleLength];
+ GetWindowText(hwnd, window_title, kTitleLength);
+ if (wcsnlen_s(window_title, kTitleLength) == 0) {
+ DWORD enumerated_process;
+ GetWindowThreadProcessId(hwnd, &enumerated_process);
+ if (!context->selected_window_process_id) {
+ GetWindowThreadProcessId(context->selected_window,
+ &context->selected_window_process_id);
+ }
+ if (context->selected_window_process_id == enumerated_process) {
+ return TRUE;
+ }
+ }
+
+ // Check if the enumerated window intersects with the selected window.
+ RECT enumerated_rect;
+ if (!GetWindowRect(hwnd, &enumerated_rect)) {
+ // Bail out if failed to get the window area.
+ context->is_top_window = false;
+ return FALSE;
+ }
+
+ DesktopRect intersect_rect = context->selected_window_rect;
+ DesktopRect enumerated_desktop_rect =
+ DesktopRect::MakeLTRB(enumerated_rect.left,
+ enumerated_rect.top,
+ enumerated_rect.right,
+ enumerated_rect.bottom);
+ intersect_rect.IntersectWith(enumerated_desktop_rect);
+
+ // If intersection is not empty, the selected window is not on top.
+ if (!intersect_rect.is_empty()) {
+ context->is_top_window = false;
+ return FALSE;
+ }
+ // Otherwise, keep enumerating.
+ return TRUE;
+}
+
+class CroppingWindowCapturerWin : public CroppingWindowCapturer {
+ public:
+ CroppingWindowCapturerWin(
+ const DesktopCaptureOptions& options)
+ : CroppingWindowCapturer(options) {}
+
+ private:
+ virtual bool ShouldUseScreenCapturer() OVERRIDE;
+ virtual DesktopRect GetWindowRectInVirtualScreen() OVERRIDE;
+
+ // The region from GetWindowRgn in the desktop coordinate if the region is
+ // rectangular, or the rect from GetWindowRect if the region is not set.
+ DesktopRect window_region_rect_;
+};
+
+bool CroppingWindowCapturerWin::ShouldUseScreenCapturer() {
+ if (!rtc::IsWindows8OrLater())
+ return false;
+
+ // Check if the window is a translucent layered window.
+ HWND selected = reinterpret_cast<HWND>(selected_window());
+ LONG window_ex_style = GetWindowLong(selected, GWL_EXSTYLE);
+ if (window_ex_style & WS_EX_LAYERED) {
+ COLORREF color_ref_key = 0;
+ BYTE alpha = 0;
+ DWORD flags = 0;
+
+ // GetLayeredWindowAttributes fails if the window was setup with
+ // UpdateLayeredWindow. We have no way to know the opacity of the window in
+ // that case. This happens for Stiky Note (crbug/412726).
+ if (!GetLayeredWindowAttributes(selected, &color_ref_key, &alpha, &flags))
+ return false;
+
+ // UpdateLayeredWindow is the only way to set per-pixel alpha and will cause
+ // the previous GetLayeredWindowAttributes to fail. So we only need to check
+ // the window wide color key or alpha.
+ if ((flags & LWA_COLORKEY) || ((flags & LWA_ALPHA) && (alpha < 255)))
+ return false;
+ }
+
+ TopWindowVerifierContext context(
+ selected, reinterpret_cast<HWND>(excluded_window()));
+
+ RECT selected_window_rect;
+ if (!GetWindowRect(selected, &selected_window_rect)) {
+ return false;
+ }
+ context.selected_window_rect = DesktopRect::MakeLTRB(
+ selected_window_rect.left,
+ selected_window_rect.top,
+ selected_window_rect.right,
+ selected_window_rect.bottom);
+
+ // Get the window region and check if it is rectangular.
+ win::ScopedGDIObject<HRGN, win::DeleteObjectTraits<HRGN> >
+ scoped_hrgn(CreateRectRgn(0, 0, 0, 0));
+ int region_type = GetWindowRgn(selected, scoped_hrgn.Get());
+
+ // Do not use the screen capturer if the region is empty or not rectangular.
+ if (region_type == COMPLEXREGION || region_type == NULLREGION)
+ return false;
+
+ if (region_type == SIMPLEREGION) {
+ RECT region_rect;
+ GetRgnBox(scoped_hrgn.Get(), ®ion_rect);
+ DesktopRect rgn_rect =
+ DesktopRect::MakeLTRB(region_rect.left,
+ region_rect.top,
+ region_rect.right,
+ region_rect.bottom);
+ rgn_rect.Translate(context.selected_window_rect.left(),
+ context.selected_window_rect.top());
+ context.selected_window_rect.IntersectWith(rgn_rect);
+ }
+ window_region_rect_ = context.selected_window_rect;
+
+ // Check if the window is occluded by any other window, excluding the child
+ // windows, context menus, and |excluded_window_|.
+ EnumWindows(&TopWindowVerifier, reinterpret_cast<LPARAM>(&context));
+ return context.is_top_window;
+}
+
+DesktopRect CroppingWindowCapturerWin::GetWindowRectInVirtualScreen() {
+ DesktopRect original_rect;
+ DesktopRect window_rect;
+ HWND hwnd = reinterpret_cast<HWND>(selected_window());
+ if (!GetCroppedWindowRect(hwnd, &window_rect, &original_rect)) {
+ LOG(LS_WARNING) << "Failed to get window info: " << GetLastError();
+ return window_rect;
+ }
+ window_rect.IntersectWith(window_region_rect_);
+
+ // Convert |window_rect| to be relative to the top-left of the virtual screen.
+ DesktopRect screen_rect(GetScreenRect(kFullDesktopScreenId, L""));
+ window_rect.IntersectWith(screen_rect);
+ window_rect.Translate(-screen_rect.left(), -screen_rect.top());
+ return window_rect;
+}
+
+} // namespace
+
+// static
+WindowCapturer*
+CroppingWindowCapturer::Create(const DesktopCaptureOptions& options) {
+ return new CroppingWindowCapturerWin(options);
+}
+
+} // namespace webrtc
diff --git a/webrtc/modules/desktop_capture/desktop_capture.gypi b/webrtc/modules/desktop_capture/desktop_capture.gypi
index 1b702f2..49f9347 100644
--- a/webrtc/modules/desktop_capture/desktop_capture.gypi
+++ b/webrtc/modules/desktop_capture/desktop_capture.gypi
@@ -16,6 +16,11 @@
'<(webrtc_root)/base/base.gyp:rtc_base',
],
'sources': [
+ 'cropped_desktop_frame.cc',
+ 'cropped_desktop_frame.h',
+ 'cropping_window_capturer.cc',
+ 'cropping_window_capturer.h',
+ 'cropping_window_capturer_win.cc',
"desktop_and_cursor_composer.cc",
"desktop_and_cursor_composer.h",
"desktop_capture_types.h",
diff --git a/webrtc/modules/desktop_capture/desktop_frame.cc b/webrtc/modules/desktop_capture/desktop_frame.cc
index f26dc93..cb32ef7 100644
--- a/webrtc/modules/desktop_capture/desktop_frame.cc
+++ b/webrtc/modules/desktop_capture/desktop_frame.cc
@@ -32,8 +32,7 @@
const DesktopRect& dest_rect) {
assert(DesktopRect::MakeSize(size()).ContainsRect(dest_rect));
- uint8_t* dest = data() + stride() * dest_rect.top() +
- DesktopFrame::kBytesPerPixel * dest_rect.left();
+ uint8_t* dest = GetFrameDataAtPos(dest_rect.top_left());
for (int y = 0; y < dest_rect.height(); ++y) {
memcpy(dest, src_buffer, DesktopFrame::kBytesPerPixel * dest_rect.width());
src_buffer += src_stride;
@@ -47,11 +46,14 @@
assert(DesktopRect::MakeSize(src_frame.size()).ContainsRect(
DesktopRect::MakeOriginSize(src_pos, dest_rect.size())));
- CopyPixelsFrom(src_frame.data() + src_frame.stride() * src_pos.y() +
- DesktopFrame::kBytesPerPixel * src_pos.x(),
+ CopyPixelsFrom(src_frame.GetFrameDataAtPos(src_pos),
src_frame.stride(), dest_rect);
}
+uint8_t* DesktopFrame::GetFrameDataAtPos(const DesktopVector& pos) const {
+ return data() + stride() * pos.y() + DesktopFrame::kBytesPerPixel * pos.x();
+}
+
BasicDesktopFrame::BasicDesktopFrame(DesktopSize size)
: DesktopFrame(size, kBytesPerPixel * size.width(),
new uint8_t[kBytesPerPixel * size.width() * size.height()],
diff --git a/webrtc/modules/desktop_capture/desktop_frame.h b/webrtc/modules/desktop_capture/desktop_frame.h
index 781d108..7bcc346 100644
--- a/webrtc/modules/desktop_capture/desktop_frame.h
+++ b/webrtc/modules/desktop_capture/desktop_frame.h
@@ -67,6 +67,9 @@
const DesktopVector& src_pos,
const DesktopRect& dest_rect);
+ // A helper to return the data pointer of a frame at the specified position.
+ uint8_t* GetFrameDataAtPos(const DesktopVector& pos) const;
+
protected:
DesktopFrame(DesktopSize size,
int stride,
diff --git a/webrtc/modules/desktop_capture/window_capturer.h b/webrtc/modules/desktop_capture/window_capturer.h
index ad75c88..9ba441a 100644
--- a/webrtc/modules/desktop_capture/window_capturer.h
+++ b/webrtc/modules/desktop_capture/window_capturer.h
@@ -52,11 +52,7 @@
// Bring the selected window to the front. Returns false in case of a
// failure or no window selected.
- // TODO(jiayl): remove the default impl when FakeWindowCapturer is updated in
- // Chromium.
- virtual bool BringSelectedWindowToFront() {
- return true;
- }
+ virtual bool BringSelectedWindowToFront() = 0;
};
} // namespace webrtc