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:
parent
9cf3ea0ab2
commit
61709a3233
@ -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",
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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
|
||||
@ -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_
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user