Revert "Begin implementing WGC CaptureFrame"

This reverts commit e820cef5340610b9beebbcb63868743b95b97fcd.

Reason for revert: Breaks downstream client. I will investigate and
get back with a suggestion to fix.

Original change's description:
> Begin implementing WGC CaptureFrame
>
> This change introduces the design that will allow us to deliver frames
> synchronously to callers despite the Windows.Graphics.Capture APIs being
> inherently asynchronous.
>
> We achieve this by having WindowCapturerWinWgc create and maintain a
> WgcCaptureSession object for each window that it is asked to capture a
> frame for. The capture session object will be the class that actually
> uses the WGC APIs, and it will store the frames it receives in a frame
> pool and deliver them via GetMostRecentFrame.
>
> The next CL will add the necessary functionality to the
> WgcCaptureSession class.
>
> Bug: webrtc:9273
> Change-Id: I44e164f4874503d8ccc8e6a210e74f9c8458f6c4
> Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/184220
> Commit-Queue: Austin Orion <auorion@microsoft.com>
> Reviewed-by: Tommi <tommi@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#32240}

TBR=mbonadei@webrtc.org,jamiewalch@chromium.org,tommi@webrtc.org,auorion@microsoft.com

Change-Id: I114944357ce5be7d1e2da817703dc95d544aa99a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: webrtc:9273
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/186045
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32248}
This commit is contained in:
Mirko Bonadei 2020-09-30 10:47:40 +00:00 committed by Commit Bot
parent 9cf3ea0ab2
commit 61709a3233
10 changed files with 18 additions and 221 deletions

View File

@ -478,8 +478,6 @@ rtc_library("desktop_capture_generic") {
"win/screen_capturer_win_magnifier.h",
"win/selected_window_context.cc",
"win/selected_window_context.h",
"win/wgc_capture_session.cc",
"win/wgc_capture_session.h",
"win/window_capture_utils.cc",
"win/window_capture_utils.h",
"win/window_capturer_win_gdi.cc",

View File

@ -20,13 +20,6 @@
#include "modules/desktop_capture/desktop_capture_options.h"
#include "modules/desktop_capture/desktop_capturer_differ_wrapper.h"
#if defined(WEBRTC_WIN)
#include "modules/desktop_capture/win/window_capturer_win_wgc.h"
#include "rtc_base/win/windows_version.h"
const bool kUseWinWgcCapturer = false;
#endif // defined(WEBRTC_WIN)
namespace webrtc {
DesktopCapturer::~DesktopCapturer() = default;
@ -56,14 +49,6 @@ bool DesktopCapturer::IsOccluded(const DesktopVector& pos) {
std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateWindowCapturer(
const DesktopCaptureOptions& options) {
#if defined(WEBRTC_WIN)
// TODO(bugs.webrtc.org/11760): Add a WebRTC field trial (or similar
// mechanism) check here that leads to use of the WGC capturer once it is
// fully implemented.
if (kUseWinWgcCapturer &&
rtc::rtc_win::GetVersion() >= rtc::rtc_win::Version::VERSION_WIN10_RS5) {
return WindowCapturerWinWgc::CreateRawWindowCapturer(options);
}
if (options.allow_cropping_window_capturer()) {
return CroppingWindowCapturer::CreateCapturer(options);
}

View File

@ -29,7 +29,7 @@ const float kStandardDPI = 96.0f;
// DesktopFrame represents a video frame captured from the screen.
class RTC_EXPORT DesktopFrame {
public:
// DesktopFrame objects always hold BGRA data.
// DesktopFrame objects always hold RGBA data.
static const int kBytesPerPixel = 4;
virtual ~DesktopFrame();

View File

@ -1,40 +0,0 @@
/*
* Copyright (c) 2020 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 "modules/desktop_capture/win/wgc_capture_session.h"
#include <utility>
#include "rtc_base/checks.h"
using Microsoft::WRL::ComPtr;
namespace webrtc {
WgcCaptureSession::WgcCaptureSession(ComPtr<ID3D11Device> d3d11_device,
HWND window)
: d3d11_device_(std::move(d3d11_device)), window_(window) {}
WgcCaptureSession::~WgcCaptureSession() = default;
HRESULT WgcCaptureSession::StartCapture() {
RTC_DCHECK(!is_capture_started_);
RTC_DCHECK(d3d11_device_);
RTC_DCHECK(window_);
return E_NOTIMPL;
}
HRESULT WgcCaptureSession::GetMostRecentFrame(
std::unique_ptr<DesktopFrame>* output_frame) {
RTC_DCHECK(is_capture_started_);
return E_NOTIMPL;
}
} // namespace webrtc

View File

@ -1,48 +0,0 @@
/*
* Copyright (c) 2020 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 MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURE_SESSION_H_
#define MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURE_SESSION_H_
#include <Windows.Graphics.Capture.h>
#include <d3d11.h>
#include <wrl/client.h>
#include <memory>
#include "modules/desktop_capture/desktop_frame.h"
namespace webrtc {
class WgcCaptureSession final {
public:
WgcCaptureSession(Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device,
HWND window);
// Disallow copy and assign
WgcCaptureSession(const WgcCaptureSession&) = delete;
WgcCaptureSession& operator=(const WgcCaptureSession&) = delete;
~WgcCaptureSession();
HRESULT StartCapture();
HRESULT GetMostRecentFrame(std::unique_ptr<DesktopFrame>* output_frame);
bool IsCaptureStarted() const { return is_capture_started_; }
private:
// A Direct3D11 Device provided by the caller. We use this to create an
// IDirect3DDevice, and also to create textures that will hold the image data.
Microsoft::WRL::ComPtr<ID3D11Device> d3d11_device_;
HWND window_;
bool is_capture_started_ = false;
};
} // namespace webrtc
#endif // MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURE_SESSION_H_

View File

@ -10,9 +10,9 @@
#include "modules/desktop_capture/win/window_capturer_win_wgc.h"
#include <utility>
#include <memory>
#include "rtc_base/logging.h"
#include "modules/desktop_capture/desktop_capturer.h"
namespace webrtc {
@ -37,95 +37,12 @@ void WindowCapturerWinWgc::Start(Callback* callback) {
RTC_DCHECK(callback);
callback_ = callback;
// Create a Direct3D11 device to share amongst the WgcCaptureSessions. Many
// parameters are nullptr as the implemention uses defaults that work well for
// us.
HRESULT hr = D3D11CreateDevice(
/*adapter=*/nullptr, D3D_DRIVER_TYPE_HARDWARE,
/*software_rasterizer=*/nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
/*feature_levels=*/nullptr, /*feature_levels_size=*/0, D3D11_SDK_VERSION,
&d3d11_device_, /*feature_level=*/nullptr, /*device_context=*/nullptr);
if (hr == DXGI_ERROR_UNSUPPORTED) {
// If a hardware device could not be created, use WARP which is a high speed
// software device.
hr = D3D11CreateDevice(
/*adapter=*/nullptr, D3D_DRIVER_TYPE_WARP,
/*software_rasterizer=*/nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT,
/*feature_levels=*/nullptr, /*feature_levels_size=*/0,
D3D11_SDK_VERSION, &d3d11_device_, /*feature_level=*/nullptr,
/*device_context=*/nullptr);
}
if (FAILED(hr)) {
RTC_LOG(LS_ERROR) << "Failed to create D3D11Device: " << hr;
}
}
void WindowCapturerWinWgc::CaptureFrame() {
RTC_DCHECK(callback_);
if (!window_) {
RTC_LOG(LS_ERROR) << "Window hasn't been selected";
callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT,
/*frame=*/nullptr);
return;
}
if (!d3d11_device_) {
RTC_LOG(LS_ERROR) << "No D3D11D3evice, cannot capture.";
callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT,
/*frame=*/nullptr);
return;
}
WgcCaptureSession* capture_session = nullptr;
auto iter = ongoing_captures_.find(window_);
if (iter == ongoing_captures_.end()) {
auto iter_success_pair = ongoing_captures_.emplace(
std::piecewise_construct, std::forward_as_tuple(window_),
std::forward_as_tuple(d3d11_device_, window_));
if (iter_success_pair.second) {
capture_session = &iter_success_pair.first->second;
} else {
RTC_LOG(LS_ERROR) << "Failed to create new WgcCaptureSession.";
callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT,
/*frame=*/nullptr);
return;
}
} else {
capture_session = &iter->second;
}
HRESULT hr;
if (!capture_session->IsCaptureStarted()) {
hr = capture_session->StartCapture();
if (FAILED(hr)) {
RTC_LOG(LS_ERROR) << "Failed to start capture: " << hr;
callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT,
/*frame=*/nullptr);
return;
}
}
std::unique_ptr<DesktopFrame> frame;
hr = capture_session->GetMostRecentFrame(&frame);
if (FAILED(hr)) {
RTC_LOG(LS_ERROR) << "GetMostRecentFrame failed: " << hr;
callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_PERMANENT,
/*frame=*/nullptr);
return;
}
if (!frame) {
RTC_LOG(LS_WARNING) << "GetMostRecentFrame returned an empty frame.";
callback_->OnCaptureResult(DesktopCapturer::Result::ERROR_TEMPORARY,
/*frame=*/nullptr);
return;
}
callback_->OnCaptureResult(DesktopCapturer::Result::SUCCESS,
std::move(frame));
callback_->OnCaptureResult(Result::ERROR_TEMPORARY, nullptr);
}
// static

View File

@ -11,22 +11,19 @@
#ifndef MODULES_DESKTOP_CAPTURE_WIN_WINDOW_CAPTURER_WIN_WGC_H_
#define MODULES_DESKTOP_CAPTURE_WIN_WINDOW_CAPTURER_WIN_WGC_H_
#include <d3d11.h>
#include <wrl/client.h>
#include <map>
#include <memory>
#include "modules/desktop_capture/desktop_capture_options.h"
#include "modules/desktop_capture/desktop_capturer.h"
#include "modules/desktop_capture/win/wgc_capture_session.h"
#include "modules/desktop_capture/win/window_capture_utils.h"
namespace webrtc {
class WindowCapturerWinWgc final : public DesktopCapturer {
class WindowCapturerWinWgc : public DesktopCapturer {
public:
WindowCapturerWinWgc();
// Disallow copy and assign
WindowCapturerWinWgc(const WindowCapturerWinWgc&) = delete;
WindowCapturerWinWgc& operator=(const WindowCapturerWinWgc&) = delete;
@ -42,26 +39,12 @@ class WindowCapturerWinWgc final : public DesktopCapturer {
bool SelectSource(SourceId id) override;
private:
// The callback that we deliver frames to, synchronously, before CaptureFrame
// returns.
Callback* callback_ = nullptr;
// HWND for the currently selected window or nullptr if a window is not
// selected. We may be capturing many other windows, but this is the window
// that we will return a frame for when CaptureFrame is called.
// HWND for the currently selected window or nullptr if window is not
// selected.
HWND window_ = nullptr;
// This helps us enumerate the list of windows that we can capture.
WindowCaptureHelperWin window_capture_helper_;
// A Direct3D11 device that is shared amongst the WgcCaptureSessions, who
// require one to perform the capture.
Microsoft::WRL::ComPtr<::ID3D11Device> d3d11_device_;
// A map of all the windows we are capturing and the associated
// WgcCaptureSession. This is where we will get the frames for the window
// from, when requested.
std::map<HWND, WgcCaptureSession> ongoing_captures_;
};
} // namespace webrtc

View File

@ -11,13 +11,21 @@
#include "modules/desktop_capture/desktop_capture_options.h"
#include "modules/desktop_capture/desktop_capturer.h"
#include "modules/desktop_capture/win/window_capturer_win_gdi.h"
#include "modules/desktop_capture/win/window_capturer_win_wgc.h"
namespace webrtc {
// static
std::unique_ptr<DesktopCapturer> DesktopCapturer::CreateRawWindowCapturer(
const DesktopCaptureOptions& options) {
return WindowCapturerWinGdi::CreateRawWindowCapturer(options);
// TODO(bugs.webrtc.org/11760): Add a WebRTC field trial (or similar
// mechanism) and Windows version check here that leads to use of the WGC
// capturer once it is fully implemented.
if (true) {
return WindowCapturerWinGdi::CreateRawWindowCapturer(options);
} else {
return WindowCapturerWinWgc::CreateRawWindowCapturer(options);
}
}
} // namespace webrtc

View File

@ -203,12 +203,8 @@ Version MajorMinorBuildToVersion(int major, int minor, int build) {
return VERSION_WIN10_RS2;
} else if (build < 17134) {
return VERSION_WIN10_RS3;
} else if (build < 17763) {
return VERSION_WIN10_RS4;
} else if (build < 18362) {
return VERSION_WIN10_RS5;
} else {
return VERSION_WIN10_19H1;
return VERSION_WIN10_RS4;
}
} else if (major > 6) {
RTC_NOTREACHED();

View File

@ -43,8 +43,6 @@ enum Version {
VERSION_WIN10_RS2 = 10, // Redstone 2: Version 1703, Build 15063.
VERSION_WIN10_RS3 = 11, // Redstone 3: Version 1709, Build 16299.
VERSION_WIN10_RS4 = 12, // Redstone 4: Version 1803, Build 17134.
VERSION_WIN10_RS5 = 13, // Redstone 5: Version 1809, Build 17763.
VERSION_WIN10_19H1 = 14, // 19H1: Version 1903, Build 18362.
// On edit, update tools\metrics\histograms\enums.xml "WindowsVersion" and
// "GpuBlacklistFeatureTestResultsWindows2".
VERSION_WIN_LAST, // Indicates error condition.