mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-26 20:25:34 +08:00
139 lines
2.8 KiB
C++
139 lines
2.8 KiB
C++
#include "screen_capture_wgc.h"
|
|
|
|
#include <Windows.h>
|
|
#include <d3d11_4.h>
|
|
#include <winrt/Windows.Foundation.Metadata.h>
|
|
#include <winrt/Windows.Graphics.Capture.h>
|
|
|
|
#include <iostream>
|
|
|
|
BOOL WINAPI EnumMonitorProc(HMONITOR hmonitor, HDC hdc, LPRECT lprc,
|
|
LPARAM data) {
|
|
MONITORINFOEX info_ex;
|
|
info_ex.cbSize = sizeof(MONITORINFOEX);
|
|
|
|
GetMonitorInfo(hmonitor, &info_ex);
|
|
|
|
if (info_ex.dwFlags == DISPLAY_DEVICE_MIRRORING_DRIVER) return true;
|
|
|
|
if (info_ex.dwFlags & MONITORINFOF_PRIMARY) {
|
|
*(HMONITOR *)data = hmonitor;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
HMONITOR GetPrimaryMonitor() {
|
|
HMONITOR hmonitor = nullptr;
|
|
|
|
::EnumDisplayMonitors(NULL, NULL, EnumMonitorProc, (LPARAM)&hmonitor);
|
|
|
|
return hmonitor;
|
|
}
|
|
|
|
ScreenCaptureWgc::ScreenCaptureWgc() {}
|
|
|
|
ScreenCaptureWgc::~ScreenCaptureWgc() {
|
|
Stop();
|
|
CleanUp();
|
|
}
|
|
|
|
bool ScreenCaptureWgc::IsWgcSupported() {
|
|
try {
|
|
/* no contract for IGraphicsCaptureItemInterop, verify 10.0.18362.0 */
|
|
return winrt::Windows::Foundation::Metadata::ApiInformation::
|
|
IsApiContractPresent(L"Windows.Foundation.UniversalApiContract", 8);
|
|
} catch (const winrt::hresult_error &) {
|
|
return false;
|
|
} catch (...) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
int ScreenCaptureWgc::Init(const RECORD_DESKTOP_RECT &rect, const int fps,
|
|
cb_desktop_data cb) {
|
|
int error = 0;
|
|
if (_inited == true) return error;
|
|
|
|
_fps = fps;
|
|
|
|
_on_data = cb;
|
|
|
|
do {
|
|
if (!IsWgcSupported()) {
|
|
std::cout << "AE_UNSUPPORT" << std::endl;
|
|
error = 2;
|
|
break;
|
|
}
|
|
|
|
session_ = new WgcSessionImpl();
|
|
if (!session_) {
|
|
error = -1;
|
|
std::cout << "AE_WGC_CREATE_CAPTURER_FAILED" << std::endl;
|
|
break;
|
|
}
|
|
|
|
session_->RegisterObserver(this);
|
|
|
|
error = session_->Initialize(GetPrimaryMonitor());
|
|
|
|
_inited = true;
|
|
} while (0);
|
|
|
|
if (error != 0) {
|
|
}
|
|
|
|
return error;
|
|
}
|
|
|
|
int ScreenCaptureWgc::Start() {
|
|
if (_running == true) {
|
|
std::cout << "record desktop duplication is already running" << std::endl;
|
|
return 0;
|
|
}
|
|
|
|
if (_inited == false) {
|
|
std::cout << "AE_NEED_INIT" << std::endl;
|
|
return 4;
|
|
}
|
|
|
|
_running = true;
|
|
session_->Start();
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ScreenCaptureWgc::Pause() {
|
|
_paused = true;
|
|
if (session_) session_->Pause();
|
|
return 0;
|
|
}
|
|
|
|
int ScreenCaptureWgc::Resume() {
|
|
_paused = false;
|
|
if (session_) session_->Resume();
|
|
return 0;
|
|
}
|
|
|
|
int ScreenCaptureWgc::Stop() {
|
|
_running = false;
|
|
|
|
if (session_) session_->Stop();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ScreenCaptureWgc::OnFrame(const WgcSession::wgc_session_frame &frame) {
|
|
if (_on_data)
|
|
_on_data((unsigned char *)frame.data, frame.width * frame.height * 4,
|
|
frame.width, frame.height);
|
|
}
|
|
|
|
void ScreenCaptureWgc::CleanUp() {
|
|
_inited = false;
|
|
|
|
if (session_) session_->Release();
|
|
|
|
session_ = nullptr;
|
|
}
|