Skip to content
Snippets Groups Projects
Commit 33f089ef authored by Aline Gondim Santos's avatar Aline Gondim Santos Committed by Adrien Béraud
Browse files

windows sharing: don't loose window if name changes

GitLab: jami-client-qt#481

Change-Id: I1cea58c2c1a4c03df4488e3dd88d381fce659b77
parent 9dd1a405
No related branches found
No related tags found
No related merge requests found
From 9055aa8b78fcd8e913642ffe21759579283ae1bb Mon Sep 17 00:00:00 2001
From 000d467635e4ef42d805fd4cc17efdb2f986ce5e Mon Sep 17 00:00:00 2001
From: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com>
Date: Thu, 29 Dec 2022 12:59:19 -0300
Subject: [PATCH] Add dxgi support
......@@ -7,15 +7,15 @@ Subject: [PATCH] Add dxgi support
configure | 1 +
libavdevice/Makefile | 4 +
libavdevice/alldevices.c | 1 +
libavdevice/d3dHelpers.h | 59 +++++++++
libavdevice/direct3d11.interop.h | 51 ++++++++
libavdevice/dxgigrab.cpp | 218 +++++++++++++++++++++++++++++++
libavdevice/dxgigrab.h | 83 ++++++++++++
libavdevice/dxgigrab_c.c | 59 +++++++++
libavdevice/dxgigrab_c.h | 98 ++++++++++++++
libavdevice/windows_capture.cpp | 184 ++++++++++++++++++++++++++
libavdevice/windows_capture.h | 82 ++++++++++++
11 files changed, 840 insertions(+)
libavdevice/d3dHelpers.h | 59 ++++++++
libavdevice/direct3d11.interop.h | 51 +++++++
libavdevice/dxgigrab.cpp | 229 +++++++++++++++++++++++++++++++
libavdevice/dxgigrab.h | 83 +++++++++++
libavdevice/dxgigrab_c.c | 59 ++++++++
libavdevice/dxgigrab_c.h | 98 +++++++++++++
libavdevice/windows_capture.cpp | 184 +++++++++++++++++++++++++
libavdevice/windows_capture.h | 82 +++++++++++
11 files changed, 851 insertions(+)
create mode 100644 libavdevice/d3dHelpers.h
create mode 100644 libavdevice/direct3d11.interop.h
create mode 100644 libavdevice/dxgigrab.cpp
......@@ -194,10 +194,10 @@ index 0000000000..62c9b0843e
+}
diff --git a/libavdevice/dxgigrab.cpp b/libavdevice/dxgigrab.cpp
new file mode 100644
index 0000000000..365ba4f9aa
index 0000000000..da16b026a5
--- /dev/null
+++ b/libavdevice/dxgigrab.cpp
@@ -0,0 +1,218 @@
@@ -0,0 +1,229 @@
+/*
+ * DXGI video grab interface
+ *
......@@ -262,17 +262,28 @@ index 0000000000..365ba4f9aa
+ monitorData.rect.left = 0;
+ monitorData.rect.bottom = 0;
+ monitorData.rect.right = 0;
+ const char *name = NULL;
+ std::string name;
+ AVStream *st = NULL;
+
+ if (!strncmp(s1->url, "title=", 6)) {
+ if (!s->hwnd) {
+ name = s1->url + 6;
+ s->hwnd = FindWindow(NULL, name);
+ int srcLength = (int) name.length();
+ int requiredSize = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), srcLength, nullptr, 0);
+ if (!requiredSize) {
+ return AVERROR_EXTERNAL;
+ }
+ std::wstring wName((size_t) requiredSize, 0);
+ if (!MultiByteToWideChar(CP_UTF8, 0, name.c_str(), srcLength, &(*wName.begin()), requiredSize)) {
+ return AVERROR_EXTERNAL;
+ }
+ s->hwnd = FindWindowW(NULL, &(*wName.begin()));
+ if (!s->hwnd) {
+ av_log(s1, AV_LOG_ERROR,
+ "Can't find window '%s', aborting.\n", name);
+ "Can't find window '%s', aborting.\n", name.c_str());
+ return AVERROR_EXTERNAL;
+ }
+ }
+ } else {
+ s->hwnd = NULL;
+ char *display_number = av_strdup(s1->url);
......@@ -351,8 +362,8 @@ index 0000000000..365ba4f9aa
+ x_internal->m_capture.reset(new WindowsCapture(m_device, windowItem, monitorData));
+ x_internal->m_capture->StartCapture();
+ x_internal->m_capture->checkNewFrameArrived();
+ x_internal->m_capture->window = name ? name : "";
+ x_internal->windowName = name ? name : "";
+ x_internal->m_capture->window = name;
+ x_internal->windowName = name;
+ }
+
+ s->time_base = av_inv_q(s->framerate);
......@@ -676,7 +687,7 @@ index 0000000000..d624ca0683
+#endif /* AVDEVICE_DXGI_C_H */
diff --git a/libavdevice/windows_capture.cpp b/libavdevice/windows_capture.cpp
new file mode 100644
index 0000000000..9eaf8cf222
index 0000000000..c6b29f1a1d
--- /dev/null
+++ b/libavdevice/windows_capture.cpp
@@ -0,0 +1,184 @@
......@@ -780,12 +791,12 @@ index 0000000000..9eaf8cf222
+{
+ std::lock_guard<std::mutex> lk(mtx_);
+ if (!running_)
+ return 0;
+ return false;
+ auto shouldResize = false;
+
+ auto frame = m_framePool.TryGetNextFrame();
+ if (!frame)
+ return 0;
+ return false;
+
+ auto frameSurface = GetDXGIInterfaceFromObject<ID3D11Texture2D>(frame.Surface());
+
......@@ -793,7 +804,7 @@ index 0000000000..9eaf8cf222
+ frameSurface->GetDesc(&desc);
+ auto frameContentSize = frame.ContentSize();
+ if (desc.Width <= 0 || desc.Height <= 0)
+ return 0;
+ return false;
+
+ shouldResize = frameContentSize.Width != m_DeviceSize.Width || frameContentSize.Height != m_DeviceSize.Height;
+
......@@ -820,7 +831,7 @@ index 0000000000..9eaf8cf222
+ // copy the texture to a staging resource
+ m_d3dContext->CopyResource(texture, frameSurface.get());
+
+ return 1;
+ return true;
+}
+
+int
......
......@@ -261,6 +261,30 @@ VideoInput::configureFilePlayback(const std::string&,
sink_->setFrameSize(decoder_->getWidth(), decoder_->getHeight());
}
#ifdef WIN32
BOOL CALLBACK
EnumWindowsProcMy(HWND hwnd, LPARAM lParam)
{
std::pair<DWORD, std::string>* dataPair = reinterpret_cast<std::pair<DWORD, std::string>*>(lParam);
DWORD lpdwProcessId;
if (auto parent = GetWindow(hwnd, GW_OWNER))
GetWindowThreadProcessId(parent, &lpdwProcessId);
else
GetWindowThreadProcessId(hwnd, &lpdwProcessId);
int len = GetWindowTextLength(hwnd) + 1;
std::vector<wchar_t> buf(len);
GetWindowText(hwnd, &buf[0], len);
if (lpdwProcessId == dataPair->first) {
if (!IsWindowVisible(hwnd))
return TRUE;
dataPair->second = to_string(&buf[0]);
return FALSE;
}
return TRUE;
}
#endif
void
VideoInput::createDecoder()
{
......@@ -286,6 +310,23 @@ VideoInput::createDecoder()
bool ready = false, restartSink = false;
if ((decOpts_.format == "x11grab" || decOpts_.format == "dxgigrab") && !decOpts_.is_area) {
#ifdef WIN32
// if window is not find, it might have changed its name
// in that case we must search for the parent process window
auto hwnd = FindWindow(NULL, to_wstring(decOpts_.name.substr(6)).c_str());
if (!hwnd) {
std::pair<DWORD, std::string> idName(wProcessId, {});
LPARAM lParam = reinterpret_cast<LPARAM>(&idName);
EnumWindows(EnumWindowsProcMy, lParam);
if (!idName.second.empty()) {
auto newTitle = "title=" + idName.second;
if (decOpts_.name != newTitle || decOpts_.input != newTitle) {
decOpts_.name = newTitle;
decOpts_.input = newTitle;
}
}
}
#endif
decOpts_.width = 0;
decOpts_.height = 0;
}
......@@ -484,6 +525,12 @@ VideoInput::initWindowsGrab(const std::string& display)
if (winIdPos != std::string::npos) {
p.input = display.substr(winIdPos + windowIdStr.size()); // "TITLE";
p.name = display.substr(winIdPos + windowIdStr.size()); // "TITLE";
auto hwnd = FindWindow(NULL, to_wstring(p.name.substr(6)).c_str());
if (auto parent = GetWindow(hwnd, GW_OWNER))
GetWindowThreadProcessId(parent, &wProcessId);
else
GetWindowThreadProcessId(hwnd, &wProcessId);
p.is_area = 0;
} else {
p.input = display.substr(1);
......
......@@ -137,6 +137,7 @@ private:
bool initFile(std::string path);
#ifdef WIN32
bool initWindowsGrab(const std::string& display);
DWORD wProcessId;
#endif
bool isCapturing() const noexcept;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment