Skip to content

Commit c24549c

Browse files
authored
Feature to re-order displays in multi-display mode (#1023)
1 parent 65b0718 commit c24549c

File tree

9 files changed

+97
-25
lines changed

9 files changed

+97
-25
lines changed

Diff for: include/base/Grabber.h

+3
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ class Grabber : public DetectionAutomatic, public DetectionManual, protected Lut
8686

8787
void setMonitorNits(int nits);
8888

89+
void setReorderDisplays(int order);
90+
8991
void setFpsSoftwareDecimation(int decimation) override;
9092

9193
int getFpsSoftwareDecimation() override;
@@ -269,6 +271,7 @@ public slots:
269271
int _actualWidth, _actualHeight, _actualFPS;
270272
QString _actualDeviceName;
271273
uint _targetMonitorNits;
274+
int _reorderDisplays;
272275

273276
int _lineLength;
274277
int _frameByteSize;

Diff for: include/led-strip/ChannelCalibration.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class ChannelCalibration
4444
public:
4545
ChannelCalibration(quint8 instance, QString channelName, const QJsonObject& colorConfig, int defaultR, int defaultG, int defaultB);
4646

47-
void apply(uint8_t input, uint8_t brightness, uint8_t& red, uint8_t& green, uint8_t& blue);
47+
void apply(uint64_t input, uint8_t brightness, uint64_t& red, uint64_t& green, uint64_t& blue) const;
4848

4949
ColorRgb getAdjustment() const;
5050
void setAdjustment(const QJsonArray& value);

Diff for: sources/base/Grabber.cpp

+23
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ Grabber::Grabber(const QString& configurationPath, const QString& grabberName)
7474
, _actualFPS(0)
7575
, _actualDeviceName("")
7676
, _targetMonitorNits(200)
77+
, _reorderDisplays(0)
7778
, _lineLength(-1)
7879
, _frameByteSize(-1)
7980
, _signalDetectionEnabled(false)
@@ -184,6 +185,28 @@ void Grabber::setMonitorNits(int nits)
184185
}
185186
}
186187

188+
void Grabber::setReorderDisplays(int order)
189+
{
190+
if (_reorderDisplays != order)
191+
{
192+
_reorderDisplays = order;
193+
194+
Debug(_log, "Set re-order display permutation to %i", _reorderDisplays);
195+
196+
if (_initialized && !_blocked)
197+
{
198+
Debug(_log, "Restarting video grabber");
199+
uninit();
200+
start();
201+
}
202+
else
203+
{
204+
Info(_log, "Delayed restart of the grabber due to change of monitor display-order value");
205+
_restartNeeded = true;
206+
}
207+
}
208+
}
209+
187210
void Grabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
188211
{
189212
if (_width > 0 && _height > 0)

Diff for: sources/base/SystemWrapper.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,8 @@ void SystemWrapper::handleSettingsUpdate(settings::type type, const QJsonDocumen
169169

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

172+
_grabber->setReorderDisplays(obj["reorder_displays"].toInt(0));
173+
172174
_grabber->setSignalDetectionOffset(
173175
obj["sDHOffsetMin"].toDouble(0.25),
174176
obj["sDVOffsetMin"].toDouble(0.25),

Diff for: sources/base/schema/schema-systemGrabber.json

+16
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,22 @@
7171
},
7272
"propertyOrder" : 25
7373
},
74+
"reorder_displays" :
75+
{
76+
"type" : "integer",
77+
"format": "stepper",
78+
"title" : "edt_conf_reorder_displays_title",
79+
"default" : 0,
80+
"minimum" : 0,
81+
"maximum" : 255,
82+
"required" : true,
83+
"options": {
84+
"dependencies": {
85+
"hardware": true
86+
}
87+
},
88+
"propertyOrder" : 26
89+
},
7490
"cropLeft" :
7591
{
7692
"type" : "integer",

Diff for: sources/grabber/windows/DX/DxGrabber.cpp

+28-2
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
*/
2727
#define NOMINMAX
2828

29+
#include <algorithm>
2930
#include <iostream>
3031
#include <sstream>
3132
#include <stdexcept>
@@ -779,6 +780,11 @@ void DxGrabber::grabFrame()
779780
int targetSizeX = 0, targetSizeY = 0;
780781
int divide = getTargetSystemFrameDimension(display->actualWidth, display->actualHeight, targetSizeX, targetSizeY);
781782

783+
if (_reorderDisplays > 0 && result == 0)
784+
{
785+
images.push_back(std::pair<int, Image<ColorRgb>>(width, Image<ColorRgb>(targetSizeX, 1)));
786+
}
787+
782788
width += targetSizeX;
783789
height = std::max(targetSizeY, height);
784790
}
@@ -800,11 +806,31 @@ void DxGrabber::grabFrame()
800806
memset(image.rawMem(), 0, image.size());
801807
}
802808

803-
for (auto&& source : images)
809+
if (_reorderDisplays > 0)
804810
{
805-
image.insertHorizontal(source.first, source.second);
811+
for (int permutation = 0;
812+
permutation < _reorderDisplays &&
813+
std::next_permutation(images.begin(), images.end(),
814+
[=](const std::pair<int, Image<ColorRgb>>& a, const std::pair<int, Image<ColorRgb>>& b)
815+
{
816+
return a.first < b.first;
817+
});
818+
permutation++);
819+
820+
int targetX = 0;
821+
for (auto it = images.begin(); it != images.end(); ++it)
822+
{
823+
it->first = targetX;
824+
targetX += it->second.width();
825+
}
806826
}
807827

828+
for (auto&& source : images)
829+
if (_reorderDisplays == 0 || source.second.height() > 1)
830+
{
831+
image.insertHorizontal(source.first, source.second);
832+
}
833+
808834
if (_signalDetectionEnabled)
809835
{
810836
if (checkSignalDetectionManual(image))

Diff for: sources/led-strip/ChannelCalibration.cpp

+5-5
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,9 @@ bool ChannelCalibration::isEnabled() const
118118
return _enabled;
119119
}
120120

121-
void ChannelCalibration::apply(uint8_t input, uint8_t brightness, uint8_t& red, uint8_t& green, uint8_t& blue)
122-
{
123-
red = std::min(((brightness * input * _targetCalibration.red) / 65025), (int)UINT8_MAX);
124-
green = std::min(((brightness * input * _targetCalibration.green) / 65025), (int)UINT8_MAX);
125-
blue = std::min(((brightness * input * _targetCalibration.blue) / 65025), (int)UINT8_MAX);
121+
void ChannelCalibration::apply(uint64_t input, uint8_t brightness, uint64_t& red, uint64_t& green, uint64_t& blue) const
122+
{
123+
red = (brightness * input * _targetCalibration.red + (65025 / 2)) / 65025;
124+
green = (brightness * input * _targetCalibration.green + (65025 / 2)) / 65025;
125+
blue = (brightness * input * _targetCalibration.blue + (65025 / 2)) / 65025;
126126
}

Diff for: sources/led-strip/ColorCalibration.cpp

+16-16
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,9 @@ void ColorCalibration::calibrate(ColorRgb& color)
109109
{
110110
if (B_RGB != 255)
111111
{
112-
color.red = ((uint32_t)color.red * B_RGB) / 255;
113-
color.green = ((uint32_t)color.green * B_RGB) / 255;
114-
color.blue = ((uint32_t)color.blue * B_RGB) / 255;
112+
color.red = ((uint32_t)color.red * B_RGB + (255 / 2)) / 255;
113+
color.green = ((uint32_t)color.green * B_RGB + (255 / 2)) / 255;
114+
color.blue = ((uint32_t)color.blue * B_RGB + (255 / 2)) / 255;
115115
}
116116
}
117117
else
@@ -121,17 +121,17 @@ void ColorCalibration::calibrate(ColorRgb& color)
121121
uint32_t nrg = (uint32_t)(255 - ored) * (ogreen);
122122
uint32_t rg = (uint32_t)(ored) * (ogreen);
123123

124-
uint8_t black = nrng * (255 - oblue) / 65025;
125-
uint8_t red = rng * (255 - oblue) / 65025;
126-
uint8_t green = nrg * (255 - oblue) / 65025;
127-
uint8_t blue = nrng * (oblue) / 65025;
128-
uint8_t cyan = nrg * (oblue) / 65025;
129-
uint8_t magenta = rng * (oblue) / 65025;
130-
uint8_t yellow = rg * (255 - oblue) / 65025;
131-
uint8_t white = rg * (oblue) / 65025;
124+
uint32_t black = nrng * (255 - oblue);
125+
uint32_t red = rng * (255 - oblue);
126+
uint32_t green = nrg * (255 - oblue);
127+
uint32_t blue = nrng * (oblue);
128+
uint32_t cyan = nrg * (oblue);
129+
uint32_t magenta = rng * (oblue);
130+
uint32_t yellow = rg * (255 - oblue);
131+
uint32_t white = rg * (oblue);
132132

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

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

145-
color.red = OR + RR + GR + BR + CR + MR + YR + WR;
146-
color.green = OG + RG + GG + BG + CG + MG + YG + WG;
147-
color.blue = OB + RB + GB + BB + CB + MB + YB + WB;
145+
color.red = std::min((OR + RR + GR + BR + CR + MR + YR + WR + (65025 / 2)) / 65025, (uint64_t) 255);
146+
color.green = std::min((OG + RG + GG + BG + CG + MG + YG + WG + (65025 / 2)) / 65025, (uint64_t) 255);
147+
color.blue = std::min((OB + RB + GB + BB + CB + MB + YB + WB + (65025 / 2)) / 65025, (uint64_t) 255);
148148
}
149149
}
150150
_colorspaceCalibration->applyBacklight(ored, ogreen, oblue);

Diff for: www/i18n/en.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -1267,5 +1267,7 @@
12671267
"wiz_home_assistant_title": "Home Assistant lights wizard",
12681268
"wiz_ha_intro": "Please select the address of the Home Assistant instance and enter the 'Long Lived Access Tokens' created there.",
12691269
"select_ha_intro": "Select Home Assistant",
1270-
"edt_dev_spec_constantBrightness_title": "Constant brightness"
1270+
"edt_dev_spec_constantBrightness_title": "Constant brightness",
1271+
"edt_conf_reorder_displays_title": "Reorder displays",
1272+
"edt_conf_reorder_displays_expl": "Manipulate the order (permutations) of the displays until you get the correct one in multi-display mode"
12711273
}

0 commit comments

Comments
 (0)