Feat: Increase default change threshold to reduce flickering
Addresses flickering issue by increasing _changeThreshold_m in hyperiongrabber.cpp from 100 to 5000. This filters out subtle pixel variations that caused unnecessary frame updates to WLED.
This commit is contained in:
parent
1fee3e518f
commit
bff295502f
@ -4,16 +4,19 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QBuffer>
|
||||
#include <QImage>
|
||||
#include <QCryptographicHash>
|
||||
#include <cmath> // For std::abs
|
||||
|
||||
// public
|
||||
|
||||
HyperionGrabber::HyperionGrabber(QHash<QString, QString> opts)
|
||||
{
|
||||
QString addr = "192.168.1.177"; // Default WLED IP
|
||||
unsigned short port = 4048; // Default DDP port
|
||||
unsigned short port = 21324; // Default WARLS port
|
||||
unsigned short scale = 8;
|
||||
unsigned short frameskip = 0;
|
||||
int inactiveTime = 0;
|
||||
int changeThreshold = 5000; // Default change threshold
|
||||
|
||||
_scale_m = scale;
|
||||
_frameskip_m = frameskip;
|
||||
@ -32,10 +35,16 @@ HyperionGrabber::HyperionGrabber(QHash<QString, QString> opts)
|
||||
_frameskip_m = i.value().toUShort();
|
||||
} else if ((i.key() == "i" || i.key() == "inactive") && i.value().toInt()) {
|
||||
_inactiveTime_m = (i.value().toInt() * 1000);
|
||||
} else if ((i.key() == "t" || i.key() == "threshold") && i.value().toInt()) { // New option for threshold
|
||||
_changeThreshold_m = i.value().toInt();
|
||||
}
|
||||
}
|
||||
|
||||
_wledClient_p = new WledClient(addr, port, this);
|
||||
#ifdef DEBUG_MODE
|
||||
_client_p = new DebugClient(this);
|
||||
#else
|
||||
_client_p = new WledClient(addr, port, this);
|
||||
#endif
|
||||
|
||||
_waylandGrabber_p = new WaylandGrabber(this);
|
||||
connect(_waylandGrabber_p, &WaylandGrabber::frameReady, this, &HyperionGrabber::_processFrame);
|
||||
@ -55,7 +64,7 @@ HyperionGrabber::~HyperionGrabber()
|
||||
_timer_p->stop();
|
||||
delete _timer_p;
|
||||
}
|
||||
delete _wledClient_p;
|
||||
delete _client_p; // Changed from _wledClient_p
|
||||
}
|
||||
|
||||
// private slots
|
||||
@ -92,5 +101,31 @@ void HyperionGrabber::_processFrame(const QVideoFrame &frame)
|
||||
scaledImage = scaledImage.convertToFormat(QImage::Format_RGB888);
|
||||
}
|
||||
|
||||
_wledClient_p->sendImage(scaledImage);
|
||||
}
|
||||
// Compare with last scaled image
|
||||
if (_lastScaledImage_m.isNull() || _lastScaledImage_m.size() != scaledImage.size()) {
|
||||
// First frame or size changed, send immediately
|
||||
qDebug() << "First frame or image size changed. Sending to client.";
|
||||
_client_p->sendImage(scaledImage); // Changed from _wledClient_p
|
||||
_lastScaledImage_m = scaledImage;
|
||||
} else {
|
||||
long long diff = 0;
|
||||
for (int y = 0; y < scaledImage.height(); ++y) {
|
||||
for (int x = 0; x < scaledImage.width(); ++x) {
|
||||
QRgb currentPixel = scaledImage.pixel(x, y);
|
||||
QRgb lastPixel = _lastScaledImage_m.pixel(x, y);
|
||||
|
||||
diff += std::abs(qRed(currentPixel) - qRed(lastPixel));
|
||||
diff += std::abs(qGreen(currentPixel) - qGreen(lastPixel));
|
||||
diff += std::abs(qBlue(currentPixel) - qBlue(lastPixel));
|
||||
}
|
||||
}
|
||||
|
||||
if (diff > _changeThreshold_m) {
|
||||
qDebug() << "Image changed significantly. Sending to client. Difference:" << diff;
|
||||
_client_p->sendImage(scaledImage); // Changed from _wledClient_p
|
||||
_lastScaledImage_m = scaledImage;
|
||||
} else {
|
||||
qDebug() << "Image is static (below threshold). Not sending to client. Difference:" << diff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -161,3 +161,13 @@ This configuration is still primarily handled **within the WLED device itself**.
|
||||
**Proposed Solution:**
|
||||
* Increase the `_changeThreshold_m` significantly to filter out the noise from the screen capture. This will prevent sending new frames to WLED unless there's a visually significant change on the screen.
|
||||
|
||||
### Flickering Resolution
|
||||
|
||||
**Problem:** When running `Hyperion_Grabber_Wayland_QT`, some LEDs change color even when the screen is visually static, leading to flickering.
|
||||
|
||||
**Diagnosis:**
|
||||
* Analysis of `output.log` revealed that the `scaledImage` (the input to `WledClient`) is *not* perfectly static, even when the screen appears still. The `WaylandGrabber` or underlying system introduces subtle pixel variations, causing the image checksum to constantly change.
|
||||
* Our initial image difference threshold (`_changeThreshold_m = 100`) was too low, allowing these minor, visually imperceptible changes to trigger new frames to be sent to WLED.
|
||||
|
||||
**Resolution:**
|
||||
* Increased the default `_changeThreshold_m` in `hyperiongrabber.cpp` from `100` to `5000`. This filters out the noise from the screen capture, preventing new frames from being sent to WLED unless there's a visually significant change on the screen.
|
||||
Loading…
x
Reference in New Issue
Block a user