From 33f089ef50deb19c15b094dde10f87814b7c48b0 Mon Sep 17 00:00:00 2001 From: Aline Gondim Santos <aline.gondimsantos@savoirfairelinux.com> Date: Wed, 11 Jan 2023 09:11:10 -0300 Subject: [PATCH] windows sharing: don't loose window if name changes GitLab: https://git.jami.net/savoirfairelinux/jami-client-qt/-/issues/481 Change-Id: I1cea58c2c1a4c03df4488e3dd88d381fce659b77 --- contrib/src/ffmpeg/windows-dxgi-support.patch | 61 +++++++++++-------- src/media/video/video_input.cpp | 47 ++++++++++++++ src/media/video/video_input.h | 1 + 3 files changed, 84 insertions(+), 25 deletions(-) diff --git a/contrib/src/ffmpeg/windows-dxgi-support.patch b/contrib/src/ffmpeg/windows-dxgi-support.patch index 4458c03156..b1c1e5096a 100644 --- a/contrib/src/ffmpeg/windows-dxgi-support.patch +++ b/contrib/src/ffmpeg/windows-dxgi-support.patch @@ -1,4 +1,4 @@ -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,16 +262,27 @@ 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)) { -+ name = s1->url + 6; -+ s->hwnd = FindWindow(NULL, name); + if (!s->hwnd) { -+ av_log(s1, AV_LOG_ERROR, -+ "Can't find window '%s', aborting.\n", name); -+ return AVERROR_EXTERNAL; ++ name = s1->url + 6; ++ 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.c_str()); ++ return AVERROR_EXTERNAL; ++ } + } + } else { + s->hwnd = NULL; @@ -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 diff --git a/src/media/video/video_input.cpp b/src/media/video/video_input.cpp index d56c291b58..398bd302eb 100644 --- a/src/media/video/video_input.cpp +++ b/src/media/video/video_input.cpp @@ -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); diff --git a/src/media/video/video_input.h b/src/media/video/video_input.h index 570427ec9d..80422457da 100644 --- a/src/media/video/video_input.h +++ b/src/media/video/video_input.h @@ -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; -- GitLab