Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature to re-order displays in multi-display mode (DirectX) #1023

Merged
merged 1 commit into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions include/base/Grabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ class Grabber : public DetectionAutomatic, public DetectionManual, protected Lut

void setMonitorNits(int nits);

void setReorderDisplays(int order);

void setFpsSoftwareDecimation(int decimation) override;

int getFpsSoftwareDecimation() override;
Expand Down Expand Up @@ -269,6 +271,7 @@ public slots:
int _actualWidth, _actualHeight, _actualFPS;
QString _actualDeviceName;
uint _targetMonitorNits;
int _reorderDisplays;

int _lineLength;
int _frameByteSize;
Expand Down
2 changes: 1 addition & 1 deletion include/led-strip/ChannelCalibration.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class ChannelCalibration
public:
ChannelCalibration(quint8 instance, QString channelName, const QJsonObject& colorConfig, int defaultR, int defaultG, int defaultB);

void apply(uint8_t input, uint8_t brightness, uint8_t& red, uint8_t& green, uint8_t& blue);
void apply(uint64_t input, uint8_t brightness, uint64_t& red, uint64_t& green, uint64_t& blue) const;

ColorRgb getAdjustment() const;
void setAdjustment(const QJsonArray& value);
Expand Down
23 changes: 23 additions & 0 deletions sources/base/Grabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ Grabber::Grabber(const QString& configurationPath, const QString& grabberName)
, _actualFPS(0)
, _actualDeviceName("")
, _targetMonitorNits(200)
, _reorderDisplays(0)
, _lineLength(-1)
, _frameByteSize(-1)
, _signalDetectionEnabled(false)
Expand Down Expand Up @@ -184,6 +185,28 @@ void Grabber::setMonitorNits(int nits)
}
}

void Grabber::setReorderDisplays(int order)
{
if (_reorderDisplays != order)
{
_reorderDisplays = order;

Debug(_log, "Set re-order display permutation to %i", _reorderDisplays);

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

void Grabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
{
if (_width > 0 && _height > 0)
Expand Down
2 changes: 2 additions & 0 deletions sources/base/SystemWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,8 @@ void SystemWrapper::handleSettingsUpdate(settings::type type, const QJsonDocumen

_grabber->setMonitorNits(obj["monitor_nits"].toInt(200));

_grabber->setReorderDisplays(obj["reorder_displays"].toInt(0));

_grabber->setSignalDetectionOffset(
obj["sDHOffsetMin"].toDouble(0.25),
obj["sDVOffsetMin"].toDouble(0.25),
Expand Down
16 changes: 16 additions & 0 deletions sources/base/schema/schema-systemGrabber.json
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,22 @@
},
"propertyOrder" : 25
},
"reorder_displays" :
{
"type" : "integer",
"format": "stepper",
"title" : "edt_conf_reorder_displays_title",
"default" : 0,
"minimum" : 0,
"maximum" : 255,
"required" : true,
"options": {
"dependencies": {
"hardware": true
}
},
"propertyOrder" : 26
},
"cropLeft" :
{
"type" : "integer",
Expand Down
30 changes: 28 additions & 2 deletions sources/grabber/windows/DX/DxGrabber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*/
#define NOMINMAX

#include <algorithm>
#include <iostream>
#include <sstream>
#include <stdexcept>
Expand Down Expand Up @@ -779,6 +780,11 @@ void DxGrabber::grabFrame()
int targetSizeX = 0, targetSizeY = 0;
int divide = getTargetSystemFrameDimension(display->actualWidth, display->actualHeight, targetSizeX, targetSizeY);

if (_reorderDisplays > 0 && result == 0)
{
images.push_back(std::pair<int, Image<ColorRgb>>(width, Image<ColorRgb>(targetSizeX, 1)));
}

width += targetSizeX;
height = std::max(targetSizeY, height);
}
Expand All @@ -800,11 +806,31 @@ void DxGrabber::grabFrame()
memset(image.rawMem(), 0, image.size());
}

for (auto&& source : images)
if (_reorderDisplays > 0)
{
image.insertHorizontal(source.first, source.second);
for (int permutation = 0;
permutation < _reorderDisplays &&
std::next_permutation(images.begin(), images.end(),
[=](const std::pair<int, Image<ColorRgb>>& a, const std::pair<int, Image<ColorRgb>>& b)
{
return a.first < b.first;
});
permutation++);

int targetX = 0;
for (auto it = images.begin(); it != images.end(); ++it)
{
it->first = targetX;
targetX += it->second.width();
}
}

for (auto&& source : images)
if (_reorderDisplays == 0 || source.second.height() > 1)
{
image.insertHorizontal(source.first, source.second);
}

if (_signalDetectionEnabled)
{
if (checkSignalDetectionManual(image))
Expand Down
10 changes: 5 additions & 5 deletions sources/led-strip/ChannelCalibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ bool ChannelCalibration::isEnabled() const
return _enabled;
}

void ChannelCalibration::apply(uint8_t input, uint8_t brightness, uint8_t& red, uint8_t& green, uint8_t& blue)
{
red = std::min(((brightness * input * _targetCalibration.red) / 65025), (int)UINT8_MAX);
green = std::min(((brightness * input * _targetCalibration.green) / 65025), (int)UINT8_MAX);
blue = std::min(((brightness * input * _targetCalibration.blue) / 65025), (int)UINT8_MAX);
void ChannelCalibration::apply(uint64_t input, uint8_t brightness, uint64_t& red, uint64_t& green, uint64_t& blue) const
{
red = (brightness * input * _targetCalibration.red + (65025 / 2)) / 65025;
green = (brightness * input * _targetCalibration.green + (65025 / 2)) / 65025;
blue = (brightness * input * _targetCalibration.blue + (65025 / 2)) / 65025;
}
32 changes: 16 additions & 16 deletions sources/led-strip/ColorCalibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ void ColorCalibration::calibrate(ColorRgb& color)
{
if (B_RGB != 255)
{
color.red = ((uint32_t)color.red * B_RGB) / 255;
color.green = ((uint32_t)color.green * B_RGB) / 255;
color.blue = ((uint32_t)color.blue * B_RGB) / 255;
color.red = ((uint32_t)color.red * B_RGB + (255 / 2)) / 255;
color.green = ((uint32_t)color.green * B_RGB + (255 / 2)) / 255;
color.blue = ((uint32_t)color.blue * B_RGB + (255 / 2)) / 255;
}
}
else
Expand All @@ -121,17 +121,17 @@ void ColorCalibration::calibrate(ColorRgb& color)
uint32_t nrg = (uint32_t)(255 - ored) * (ogreen);
uint32_t rg = (uint32_t)(ored) * (ogreen);

uint8_t black = nrng * (255 - oblue) / 65025;
uint8_t red = rng * (255 - oblue) / 65025;
uint8_t green = nrg * (255 - oblue) / 65025;
uint8_t blue = nrng * (oblue) / 65025;
uint8_t cyan = nrg * (oblue) / 65025;
uint8_t magenta = rng * (oblue) / 65025;
uint8_t yellow = rg * (255 - oblue) / 65025;
uint8_t white = rg * (oblue) / 65025;
uint32_t black = nrng * (255 - oblue);
uint32_t red = rng * (255 - oblue);
uint32_t green = nrg * (255 - oblue);
uint32_t blue = nrng * (oblue);
uint32_t cyan = nrg * (oblue);
uint32_t magenta = rng * (oblue);
uint32_t yellow = rg * (255 - oblue);
uint32_t white = rg * (oblue);

uint8_t OR, OG, OB, RR, RG, RB, GR, GG, GB, BR, BG, BB;
uint8_t CR, CG, CB, MR, MG, MB, YR, YG, YB, WR, WG, WB;
uint64_t OR, OG, OB, RR, RG, RB, GR, GG, GB, BR, BG, BB;
uint64_t CR, CG, CB, MR, MG, MB, YR, YG, YB, WR, WG, WB;

_blackCalibration->apply(black, 255, OR, OG, OB);
_redCalibration->apply(red, B_RGB, RR, RG, RB);
Expand All @@ -142,9 +142,9 @@ void ColorCalibration::calibrate(ColorRgb& color)
_yellowCalibration->apply(yellow, B_CMY, YR, YG, YB);
_whiteCalibration->apply(white, B_W, WR, WG, WB);

color.red = OR + RR + GR + BR + CR + MR + YR + WR;
color.green = OG + RG + GG + BG + CG + MG + YG + WG;
color.blue = OB + RB + GB + BB + CB + MB + YB + WB;
color.red = std::min((OR + RR + GR + BR + CR + MR + YR + WR + (65025 / 2)) / 65025, (uint64_t) 255);
color.green = std::min((OG + RG + GG + BG + CG + MG + YG + WG + (65025 / 2)) / 65025, (uint64_t) 255);
color.blue = std::min((OB + RB + GB + BB + CB + MB + YB + WB + (65025 / 2)) / 65025, (uint64_t) 255);
}
}
_colorspaceCalibration->applyBacklight(ored, ogreen, oblue);
Expand Down
4 changes: 3 additions & 1 deletion www/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1267,5 +1267,7 @@
"wiz_home_assistant_title": "Home Assistant lights wizard",
"wiz_ha_intro": "Please select the address of the Home Assistant instance and enter the 'Long Lived Access Tokens' created there.",
"select_ha_intro": "Select Home Assistant",
"edt_dev_spec_constantBrightness_title": "Constant brightness"
"edt_dev_spec_constantBrightness_title": "Constant brightness",
"edt_conf_reorder_displays_title": "Reorder displays",
"edt_conf_reorder_displays_expl": "Manipulate the order (permutations) of the displays until you get the correct one in multi-display mode"
}
Loading