提交 db35a022 编写于 作者: J jpark37

libobs-winrt,win-capture: Support desktop capture

Add display capture support via winrt_capture_init_monitor. Almost all
of the existing window capture code is reused.

Rename winrt_capture_init to winrt_capture_init_window for symmetry.
上级 b460f025
...@@ -110,6 +110,7 @@ static bool get_client_box(HWND window, uint32_t width, uint32_t height, ...@@ -110,6 +110,7 @@ static bool get_client_box(HWND window, uint32_t width, uint32_t height,
struct winrt_capture { struct winrt_capture {
HWND window; HWND window;
bool client_area; bool client_area;
HMONITOR monitor;
bool capture_cursor; bool capture_cursor;
BOOL cursor_visible; BOOL cursor_visible;
...@@ -260,6 +261,53 @@ try { ...@@ -260,6 +261,53 @@ try {
} }
#endif #endif
static winrt::Windows::Graphics::Capture::GraphicsCaptureItem
winrt_capture_create_item(IGraphicsCaptureItemInterop *const interop_factory,
HWND window, HMONITOR monitor)
{
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr};
if (window) {
try {
const HRESULT hr = interop_factory->CreateForWindow(
window,
winrt::guid_of<ABI::Windows::Graphics::Capture::
IGraphicsCaptureItem>(),
reinterpret_cast<void **>(
winrt::put_abi(item)));
if (FAILED(hr))
blog(LOG_ERROR, "CreateForWindow (0x%08X)", hr);
} catch (winrt::hresult_error &err) {
blog(LOG_ERROR, "CreateForWindow (0x%08X): %ls",
err.to_abi(), err.message().c_str());
} catch (...) {
blog(LOG_ERROR, "CreateForWindow (0x%08X)",
winrt::to_hresult());
}
} else {
assert(monitor);
try {
const HRESULT hr = interop_factory->CreateForMonitor(
monitor,
winrt::guid_of<ABI::Windows::Graphics::Capture::
IGraphicsCaptureItem>(),
reinterpret_cast<void **>(
winrt::put_abi(item)));
if (FAILED(hr))
blog(LOG_ERROR, "CreateForMonitor (0x%08X)",
hr);
} catch (winrt::hresult_error &err) {
blog(LOG_ERROR, "CreateForMonitor (0x%08X): %ls",
err.to_abi(), err.message().c_str());
} catch (...) {
blog(LOG_ERROR, "CreateForMonitor (0x%08X)",
winrt::to_hresult());
}
}
return item;
}
static void winrt_capture_device_loss_rebuild(void *device_void, void *data) static void winrt_capture_device_loss_rebuild(void *device_void, void *data)
{ {
winrt_capture *capture = static_cast<winrt_capture *>(data); winrt_capture *capture = static_cast<winrt_capture *>(data);
...@@ -268,20 +316,9 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data) ...@@ -268,20 +316,9 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data)
winrt::Windows::Graphics::Capture::GraphicsCaptureItem>(); winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
auto interop_factory = auto interop_factory =
activation_factory.as<IGraphicsCaptureItemInterop>(); activation_factory.as<IGraphicsCaptureItemInterop>();
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr}; winrt::Windows::Graphics::Capture::GraphicsCaptureItem item =
try { winrt_capture_create_item(interop_factory.get(),
interop_factory->CreateForWindow( capture->window, capture->monitor);
capture->window,
winrt::guid_of<ABI::Windows::Graphics::Capture::
IGraphicsCaptureItem>(),
reinterpret_cast<void **>(winrt::put_abi(item)));
} catch (winrt::hresult_error &err) {
blog(LOG_ERROR, "CreateForWindow (0x%08X): %ls", err.to_abi(),
err.message().c_str());
} catch (...) {
blog(LOG_ERROR, "CreateForWindow (0x%08X)",
winrt::to_hresult());
}
ID3D11Device *const d3d_device = (ID3D11Device *)device_void; ID3D11Device *const d3d_device = (ID3D11Device *)device_void;
ComPtr<IDXGIDevice> dxgi_device; ComPtr<IDXGIDevice> dxgi_device;
...@@ -341,8 +378,10 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data) ...@@ -341,8 +378,10 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data)
} }
} }
extern "C" EXPORT struct winrt_capture * static struct winrt_capture *winrt_capture_init_internal(BOOL cursor,
winrt_capture_init(BOOL cursor, HWND window, BOOL client_area) HWND window,
BOOL client_area,
HMONITOR monitor)
try { try {
ID3D11Device *const d3d_device = (ID3D11Device *)gs_get_device_obj(); ID3D11Device *const d3d_device = (ID3D11Device *)gs_get_device_obj();
ComPtr<IDXGIDevice> dxgi_device; ComPtr<IDXGIDevice> dxgi_device;
...@@ -365,26 +404,11 @@ try { ...@@ -365,26 +404,11 @@ try {
winrt::Windows::Graphics::Capture::GraphicsCaptureItem>(); winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
auto interop_factory = auto interop_factory =
activation_factory.as<IGraphicsCaptureItemInterop>(); activation_factory.as<IGraphicsCaptureItemInterop>();
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr}; winrt::Windows::Graphics::Capture::GraphicsCaptureItem item =
try { winrt_capture_create_item(interop_factory.get(), window,
hr = interop_factory->CreateForWindow( monitor);
window, if (!item)
winrt::guid_of<ABI::Windows::Graphics::Capture::
IGraphicsCaptureItem>(),
reinterpret_cast<void **>(winrt::put_abi(item)));
if (FAILED(hr)) {
blog(LOG_ERROR, "CreateForWindow (0x%08X)", hr);
return nullptr;
}
} catch (winrt::hresult_error &err) {
blog(LOG_ERROR, "CreateForWindow (0x%08X): %ls", err.to_abi(),
err.message().c_str());
return nullptr; return nullptr;
} catch (...) {
blog(LOG_ERROR, "CreateForWindow (0x%08X)",
winrt::to_hresult());
return nullptr;
}
const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice
device = inspectable.as<winrt::Windows::Graphics::DirectX:: device = inspectable.as<winrt::Windows::Graphics::DirectX::
...@@ -420,6 +444,7 @@ try { ...@@ -420,6 +444,7 @@ try {
struct winrt_capture *capture = new winrt_capture{}; struct winrt_capture *capture = new winrt_capture{};
capture->window = window; capture->window = window;
capture->client_area = client_area; capture->client_area = client_area;
capture->monitor = monitor;
capture->capture_cursor = cursor && cursor_toggle_supported; capture->capture_cursor = cursor && cursor_toggle_supported;
capture->cursor_visible = cursor; capture->cursor_visible = cursor;
capture->item = item; capture->item = item;
...@@ -456,6 +481,18 @@ try { ...@@ -456,6 +481,18 @@ try {
return nullptr; return nullptr;
} }
extern "C" EXPORT struct winrt_capture *
winrt_capture_init_window(BOOL cursor, HWND window, BOOL client_area)
{
return winrt_capture_init_internal(cursor, window, client_area, NULL);
}
extern "C" EXPORT struct winrt_capture *
winrt_capture_init_monitor(BOOL cursor, HMONITOR monitor)
{
return winrt_capture_init_internal(cursor, NULL, false, monitor);
}
extern "C" EXPORT void winrt_capture_free(struct winrt_capture *capture) extern "C" EXPORT void winrt_capture_free(struct winrt_capture *capture)
{ {
if (capture) { if (capture) {
......
...@@ -11,8 +11,10 @@ extern "C" { ...@@ -11,8 +11,10 @@ extern "C" {
EXPORT BOOL winrt_capture_supported(); EXPORT BOOL winrt_capture_supported();
EXPORT BOOL winrt_capture_cursor_toggle_supported(); EXPORT BOOL winrt_capture_cursor_toggle_supported();
EXPORT struct winrt_capture *winrt_capture_init(BOOL cursor, HWND window, EXPORT struct winrt_capture *winrt_capture_init_window(BOOL cursor, HWND window,
BOOL client_area); BOOL client_area);
EXPORT struct winrt_capture *winrt_capture_init_monitor(BOOL cursor,
HMONITOR monitor);
EXPORT void winrt_capture_free(struct winrt_capture *capture); EXPORT void winrt_capture_free(struct winrt_capture *capture);
EXPORT BOOL winrt_capture_active(const struct winrt_capture *capture); EXPORT BOOL winrt_capture_active(const struct winrt_capture *capture);
......
...@@ -28,9 +28,8 @@ ...@@ -28,9 +28,8 @@
typedef BOOL (*PFN_winrt_capture_supported)(); typedef BOOL (*PFN_winrt_capture_supported)();
typedef BOOL (*PFN_winrt_capture_cursor_toggle_supported)(); typedef BOOL (*PFN_winrt_capture_cursor_toggle_supported)();
typedef struct winrt_capture *(*PFN_winrt_capture_init)(BOOL cursor, typedef struct winrt_capture *(*PFN_winrt_capture_init_window)(
HWND window, BOOL cursor, HWND window, BOOL client_area);
BOOL client_area);
typedef void (*PFN_winrt_capture_free)(struct winrt_capture *capture); typedef void (*PFN_winrt_capture_free)(struct winrt_capture *capture);
typedef BOOL (*PFN_winrt_capture_active)(const struct winrt_capture *capture); typedef BOOL (*PFN_winrt_capture_active)(const struct winrt_capture *capture);
...@@ -46,7 +45,7 @@ struct winrt_exports { ...@@ -46,7 +45,7 @@ struct winrt_exports {
PFN_winrt_capture_supported winrt_capture_supported; PFN_winrt_capture_supported winrt_capture_supported;
PFN_winrt_capture_cursor_toggle_supported PFN_winrt_capture_cursor_toggle_supported
winrt_capture_cursor_toggle_supported; winrt_capture_cursor_toggle_supported;
PFN_winrt_capture_init winrt_capture_init; PFN_winrt_capture_init_window winrt_capture_init_window;
PFN_winrt_capture_free winrt_capture_free; PFN_winrt_capture_free winrt_capture_free;
PFN_winrt_capture_active winrt_capture_active; PFN_winrt_capture_active winrt_capture_active;
PFN_winrt_capture_show_cursor winrt_capture_show_cursor; PFN_winrt_capture_show_cursor winrt_capture_show_cursor;
...@@ -224,7 +223,7 @@ static bool load_winrt_imports(struct winrt_exports *exports, void *module, ...@@ -224,7 +223,7 @@ static bool load_winrt_imports(struct winrt_exports *exports, void *module,
WINRT_IMPORT(winrt_capture_supported); WINRT_IMPORT(winrt_capture_supported);
WINRT_IMPORT(winrt_capture_cursor_toggle_supported); WINRT_IMPORT(winrt_capture_cursor_toggle_supported);
WINRT_IMPORT(winrt_capture_init); WINRT_IMPORT(winrt_capture_init_window);
WINRT_IMPORT(winrt_capture_free); WINRT_IMPORT(winrt_capture_free);
WINRT_IMPORT(winrt_capture_active); WINRT_IMPORT(winrt_capture_active);
WINRT_IMPORT(winrt_capture_show_cursor); WINRT_IMPORT(winrt_capture_show_cursor);
...@@ -544,7 +543,7 @@ static void wc_tick(void *data, float seconds) ...@@ -544,7 +543,7 @@ static void wc_tick(void *data, float seconds)
if (wc->window && (wc->capture_winrt == NULL)) { if (wc->window && (wc->capture_winrt == NULL)) {
if (!wc->previously_failed) { if (!wc->previously_failed) {
wc->capture_winrt = wc->capture_winrt =
wc->exports.winrt_capture_init( wc->exports.winrt_capture_init_window(
wc->cursor, wc->window, wc->cursor, wc->window,
wc->client_area); wc->client_area);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册