Skip to content

Commit

Permalink
Fix multi-monitor capturing
Browse files Browse the repository at this point in the history
  • Loading branch information
awawa-dev committed Oct 30, 2024
1 parent 1b2898b commit ceefa88
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 36 deletions.
44 changes: 38 additions & 6 deletions sources/base/Grabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,24 @@ void Grabber::setEnabled(bool enable)

void Grabber::setMonitorNits(int nits)
{
_targetMonitorNits = nits;
if (_targetMonitorNits != nits)
{
_targetMonitorNits = nits;

Debug(_log, "Set nits to %i", _targetMonitorNits);

if (_initialized && !_blocked)
{
Debug(_log, "Restarting video grabber");
uninit();
start();
}
else
{
Info(_log, "Delayed restart of the grabber due to change of monitor nits value");
_restartNeeded = true;
}
}
}

void Grabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
Expand All @@ -128,7 +145,24 @@ void Grabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTo

void Grabber::enableHardwareAcceleration(bool hardware)
{
_hardware = hardware;
if (_hardware != hardware)
{
_hardware = hardware;

Debug(_log, "Set hardware acceleration to %s", _hardware ? "enabled" : "disabled");

if (_initialized && !_blocked)
{
Debug(_log, "Restarting video grabber");
uninit();
start();
}
else
{
Info(_log, "Delayed restart of the grabber due to change of the hardware acceleration");
_restartNeeded = true;
}
}
}

bool Grabber::trySetInput(int input)
Expand Down Expand Up @@ -520,10 +554,8 @@ int Grabber::getTargetSystemFrameDimension(int& targetSizeX, int& targetSizeY)

int Grabber::getTargetSystemFrameDimension(int actualWidth, int actualHeight, int& targetSizeX, int& targetSizeY)
{
int startX = _cropLeft;
int startY = _cropTop;
int realSizeX = actualWidth - startX - _cropRight;
int realSizeY = actualHeight - startY - _cropBottom;
int realSizeX = actualWidth;
int realSizeY = actualHeight;

if (realSizeX <= 16 || realSizeY <= 16)
{
Expand Down
79 changes: 49 additions & 30 deletions sources/grabber/windows/DX/DxGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,9 @@ bool DxGrabber::initDirectX(QString selectedDeviceName)
_multiMonitor = (selectedDeviceName == multiName);

IDXGIOutput* pOutput;
for (UINT j = 0; pAdapter->EnumOutputs(j, &pOutput) != DXGI_ERROR_NOT_FOUND && (!exitNow || _multiMonitor); j++)


for (UINT j = 0; pAdapter->EnumOutputs(j, &pOutput) != DXGI_ERROR_NOT_FOUND && (!exitNow || (_multiMonitor && result)); j++)
{
DXGI_OUTPUT_DESC oDesc{};
pOutput->GetDesc(&oDesc);
Expand All @@ -329,38 +331,46 @@ bool DxGrabber::initDirectX(QString selectedDeviceName)

if (CHECK(pOutput->QueryInterface(__uuidof(IDXGIOutput6), reinterpret_cast<void**>(&pOutput6))))
{
HRESULT findDriver = E_FAIL;
D3D_FEATURE_LEVEL featureLevel;
std::vector<D3D_DRIVER_TYPE> driverTypes{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
D3D_DRIVER_TYPE_UNKNOWN
};

CLEAR(featureLevel);

for (auto& driverType : driverTypes)
if (_d3dDevice == nullptr)
{
findDriver = D3D11CreateDevice(pAdapter, driverType,
nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, nullptr, 0,
D3D11_SDK_VERSION, &_d3dDevice, &featureLevel, &_d3dContext);

if (SUCCEEDED(findDriver))
HRESULT findDriver = E_FAIL;
D3D_FEATURE_LEVEL featureLevel;
std::vector<D3D_DRIVER_TYPE> driverTypes{
D3D_DRIVER_TYPE_HARDWARE,
D3D_DRIVER_TYPE_WARP,
D3D_DRIVER_TYPE_REFERENCE,
D3D_DRIVER_TYPE_UNKNOWN
};

CLEAR(featureLevel);

for (auto& driverType : driverTypes)
{
switch (driverType)
findDriver = D3D11CreateDevice(pAdapter, driverType,
nullptr, D3D11_CREATE_DEVICE_BGRA_SUPPORT, nullptr, 0,
D3D11_SDK_VERSION, &_d3dDevice, &featureLevel, &_d3dContext);

if (SUCCEEDED(findDriver))
{
case D3D_DRIVER_TYPE_HARDWARE: Info(_log, "Selected D3D_DRIVER_TYPE_HARDWARE"); break;
case D3D_DRIVER_TYPE_WARP: Info(_log, "Selected D3D_DRIVER_TYPE_WARP"); break;
case D3D_DRIVER_TYPE_REFERENCE: Info(_log, "Selected D3D_DRIVER_TYPE_REFERENCE"); break;
case D3D_DRIVER_TYPE_UNKNOWN: Info(_log, "Selected D3D_DRIVER_TYPE_UNKNOWN"); break;
switch (driverType)
{
case D3D_DRIVER_TYPE_HARDWARE: Info(_log, "Selected D3D_DRIVER_TYPE_HARDWARE"); break;
case D3D_DRIVER_TYPE_WARP: Info(_log, "Selected D3D_DRIVER_TYPE_WARP"); break;
case D3D_DRIVER_TYPE_REFERENCE: Info(_log, "Selected D3D_DRIVER_TYPE_REFERENCE"); break;
case D3D_DRIVER_TYPE_UNKNOWN: Info(_log, "Selected D3D_DRIVER_TYPE_UNKNOWN"); break;
}

break;
}
}

break;
if (!SUCCEEDED(findDriver))
{
_d3dContext = nullptr;
}
}

if (CHECK(findDriver) && _d3dDevice != nullptr)
if (_d3dDevice != nullptr)
{
HRESULT status = E_FAIL;
DXGI_OUTPUT_DESC1 descGamut;
Expand Down Expand Up @@ -420,7 +430,7 @@ bool DxGrabber::initDirectX(QString selectedDeviceName)

if (!display->wideGamut)
{
int maxSize = std::max((display->actualWidth - _cropLeft - _cropRight), (display->actualHeight - _cropTop - _cropBottom));
int maxSize = std::max(display->actualWidth, display->actualHeight);

display->actualDivide = 0;
while (maxSize > _width)
Expand All @@ -435,7 +445,7 @@ bool DxGrabber::initDirectX(QString selectedDeviceName)
else
{
display->actualDivide = -1;
getTargetSystemFrameDimension(targetSizeX, targetSizeY);
getTargetSystemFrameDimension(display->actualWidth, display->actualHeight, targetSizeX, targetSizeY);
}
}

Expand Down Expand Up @@ -479,6 +489,7 @@ bool DxGrabber::initDirectX(QString selectedDeviceName)
else
{
result = true;
_handles.emplace_back(std::move(display));
Info(_log, "The DX11 device has been initialized. Hardware acceleration is disabled");
}
}
Expand Down Expand Up @@ -517,6 +528,11 @@ bool DxGrabber::initDirectX(QString selectedDeviceName)

SafeRelease(&pFactory);

if (!result && _handles.size() > 0)
{
uninit();
}

return result;
}

Expand Down Expand Up @@ -760,8 +776,11 @@ void DxGrabber::grabFrame()
images.push_back(std::pair<int, Image<ColorRgb>>(width, image));
}

width += display->actualWidth;
height = std::max(display->actualHeight, height);
int targetSizeX = 0, targetSizeY = 0;
int divide = getTargetSystemFrameDimension(display->actualWidth, display->actualHeight, targetSizeX, targetSizeY);

width += targetSizeX;
height = std::max(targetSizeY, height);
}

if (useCache && (_cacheImage.width() != width || _cacheImage.height() != height))
Expand Down Expand Up @@ -911,7 +930,7 @@ int DxGrabber::captureFrame(DisplayHandle& display, Image<ColorRgb>& image)
int divide = getTargetSystemFrameDimension(display.actualWidth, display.actualHeight, targetSizeX, targetSizeY);

image = Image<ColorRgb>(targetSizeX, targetSizeY);
FrameDecoder::processSystemImageBGRA(image, targetSizeX, targetSizeY, _cropLeft, _cropTop, (uint8_t*)internalMap.pData, display.actualWidth, display.actualHeight, divide, (_hdrToneMappingEnabled == 0 || !_lutBufferInit || !useLut) ? nullptr : _lut.data(), lineSize);
FrameDecoder::processSystemImageBGRA(image, targetSizeX, targetSizeY, 0, 0, (uint8_t*)internalMap.pData, display.actualWidth, display.actualHeight, divide, (_hdrToneMappingEnabled == 0 || !_lutBufferInit || !useLut) ? nullptr : _lut.data(), lineSize);

result = 1;
_d3dContext->Unmap(display.d3dSourceTexture, 0);
Expand Down

0 comments on commit ceefa88

Please sign in to comment.