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
This commit is contained in:
parent
a367aeab82
commit
0e71070207
@ -110,6 +110,13 @@ inline bool IsWindowsXpOrLater() {
|
||||
(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 @@ bool AdjustCurrentProcessPrivilege(const TCHAR* privilege, bool to_enable);
|
||||
|
||||
} // namespace rtc
|
||||
|
||||
#endif // WEBRTC_WIN
|
||||
#endif // WEBRTC_WIN
|
||||
#endif // WEBRTC_BASE_WIN32_H_
|
||||
|
@ -14,6 +14,11 @@ use_desktop_capture_differ_sse2 =
|
||||
|
||||
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",
|
||||
|
45
webrtc/modules/desktop_capture/cropped_desktop_frame.cc
Normal file
45
webrtc/modules/desktop_capture/cropped_desktop_frame.cc
Normal file
@ -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
|
25
webrtc/modules/desktop_capture/cropped_desktop_frame.h
Normal file
25
webrtc/modules/desktop_capture/cropped_desktop_frame.h
Normal file
@ -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_
|
||||
|
111
webrtc/modules/desktop_capture/cropping_window_capturer.cc
Normal file
111
webrtc/modules/desktop_capture/cropping_window_capturer.cc
Normal file
@ -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
|
74
webrtc/modules/desktop_capture/cropping_window_capturer.h
Normal file
74
webrtc/modules/desktop_capture/cropping_window_capturer.h
Normal file
@ -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_
|
||||
|
216
webrtc/modules/desktop_capture/cropping_window_capturer_win.cc
Normal file
216
webrtc/modules/desktop_capture/cropping_window_capturer_win.cc
Normal file
@ -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
|
@ -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",
|
||||
|
@ -32,8 +32,7 @@ void DesktopFrame::CopyPixelsFrom(uint8_t* src_buffer, int src_stride,
|
||||
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 @@ void DesktopFrame::CopyPixelsFrom(const DesktopFrame& src_frame,
|
||||
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()],
|
||||
|
@ -67,6 +67,9 @@ class DesktopFrame {
|
||||
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,
|
||||
|
@ -52,11 +52,7 @@ class WindowCapturer : public DesktopCapturer {
|
||||
|
||||
// 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user