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.master
parent
b460f025ed
commit
db35a022cd
|
@ -110,6 +110,7 @@ static bool get_client_box(HWND window, uint32_t width, uint32_t height,
|
|||
struct winrt_capture {
|
||||
HWND window;
|
||||
bool client_area;
|
||||
HMONITOR monitor;
|
||||
|
||||
bool capture_cursor;
|
||||
BOOL cursor_visible;
|
||||
|
@ -260,6 +261,53 @@ try {
|
|||
}
|
||||
#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)
|
||||
{
|
||||
winrt_capture *capture = static_cast<winrt_capture *>(data);
|
||||
|
@ -268,20 +316,9 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data)
|
|||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
|
||||
auto interop_factory =
|
||||
activation_factory.as<IGraphicsCaptureItemInterop>();
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr};
|
||||
try {
|
||||
interop_factory->CreateForWindow(
|
||||
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());
|
||||
}
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item =
|
||||
winrt_capture_create_item(interop_factory.get(),
|
||||
capture->window, capture->monitor);
|
||||
|
||||
ID3D11Device *const d3d_device = (ID3D11Device *)device_void;
|
||||
ComPtr<IDXGIDevice> dxgi_device;
|
||||
|
@ -341,8 +378,10 @@ static void winrt_capture_device_loss_rebuild(void *device_void, void *data)
|
|||
}
|
||||
}
|
||||
|
||||
extern "C" EXPORT struct winrt_capture *
|
||||
winrt_capture_init(BOOL cursor, HWND window, BOOL client_area)
|
||||
static struct winrt_capture *winrt_capture_init_internal(BOOL cursor,
|
||||
HWND window,
|
||||
BOOL client_area,
|
||||
HMONITOR monitor)
|
||||
try {
|
||||
ID3D11Device *const d3d_device = (ID3D11Device *)gs_get_device_obj();
|
||||
ComPtr<IDXGIDevice> dxgi_device;
|
||||
|
@ -365,26 +404,11 @@ try {
|
|||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem>();
|
||||
auto interop_factory =
|
||||
activation_factory.as<IGraphicsCaptureItemInterop>();
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item = {nullptr};
|
||||
try {
|
||||
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);
|
||||
return nullptr;
|
||||
}
|
||||
} catch (winrt::hresult_error &err) {
|
||||
blog(LOG_ERROR, "CreateForWindow (0x%08X): %ls", err.to_abi(),
|
||||
err.message().c_str());
|
||||
winrt::Windows::Graphics::Capture::GraphicsCaptureItem item =
|
||||
winrt_capture_create_item(interop_factory.get(), window,
|
||||
monitor);
|
||||
if (!item)
|
||||
return nullptr;
|
||||
} catch (...) {
|
||||
blog(LOG_ERROR, "CreateForWindow (0x%08X)",
|
||||
winrt::to_hresult());
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const winrt::Windows::Graphics::DirectX::Direct3D11::IDirect3DDevice
|
||||
device = inspectable.as<winrt::Windows::Graphics::DirectX::
|
||||
|
@ -420,6 +444,7 @@ try {
|
|||
struct winrt_capture *capture = new winrt_capture{};
|
||||
capture->window = window;
|
||||
capture->client_area = client_area;
|
||||
capture->monitor = monitor;
|
||||
capture->capture_cursor = cursor && cursor_toggle_supported;
|
||||
capture->cursor_visible = cursor;
|
||||
capture->item = item;
|
||||
|
@ -456,6 +481,18 @@ try {
|
|||
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)
|
||||
{
|
||||
if (capture) {
|
||||
|
|
|
@ -11,8 +11,10 @@ extern "C" {
|
|||
|
||||
EXPORT BOOL winrt_capture_supported();
|
||||
EXPORT BOOL winrt_capture_cursor_toggle_supported();
|
||||
EXPORT struct winrt_capture *winrt_capture_init(BOOL cursor, HWND window,
|
||||
BOOL client_area);
|
||||
EXPORT struct winrt_capture *winrt_capture_init_window(BOOL cursor, HWND window,
|
||||
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 BOOL winrt_capture_active(const struct winrt_capture *capture);
|
||||
|
|
|
@ -28,9 +28,8 @@
|
|||
|
||||
typedef BOOL (*PFN_winrt_capture_supported)();
|
||||
typedef BOOL (*PFN_winrt_capture_cursor_toggle_supported)();
|
||||
typedef struct winrt_capture *(*PFN_winrt_capture_init)(BOOL cursor,
|
||||
HWND window,
|
||||
BOOL client_area);
|
||||
typedef struct winrt_capture *(*PFN_winrt_capture_init_window)(
|
||||
BOOL cursor, HWND window, BOOL client_area);
|
||||
typedef void (*PFN_winrt_capture_free)(struct winrt_capture *capture);
|
||||
|
||||
typedef BOOL (*PFN_winrt_capture_active)(const struct winrt_capture *capture);
|
||||
|
@ -46,7 +45,7 @@ struct winrt_exports {
|
|||
PFN_winrt_capture_supported winrt_capture_supported;
|
||||
PFN_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_active winrt_capture_active;
|
||||
PFN_winrt_capture_show_cursor winrt_capture_show_cursor;
|
||||
|
@ -224,7 +223,7 @@ static bool load_winrt_imports(struct winrt_exports *exports, void *module,
|
|||
|
||||
WINRT_IMPORT(winrt_capture_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_active);
|
||||
WINRT_IMPORT(winrt_capture_show_cursor);
|
||||
|
@ -544,7 +543,7 @@ static void wc_tick(void *data, float seconds)
|
|||
if (wc->window && (wc->capture_winrt == NULL)) {
|
||||
if (!wc->previously_failed) {
|
||||
wc->capture_winrt =
|
||||
wc->exports.winrt_capture_init(
|
||||
wc->exports.winrt_capture_init_window(
|
||||
wc->cursor, wc->window,
|
||||
wc->client_area);
|
||||
|
||||
|
|
Loading…
Reference in New Issue