Files
platform-external-webrtc/modules/desktop_capture/win/wgc_capture_source.h
Austin Orion c5b8c8f36b Fix failing WGC tests on Win10
Several tests starting failing when run on trybots on Win10. This CL
fixes several issues that were uncovered.

Issue 1:
Capture failed to start because `get_Size` returned {0, 0}. This is a
known issue in the WGC API that occurs when there are multiple user
sessions on the same machine.
Solution:
Add a `GetSize` method to the `WgcCaptureSource` interface so we can
fallback to other methods if `get_Size` fails.

Issue 2:
The screen capture tests assume there will be displays attached and
fail if there aren't.
Solution:
Always run `IsWgcSupported` for the appropriate capture type.

Issue 3:
ASAN container-overflow in `GetTestWindowIdFromSourceList`
Solution:
Check the validity of the iterator before dereferencing.

Issue 4:
Occasionally, the call to `GetMessage` in the `CloseWindowMidCapture`
test would hang because there were no messages in the queue.
Solution:
Use `PeekMessage` instead which will return if there are no messages.

Bug: webrtc:14002
Change-Id: I69b2f765db87d34a41d6a1796cd5a81f4029be33
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/260202
Reviewed-by: Alexander Cooper <alcooper@chromium.org>
Commit-Queue: Austin Orion <auorion@microsoft.com>
Cr-Commit-Position: refs/heads/main@{#36802}
2022-05-06 23:46:42 +00:00

142 lines
4.5 KiB
C++

/*
* 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_SOURCE_H_
#define MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURE_SOURCE_H_
#include <windows.graphics.capture.h>
#include <windows.graphics.h>
#include <wrl/client.h>
#include <memory>
#include "absl/types/optional.h"
#include "modules/desktop_capture/desktop_capturer.h"
#include "modules/desktop_capture/desktop_geometry.h"
namespace webrtc {
// Abstract class to represent the source that WGC-based capturers capture
// from. Could represent an application window or a screen. Consumers should use
// the appropriate Wgc*SourceFactory class to create WgcCaptureSource objects
// of the appropriate type.
class WgcCaptureSource {
public:
explicit WgcCaptureSource(DesktopCapturer::SourceId source_id);
virtual ~WgcCaptureSource();
virtual DesktopVector GetTopLeft() = 0;
virtual bool IsCapturable();
virtual bool FocusOnSource();
virtual ABI::Windows::Graphics::SizeInt32 GetSize();
HRESULT GetCaptureItem(
Microsoft::WRL::ComPtr<
ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>* result);
DesktopCapturer::SourceId GetSourceId() { return source_id_; }
protected:
virtual HRESULT CreateCaptureItem(
Microsoft::WRL::ComPtr<
ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>* result) = 0;
private:
Microsoft::WRL::ComPtr<ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>
item_;
const DesktopCapturer::SourceId source_id_;
};
class WgcCaptureSourceFactory {
public:
virtual ~WgcCaptureSourceFactory();
virtual std::unique_ptr<WgcCaptureSource> CreateCaptureSource(
DesktopCapturer::SourceId) = 0;
};
class WgcWindowSourceFactory final : public WgcCaptureSourceFactory {
public:
WgcWindowSourceFactory();
// Disallow copy and assign.
WgcWindowSourceFactory(const WgcWindowSourceFactory&) = delete;
WgcWindowSourceFactory& operator=(const WgcWindowSourceFactory&) = delete;
~WgcWindowSourceFactory() override;
std::unique_ptr<WgcCaptureSource> CreateCaptureSource(
DesktopCapturer::SourceId) override;
};
class WgcScreenSourceFactory final : public WgcCaptureSourceFactory {
public:
WgcScreenSourceFactory();
WgcScreenSourceFactory(const WgcScreenSourceFactory&) = delete;
WgcScreenSourceFactory& operator=(const WgcScreenSourceFactory&) = delete;
~WgcScreenSourceFactory() override;
std::unique_ptr<WgcCaptureSource> CreateCaptureSource(
DesktopCapturer::SourceId) override;
};
// Class for capturing application windows.
class WgcWindowSource final : public WgcCaptureSource {
public:
explicit WgcWindowSource(DesktopCapturer::SourceId source_id);
WgcWindowSource(const WgcWindowSource&) = delete;
WgcWindowSource& operator=(const WgcWindowSource&) = delete;
~WgcWindowSource() override;
DesktopVector GetTopLeft() override;
ABI::Windows::Graphics::SizeInt32 GetSize() override;
bool IsCapturable() override;
bool FocusOnSource() override;
private:
HRESULT CreateCaptureItem(
Microsoft::WRL::ComPtr<
ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>* result)
override;
};
// Class for capturing screens/monitors/displays.
class WgcScreenSource final : public WgcCaptureSource {
public:
explicit WgcScreenSource(DesktopCapturer::SourceId source_id);
WgcScreenSource(const WgcScreenSource&) = delete;
WgcScreenSource& operator=(const WgcScreenSource&) = delete;
~WgcScreenSource() override;
DesktopVector GetTopLeft() override;
ABI::Windows::Graphics::SizeInt32 GetSize() override;
bool IsCapturable() override;
private:
HRESULT CreateCaptureItem(
Microsoft::WRL::ComPtr<
ABI::Windows::Graphics::Capture::IGraphicsCaptureItem>* result)
override;
// To maintain compatibility with other capturers, this class accepts a
// device index as it's SourceId. However, WGC requires we use an HMONITOR to
// describe which screen to capture. So, we internally convert the supplied
// device index into an HMONITOR when `IsCapturable()` is called.
absl::optional<HMONITOR> hmonitor_;
};
} // namespace webrtc
#endif // MODULES_DESKTOP_CAPTURE_WIN_WGC_CAPTURE_SOURCE_H_