diff --git a/contrib/src/ffmpeg/windows-dxgi-support.patch b/contrib/src/ffmpeg/windows-dxgi-support.patch index b1c1e5096ad1edaf658f4846408b65943480fb95..33e58855e5dd316180592587cd94108023d120cd 100644 --- a/contrib/src/ffmpeg/windows-dxgi-support.patch +++ b/contrib/src/ffmpeg/windows-dxgi-support.patch @@ -1,4 +1,4 @@ -From 000d467635e4ef42d805fd4cc17efdb2f986ce5e Mon Sep 17 00:00:00 2001 +From 5215039eb485d3a17b9b69f67f2a7a72350eb639 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 @@ -9,13 +9,13 @@ Subject: [PATCH] Add dxgi support libavdevice/alldevices.c | 1 + libavdevice/d3dHelpers.h | 59 ++++++++ libavdevice/direct3d11.interop.h | 51 +++++++ - libavdevice/dxgigrab.cpp | 229 +++++++++++++++++++++++++++++++ - libavdevice/dxgigrab.h | 83 +++++++++++ + libavdevice/dxgigrab.cpp | 225 +++++++++++++++++++++++++++++++ + libavdevice/dxgigrab.h | 83 ++++++++++++ libavdevice/dxgigrab_c.c | 59 ++++++++ - libavdevice/dxgigrab_c.h | 98 +++++++++++++ + libavdevice/dxgigrab_c.h | 98 ++++++++++++++ libavdevice/windows_capture.cpp | 184 +++++++++++++++++++++++++ libavdevice/windows_capture.h | 82 +++++++++++ - 11 files changed, 851 insertions(+) + 11 files changed, 847 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..da16b026a5 +index 0000000000..9774e72ab1 --- /dev/null +++ b/libavdevice/dxgigrab.cpp -@@ -0,0 +1,229 @@ +@@ -0,0 +1,225 @@ +/* + * DXGI video grab interface + * @@ -228,6 +228,9 @@ index 0000000000..da16b026a5 + +#include "dxgigrab.h" + ++#include <dwmapi.h> ++#include <sstream> ++ +#ifdef __cplusplus +extern "C" { +#endif @@ -262,25 +265,18 @@ index 0000000000..da16b026a5 + monitorData.rect.left = 0; + monitorData.rect.bottom = 0; + monitorData.rect.right = 0; -+ std::string name; ++ std::string handle; + AVStream *st = NULL; + -+ if (!strncmp(s1->url, "title=", 6)) { ++ if (!strncmp(s1->url, "hwnd=", 5)) { + if (!s->hwnd) { -+ 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())); ++ handle = s1->url + 5; ++ try { ++ s->hwnd = reinterpret_cast<HWND>(std::stoull(handle, nullptr, 16)); ++ } catch (...) {} + if (!s->hwnd) { + av_log(s1, AV_LOG_ERROR, -+ "Can't find window '%s', aborting.\n", name.c_str()); ++ "Can't find window from handle '%s', aborting.\n", handle.c_str()); + return AVERROR_EXTERNAL; + } + } @@ -289,7 +285,7 @@ index 0000000000..da16b026a5 + char *display_number = av_strdup(s1->url); + if (!sscanf(s1->url, "%[^+]+%d,%d ", display_number, &s->offset_x, &s->offset_y)) { + av_log(s1, AV_LOG_ERROR, -+ "Please use \"<screenNumber>+<X,Y> <WidthxHeight>\" or \"title=<windowname>\" to specify your target.\n"); ++ "Please use \"<screenNumber>+<X,Y> <WidthxHeight>\" or \"hwnd=<windowHandle>\" to specify your target.\n"); + return AVERROR_EXTERNAL; + } + if (s->offset_x || s->offset_y) { @@ -312,7 +308,7 @@ index 0000000000..da16b026a5 + + if (!s->hmnt && !s->hwnd) { + av_log(s1, AV_LOG_ERROR, -+ "Please use \"<screenNumber>+<X,Y> <WidthxHeight>\" or \"title=<windowname>\" to " ++ "Please use \"<screenNumber>+<X,Y> <WidthxHeight>\" or \"hwnd=<windowHandle>\" to " + "specify your target.\n"); + return AVERROR_EXTERNAL; + } @@ -362,8 +358,8 @@ index 0000000000..da16b026a5 + 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; -+ x_internal->windowName = name; ++ x_internal->m_capture->window = handle; ++ x_internal->windowHandle = handle; + } + + s->time_base = av_inv_q(s->framerate); @@ -429,7 +425,7 @@ index 0000000000..da16b026a5 +} diff --git a/libavdevice/dxgigrab.h b/libavdevice/dxgigrab.h new file mode 100644 -index 0000000000..a247077e7d +index 0000000000..92cad7dab8 --- /dev/null +++ b/libavdevice/dxgigrab.h @@ -0,0 +1,83 @@ @@ -511,7 +507,7 @@ index 0000000000..a247077e7d + +struct dxgigrab_internal { + std::unique_ptr<WindowsCapture> m_capture{ nullptr }; -+ std::string windowName; ++ std::string windowHandle; + std::mutex mtx; +}; + @@ -963,6 +959,6 @@ index 0000000000..3e9269ed58 + std::mutex mtx_; + bool running_; +}; --- +-- 2.30.2.windows.1 diff --git a/src/media/media_decoder.cpp b/src/media/media_decoder.cpp index f9e5d04a2850ac240454bd8824cbcf4741659fc2..a98c87161a539e746a6eb5a718b2a40f4bcce449 100644 --- a/src/media/media_decoder.cpp +++ b/src/media/media_decoder.cpp @@ -631,7 +631,6 @@ MediaDecoder::decode(AVPacket& packet) } #endif avcodec_flush_buffers(decoderCtx_); - setupStream(); return ret == AVERROR_EOF ? DecodeStatus::Success : DecodeStatus::DecodeError; } diff --git a/src/media/video/video_input.cpp b/src/media/video/video_input.cpp index 398bd302eb1c926c39e7b559d6f3d7a8f26ea08e..04725d67bb5594e9b4df243e2a498d3f6a91dc5c 100644 --- a/src/media/video/video_input.cpp +++ b/src/media/video/video_input.cpp @@ -261,30 +261,6 @@ 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() { @@ -310,23 +286,6 @@ 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; } @@ -516,21 +475,15 @@ VideoInput::initWindowsGrab(const std::string& display) // Patterns // full screen sharing : :1+0,0 2560x1440 - SCREEN 1, POSITION 0X0, RESOLUTION 2560X1440 // area sharing : :1+882,211 1532x779 - SCREEN 1, POSITION 882x211, RESOLUTION 1532x779 - // window sharing : :+1,0 0x0 window-id:TITLE - POSITION 0X0 + // window sharing : :+1,0 0x0 window-id:HANDLE - POSITION 0X0 size_t space = display.find(' '); std::string windowIdStr = "window-id:"; - size_t winIdPos = display.find(windowIdStr); + size_t winHandlePos = display.find(windowIdStr); DeviceParams p = jami::getVideoDeviceMonitor().getDeviceParams(DEVICE_DESKTOP); - 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); + if (winHandlePos != std::string::npos) { + p.input = display.substr(winHandlePos + windowIdStr.size()); // "HANDLE"; + p.name = display.substr(winHandlePos + windowIdStr.size()); // "HANDLE"; 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 80422457dafce5b5050fc0b95b8a89f3b08af49d..570427ec9d275d06fa68e3a6a6d69013a863b0d3 100644 --- a/src/media/video/video_input.h +++ b/src/media/video/video_input.h @@ -137,7 +137,6 @@ private: bool initFile(std::string path); #ifdef WIN32 bool initWindowsGrab(const std::string& display); - DWORD wProcessId; #endif bool isCapturing() const noexcept;