4949#include < boblightserver/BoblightServer.h>
5050#endif
5151
52+ // Constants
53+ namespace {
54+ constexpr std::chrono::milliseconds DEFAULT_MAX_IMAGE_EMISSION_INTERVAL{ 40 }; // 25 Hz
55+ constexpr std::chrono::milliseconds DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL{ 25 }; // 40 Hz
56+ constexpr std::chrono::milliseconds DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL{ 5 }; // 200 Hz
57+ } // End of constants
58+
5259Hyperion::Hyperion (quint8 instance)
5360 : QObject()
5461 , _instIndex(instance)
@@ -75,6 +82,12 @@ Hyperion::Hyperion(quint8 instance)
7582#if defined(ENABLE_BOBLIGHT_SERVER)
7683 , _boblightServer(nullptr )
7784#endif
85+ , _lastImageEmission(0 )
86+ , _lastRawLedDataEmission(0 )
87+ , _lastLedDeviceDataEmission(0 )
88+ , _imageEmissionInterval(DEFAULT_MAX_IMAGE_EMISSION_INTERVAL)
89+ , _rawLedDataEmissionInterval(DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL)
90+ , _ledDeviceDataEmissionInterval(DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL)
7891{
7992 qRegisterMetaType<ComponentList>(" ComponentList" );
8093
@@ -109,6 +122,8 @@ void Hyperion::start()
109122 // handle hwLedCount
110123 _hwLedCount = getSetting (settings::DEVICE).object ()[" hardwareLedCount" ].toInt (getLedCount ());
111124
125+
126+
112127 // Initialize colororder vector
113128 for (const Led& led : _ledString.leds ())
114129 {
@@ -180,6 +195,15 @@ void Hyperion::start()
180195 connect (GlobalSignals::getInstance (), &GlobalSignals::setGlobalColor, this , &Hyperion::setColor);
181196 connect (GlobalSignals::getInstance (), &GlobalSignals::setGlobalImage, this , &Hyperion::setInputImage);
182197
198+ // Limit LED data emission, if high rumber of LEDs configured
199+ _rawLedDataEmissionInterval = (_ledString.leds ().size () > 1000 ) ? 2 * DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL : DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL;
200+ _ledDeviceDataEmissionInterval = (_hwLedCount > 1000 ) ? 2 * DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL : DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL;
201+
202+ // Set up timers to throttle specific signals
203+ _imageTimer.start (); // Start the elapsed timer for image signal throttling
204+ _rawLedDataTimer.start (); // Start the elapsed timer for rawLedColors throttling
205+ _ledDeviceDataTimer.start (); // Start the elapsed timer for LED-Device data throttling
206+
183207 // if there is no startup / background effect and no sending capture interface we probably want to push once BLACK (as PrioMuxer won't emit a priority change)
184208 update ();
185209
@@ -267,6 +291,7 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
267291 std::vector<ColorRgb> color (_ledString.leds ().size (), ColorRgb{0 ,0 ,0 });
268292 _ledBuffer = color;
269293
294+
270295 _ledStringColorOrder.clear ();
271296 for (const Led& led : _ledString.leds ())
272297 {
@@ -276,6 +301,10 @@ void Hyperion::handleSettingsUpdate(settings::type type, const QJsonDocument& co
276301 // handle hwLedCount update
277302 _hwLedCount = getSetting (settings::DEVICE).object ()[" hardwareLedCount" ].toInt (getLedCount ());
278303
304+ // Limit LED data emission, if high rumber of LEDs configured
305+ _rawLedDataEmissionInterval = (_ledString.leds ().size () > 1000 ) ? 2 * DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL : DEFAULT_MAX_RAW_LED_DATA_EMISSION_INTERVAL;
306+ _ledDeviceDataEmissionInterval = (_hwLedCount > 1000 ) ? 2 * DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL : DEFAULT_MAX_LED_DEVICE_DATA_EMISSION_INTERVAL;
307+
279308 // change in leds are also reflected in adjustment
280309 delete _raw2ledAdjustment;
281310 _raw2ledAdjustment = hyperion::createLedColorsAdjustment (static_cast <int >(_ledString.leds ().size ()), getSetting (settings::COLOR).object ());
@@ -672,7 +701,14 @@ void Hyperion::update()
672701 Image<ColorRgb> image = priorityInfo.image ;
673702 if (image.width () > 1 || image.height () > 1 )
674703 {
675- emit currentImage (image);
704+ _imageEmissionInterval = (image.width () > 1280 ) ? 2 * DEFAULT_MAX_IMAGE_EMISSION_INTERVAL : DEFAULT_MAX_IMAGE_EMISSION_INTERVAL;
705+ // Throttle the emission of currentImage(image) signal
706+ qint64 elapsedImageEmissionTime = _imageTimer.elapsed ();
707+ if (elapsedImageEmissionTime - _lastImageEmission >= _imageEmissionInterval.count ())
708+ {
709+ _lastImageEmission = elapsedImageEmissionTime;
710+ emit currentImage (image); // Emit the image signal at the controlled rate
711+ }
676712 _ledBuffer = _imageProcessor->process (image);
677713 }
678714 else
@@ -692,9 +728,15 @@ void Hyperion::update()
692728 }
693729 }
694730
695- // emit rawLedColors before transform
696- emit rawLedColors (_ledBuffer);
731+ // Throttle the emission of rawLedColors(_ledBuffer) signal
732+ qint64 elapsedRawLedDataEmissionTime = _rawLedDataTimer.elapsed ();
733+ if (elapsedRawLedDataEmissionTime - _lastRawLedDataEmission >= _rawLedDataEmissionInterval.count ())
734+ {
735+ _lastRawLedDataEmission = elapsedRawLedDataEmissionTime;
736+ emit rawLedColors (_ledBuffer); // Emit the rawLedColors signal at the controlled rate
737+ }
697738
739+ // Start transformations
698740 _raw2ledAdjustment->applyAdjustment (_ledBuffer);
699741
700742 int i = 0 ;
@@ -740,7 +782,13 @@ void Hyperion::update()
740782 // Smoothing is disabled
741783 if (! _deviceSmooth->enabled ())
742784 {
743- emit ledDeviceData (_ledBuffer);
785+ // Throttle the emission of LED-Device data signal
786+ qint64 elapsedLedDeviceDataEmissionTime = _ledDeviceDataTimer.elapsed ();
787+ if (elapsedLedDeviceDataEmissionTime - _lastLedDeviceDataEmission >= _ledDeviceDataEmissionInterval.count ())
788+ {
789+ _lastLedDeviceDataEmission = elapsedLedDeviceDataEmissionTime;
790+ emit ledDeviceData (_ledBuffer);
791+ }
744792 }
745793 else
746794 {
0 commit comments