diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a2f1d8e..2dc566ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ Note: The wizard will configure an APIv2 capable bridge always with Entertainmen - MDNSBrower - Fixed, if timeout while resolving host occurs - Non image updates ignored blacklisted LEDs (#1634) - Fixed that Windows OsEvents failed in non-GUI mode (#1671) +- Addressed serious (#1425) and some smaller memory leaks ##### LED-Devices diff --git a/include/blackborder/BlackBorderProcessor.h b/include/blackborder/BlackBorderProcessor.h index 96db3dbf..ce372bf1 100644 --- a/include/blackborder/BlackBorderProcessor.h +++ b/include/blackborder/BlackBorderProcessor.h @@ -1,4 +1,7 @@ -#pragma once +#ifndef BLACK_BORDER_PROCESSOR_H +#define BLACK_BORDER_PROCESSOR_H + +#include // QT includes #include @@ -24,7 +27,7 @@ namespace hyperion Q_OBJECT public: BlackBorderProcessor(Hyperion* hyperion, QObject* parent); - ~BlackBorderProcessor() override; + /// /// Return the current (detected) border /// @return The current border @@ -141,7 +144,7 @@ namespace hyperion QString _detectionMode; /// The black-border detector - BlackBorderDetector* _detector; + std::unique_ptr _detector; /// The current detected border BlackBorder _currentBorder; @@ -162,3 +165,5 @@ namespace hyperion }; } // end namespace hyperion + +#endif // BLACK_BORDER_PROCESSOR_H diff --git a/include/commandline/ValidatorOption.h b/include/commandline/ValidatorOption.h index ae618fa5..5bbacec2 100644 --- a/include/commandline/ValidatorOption.h +++ b/include/commandline/ValidatorOption.h @@ -36,6 +36,11 @@ public: : Option(other), validator(validator) {} + ~ValidatorOption() + { + delete validator; + } + virtual const QValidator *getValidator() const; virtual bool validate(Parser & parser, QString &value) override; }; diff --git a/include/grabber/qt/QtGrabber.h b/include/grabber/qt/QtGrabber.h index f04d8eca..dec3b883 100644 --- a/include/grabber/qt/QtGrabber.h +++ b/include/grabber/qt/QtGrabber.h @@ -113,8 +113,8 @@ private: int _display; int _numberOfSDisplays; - int _calculatedWidth; - int _calculatedHeight; + int _screenWidth; + int _screenHeight; int _src_x; int _src_y; int _src_x_max; diff --git a/include/grabber/x11/X11Grabber.h b/include/grabber/x11/X11Grabber.h index 308af5e8..99d4e9af 100644 --- a/include/grabber/x11/X11Grabber.h +++ b/include/grabber/x11/X11Grabber.h @@ -57,7 +57,7 @@ public: /// /// @brief Apply new width/height values, overwrite Grabber.h implementation as X11 doesn't use width/height, just pixelDecimation to calc dimensions /// - bool setWidthHeight(int width, int height) override { return true; } + bool setWidthHeight(int /*width*/, int /*height*/) override { return true; } /// /// @brief Apply new pixelDecimation @@ -109,19 +109,19 @@ private: Picture _srcPicture; Picture _dstPicture; - int _XRandREventBase; + int _xRandREventBase; XTransform _transform; - unsigned _calculatedWidth; - unsigned _calculatedHeight; - unsigned _src_x; - unsigned _src_y; + int _screenWidth; + int _screenHeight; + int _src_x; + int _src_y; - bool _XShmAvailable; - bool _XShmPixmapAvailable; - bool _XRenderAvailable; - bool _XRandRAvailable; + bool _xShmAvailable; + bool _xShmPixmapAvailable; + bool _xRenderAvailable; + bool _xRandRAvailable; bool _isWayland; Logger * _logger; diff --git a/include/hyperion/BGEffectHandler.h b/include/hyperion/BGEffectHandler.h index 96de909b..f3ee8087 100644 --- a/include/hyperion/BGEffectHandler.h +++ b/include/hyperion/BGEffectHandler.h @@ -43,6 +43,16 @@ public: handleSettingsUpdate(settings::BGEFFECT, _hyperion->getSetting(settings::BGEFFECT)); } + /// + /// @brief Disconnect from connected signals + /// Disconnect should be done before other priorities invoke methods during shutdown + /// + void disconnect() + { + QObject::disconnect(_prioMuxer, &PriorityMuxer::prioritiesChanged, nullptr, nullptr); + QObject::disconnect(_hyperion, nullptr, nullptr, nullptr); + } + /// /// @brief Check, if background effect processing is enabled. /// @return True, background effect processing is enabled. diff --git a/include/hyperion/ColorAdjustment.h b/include/hyperion/ColorAdjustment.h index 3e9b8dc8..2d846fd7 100644 --- a/include/hyperion/ColorAdjustment.h +++ b/include/hyperion/ColorAdjustment.h @@ -16,21 +16,21 @@ public: QString _id; /// The BLACK (RGB-Channel) adjustment - RgbChannelAdjustment _rgbBlackAdjustment; + RgbChannelAdjustment _rgbBlackAdjustment {0, 0, 0, "black"}; /// The WHITE (RGB-Channel) adjustment - RgbChannelAdjustment _rgbWhiteAdjustment; + RgbChannelAdjustment _rgbWhiteAdjustment{255, 255, 255, "white"}; /// The RED (RGB-Channel) adjustment - RgbChannelAdjustment _rgbRedAdjustment; + RgbChannelAdjustment _rgbRedAdjustment {255, 0, 0 , "red"}; /// The GREEN (RGB-Channel) adjustment - RgbChannelAdjustment _rgbGreenAdjustment; + RgbChannelAdjustment _rgbGreenAdjustment {0, 255, 0, "green"}; /// The BLUE (RGB-Channel) adjustment - RgbChannelAdjustment _rgbBlueAdjustment; + RgbChannelAdjustment _rgbBlueAdjustment {0, 0, 255, "blue"}; /// The CYAN (RGB-Channel) adjustment - RgbChannelAdjustment _rgbCyanAdjustment; + RgbChannelAdjustment _rgbCyanAdjustment {0, 255, 255, "cyan"}; /// The MAGENTA (RGB-Channel) adjustment - RgbChannelAdjustment _rgbMagentaAdjustment; + RgbChannelAdjustment _rgbMagentaAdjustment {255, 0, 255, "magenta"}; /// The YELLOW (RGB-Channel) adjustment - RgbChannelAdjustment _rgbYellowAdjustment; + RgbChannelAdjustment _rgbYellowAdjustment {255, 255, 0, "yellow"}; RgbTransform _rgbTransform; OkhsvTransform _okhsvTransform; diff --git a/include/hyperion/GrabberWrapper.h b/include/hyperion/GrabberWrapper.h index 5254c011..e517b013 100644 --- a/include/hyperion/GrabberWrapper.h +++ b/include/hyperion/GrabberWrapper.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include @@ -91,8 +92,8 @@ public: template bool transferFrame(Grabber_T &grabber) { - unsigned w = grabber.getImageWidth(); - unsigned h = grabber.getImageHeight(); + int w = grabber.getImageWidth(); + int h = grabber.getImageHeight(); if ( _image.width() != w || _image.height() != h) { _image.resize(w, h); @@ -185,7 +186,7 @@ protected: Logger * _log; /// The timer for generating events with the specified update rate - QTimer* _timer; + QScopedPointer _timer; /// The calculated update rate [ms] int _updateInterval_ms; diff --git a/include/mdns/MdnsBrowser.h b/include/mdns/MdnsBrowser.h index 7ee8009f..a5071b13 100644 --- a/include/mdns/MdnsBrowser.h +++ b/include/mdns/MdnsBrowser.h @@ -2,7 +2,6 @@ #define MDNS_BROWSER_H #include -#include #include #include @@ -16,6 +15,9 @@ // Qt includes #include #include +#include +#include +#include // Utility includes #include @@ -24,15 +26,12 @@ namespace { constexpr std::chrono::milliseconds DEFAULT_DISCOVER_TIMEOUT{ 500 }; constexpr std::chrono::milliseconds DEFAULT_ADDRESS_RESOLVE_TIMEOUT{ 1000 }; - -} //End of constants +} // End of constants class MdnsBrowser : public QObject { Q_OBJECT - // Run MdnsBrowser as singleton - private: /// /// @brief Browse for hyperion services in bonjour, constructed from HyperionDaemon @@ -58,7 +57,6 @@ public: QMdnsEngine::Service getFirstService(const QByteArray& serviceType, const QString& filter = ".*", const std::chrono::milliseconds waitTime = DEFAULT_DISCOVER_TIMEOUT) const; QJsonArray getServicesDiscoveredJson(const QByteArray& serviceType, const QString& filter = ".*", const std::chrono::milliseconds waitTime = std::chrono::milliseconds{ 0 }) const; - void printCache(const QByteArray& name = QByteArray(), quint16 type = QMdnsEngine::ANY) const; public slots: @@ -109,8 +107,9 @@ private: QMdnsEngine::Server _server; QMdnsEngine::Cache _cache; + QSharedPointer _resolver; - QMap _browsedServiceTypes; + QMap> _browsedServiceTypes; }; #endif // MDNSBROWSER_H diff --git a/include/mdns/MdnsProvider.h b/include/mdns/MdnsProvider.h index 80deb7c1..c3e328c7 100644 --- a/include/mdns/MdnsProvider.h +++ b/include/mdns/MdnsProvider.h @@ -9,6 +9,7 @@ // Qt includes #include #include +#include // Utility includes #include @@ -41,11 +42,11 @@ private: /// The logger instance for mDNS-Service Logger* _log; - QMdnsEngine::Server* _server; - QMdnsEngine::Hostname* _hostname; + QScopedPointer _server; + QScopedPointer _hostname; /// map of services provided - QMap _providedServiceTypes; + QMap> _providedServiceTypes; }; #endif // MDNSPROVIDER_H diff --git a/include/utils/Image.h b/include/utils/Image.h index a0722040..674b431a 100644 --- a/include/utils/Image.h +++ b/include/utils/Image.h @@ -15,9 +15,8 @@ public: { } - Image(unsigned width, unsigned height) : + Image(int width, int height) : Image(width, height, Pixel_T()) - { } @@ -28,7 +27,7 @@ public: /// @param height The height of the image /// @param background The color of the image /// - Image(unsigned width, unsigned height, const Pixel_T background) : + Image(int width, int height, const Pixel_T background) : _d_ptr(new ImageData(width, height, background)) { } @@ -78,7 +77,7 @@ public: /// /// @return The width of the image /// - inline unsigned width() const + inline int width() const { return _d_ptr->width(); } @@ -88,7 +87,7 @@ public: /// /// @return The height of the image /// - inline unsigned height() const + inline int height() const { return _d_ptr->height(); } @@ -111,7 +110,7 @@ public: /// /// @return const reference to specified pixel /// - uint8_t blue(unsigned pixel) const + uint8_t blue(int pixel) const { return _d_ptr->blue(pixel); } @@ -121,7 +120,7 @@ public: /// /// @param x The x index /// @param y The y index - const Pixel_T& operator()(unsigned x, unsigned y) const + const Pixel_T& operator()(int x, int y) const { return _d_ptr->operator()(x, y); } @@ -129,7 +128,7 @@ public: /// /// @return reference to specified pixel /// - Pixel_T& operator()(unsigned x, unsigned y) + Pixel_T& operator()(int x, int y) { return _d_ptr->operator()(x, y); } @@ -137,7 +136,7 @@ public: /// Resize the image /// @param width The width of the image /// @param height The height of the image - void resize(unsigned width, unsigned height) + void resize(int width, int height) { _d_ptr->resize(width, height); } @@ -198,12 +197,11 @@ private: /// /// @return The index into the underlying data-vector /// - inline unsigned toIndex(unsigned x, unsigned y) const + inline int toIndex(int x, int y) const { return _d_ptr->toIndex(x, y); } -private: QSharedDataPointer> _d_ptr; }; diff --git a/include/utils/ImageData.h b/include/utils/ImageData.h index e850fba3..497ea364 100644 --- a/include/utils/ImageData.h +++ b/include/utils/ImageData.h @@ -1,12 +1,9 @@ #pragma once // STL includes -#include #include #include #include -#include -#include #include // QT includes @@ -24,10 +21,10 @@ class ImageData : public QSharedData public: typedef Pixel_T pixel_type; - ImageData(unsigned width, unsigned height, const Pixel_T background) : + ImageData(int width, int height, const Pixel_T background) : _width(width), _height(height), - _pixels(new Pixel_T[width * height + 1]) + _pixels(new Pixel_T[static_cast(width) * static_cast(height)]) { std::fill(_pixels, _pixels + width * height, background); } @@ -36,9 +33,9 @@ public: QSharedData(other), _width(other._width), _height(other._height), - _pixels(new Pixel_T[other._width * other._height + 1]) + _pixels(new Pixel_T[static_cast(other._width) * static_cast(other._height)]) { - memcpy(_pixels, other._pixels, static_cast(other._width) * static_cast(other._height) * sizeof(Pixel_T)); + memcpy(_pixels, other._pixels, static_cast(other._width) * static_cast(other._height) * sizeof(Pixel_T)); } ImageData& operator=(ImageData rhs) @@ -74,52 +71,57 @@ public: delete[] _pixels; } - inline unsigned width() const + inline int width() const { return _width; } - inline unsigned height() const + inline int height() const { return _height; } - uint8_t red(unsigned pixel) const + uint8_t red(int pixel) const { return (_pixels + pixel)->red; } - uint8_t green(unsigned pixel) const + uint8_t green(int pixel) const { return (_pixels + pixel)->green; } - uint8_t blue(unsigned pixel) const + uint8_t blue(int pixel) const { return (_pixels + pixel)->blue; } - const Pixel_T& operator()(unsigned x, unsigned y) const + const Pixel_T& operator()(int x, int y) const { return _pixels[toIndex(x,y)]; } - Pixel_T& operator()(unsigned x, unsigned y) + Pixel_T& operator()(int x, int y) { return _pixels[toIndex(x,y)]; } - void resize(unsigned width, unsigned height) + void resize(int width, int height) { if (width == _width && height == _height) - return; - - if ((width * height) > unsigned((_width * _height))) { - delete[] _pixels; - _pixels = new Pixel_T[width*height + 1]; + return; } + // Allocate a new buffer without initializing the content + Pixel_T* newPixels = new Pixel_T[static_cast(width) * static_cast(height)]; + + // Release the old buffer without copying data + delete[] _pixels; + + // Update the pointer to the new buffer + _pixels = newPixels; + _width = width; _height = height; } @@ -137,11 +139,13 @@ public: void toRgb(ImageData& image) const { if (image.width() != _width || image.height() != _height) + { image.resize(_width, _height); + } - const unsigned imageSize = _width * _height; + const int imageSize = _width * _height; - for (unsigned idx = 0; idx < imageSize; idx++) + for (int idx = 0; idx < imageSize; idx++) { const Pixel_T & color = _pixels[idx]; image.memptr()[idx] = ColorRgb{color.red, color.green, color.blue}; @@ -157,26 +161,22 @@ public: { if (_width != 1 || _height != 1) { - _width = 1; - _height = 1; - delete[] _pixels; - _pixels = new Pixel_T[2]; + resize(1,1); } - - memset(_pixels, 0, static_cast(_width) * static_cast(_height) * sizeof(Pixel_T)); + // Set the single pixel to the default background + _pixels[0] = Pixel_T(); } private: - inline unsigned toIndex(unsigned x, unsigned y) const + inline int toIndex(int x, int y) const { return y * _width + x; } -private: /// The width of the image - unsigned _width; + int _width; /// The height of the image - unsigned _height; + int _height; /// The pixels of the image Pixel_T* _pixels; }; diff --git a/include/utils/Logger.h b/include/utils/Logger.h index 74c36954..0f71700e 100644 --- a/include/utils/Logger.h +++ b/include/utils/Logger.h @@ -6,6 +6,7 @@ #include #include #include +#include #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) #include @@ -14,8 +15,6 @@ #endif // stl includes -#include -#include #ifdef _WIN32 #include #endif @@ -59,7 +58,7 @@ public: QString function; unsigned int line; QString fileName; - uint64_t utime; + qint64 utime; QString message; LogLevel level; QString levelString; @@ -74,7 +73,7 @@ public: void setMinLevel(LogLevel level) { _minLevel = static_cast(level); } LogLevel getMinLevel() const { return static_cast(int(_minLevel)); } QString getName() const { return _name; } - QString getSubName() const { return _subname; } + QString getSubName() const { return _subName; } signals: void newLogMessage(Logger::T_LOG_MESSAGE); @@ -95,7 +94,7 @@ private: static QAtomicInteger GLOBAL_MIN_LOG_LEVEL; const QString _name; - const QString _subname; + const QString _subName; const bool _syslogEnabled; const unsigned _loggerId; @@ -109,15 +108,15 @@ class LoggerManager : public QObject public: static LoggerManager* getInstance(); - const QList* getLogMessageBuffer() const { return &_logMessageBuffer; } public slots: void handleNewLogMessage(const Logger::T_LOG_MESSAGE&); + QJsonArray getLogMessageBuffer(Logger::LogLevel filter=Logger::UNSET) const; signals: void newLogMessage(const Logger::T_LOG_MESSAGE&); -protected: +private: LoggerManager(); QList _logMessageBuffer; diff --git a/include/utils/hyperion.h b/include/utils/hyperion.h index 88ebc44e..eeb5be5f 100644 --- a/include/utils/hyperion.h +++ b/include/utils/hyperion.h @@ -96,7 +96,7 @@ namespace hyperion { static_cast(channelConfig[0].toInt(defaultR)), static_cast(channelConfig[1].toInt(defaultG)), static_cast(channelConfig[2].toInt(defaultB)), - "ChannelAdjust_" + channelName.toUpper() + channelName ); } diff --git a/include/webserver/WebServer.h b/include/webserver/WebServer.h index d5b87c42..088b79b3 100644 --- a/include/webserver/WebServer.h +++ b/include/webserver/WebServer.h @@ -92,11 +92,6 @@ private: StaticFileServing* _staticFileServing; QtHttpServer* _server; bool _inited = false; - - const QString WEBSERVER_DEFAULT_PATH = ":/webconfig"; - const QString WEBSERVER_DEFAULT_CRT_PATH = ":/hyperion.crt"; - const QString WEBSERVER_DEFAULT_KEY_PATH = ":/hyperion.key"; - quint16 WEBSERVER_DEFAULT_PORT = 8090; }; #endif // WEBSERVER_H diff --git a/libsrc/api/JsonAPI.cpp b/libsrc/api/JsonAPI.cpp index 866e262d..e7ba96a6 100644 --- a/libsrc/api/JsonAPI.cpp +++ b/libsrc/api/JsonAPI.cpp @@ -1983,24 +1983,10 @@ void JsonAPI::incommingLogMessage(const Logger::T_LOG_MESSAGE &msg) if (!_streaming_logging_activated) { _streaming_logging_activated = true; - const QList *logBuffer = LoggerManager::getInstance()->getLogMessageBuffer(); - for (int i = 0; i < logBuffer->length(); i++) - { - //Only present records of the current log-level - if ( logBuffer->at(i).level >= _log->getLogLevel()) - { - message["loggerName"] = logBuffer->at(i).loggerName; - message["loggerSubName"] = logBuffer->at(i).loggerSubName; - message["function"] = logBuffer->at(i).function; - message["line"] = QString::number(logBuffer->at(i).line); - message["fileName"] = logBuffer->at(i).fileName; - message["message"] = logBuffer->at(i).message; - message["levelString"] = logBuffer->at(i).levelString; - message["utime"] = QString::number(logBuffer->at(i).utime); - - messageArray.append(message); - } - } + QMetaObject::invokeMethod(LoggerManager::getInstance(), "getLogMessageBuffer", + Qt::DirectConnection, + Q_RETURN_ARG(QJsonArray, messageArray), + Q_ARG(Logger::LogLevel, _log->getLogLevel())); } else { diff --git a/libsrc/blackborder/BlackBorderProcessor.cpp b/libsrc/blackborder/BlackBorderProcessor.cpp index 538ee534..ab13a49c 100644 --- a/libsrc/blackborder/BlackBorderProcessor.cpp +++ b/libsrc/blackborder/BlackBorderProcessor.cpp @@ -35,12 +35,7 @@ BlackBorderProcessor::BlackBorderProcessor(Hyperion* hyperion, QObject* parent) // listen for component state changes connect(_hyperion, &Hyperion::compStateChangeRequest, this, &BlackBorderProcessor::handleCompStateChangeRequest); - _detector = new BlackBorderDetector(_oldThreshold); -} - -BlackBorderProcessor::~BlackBorderProcessor() -{ - delete _detector; + _detector = std::make_unique(_oldThreshold); } void BlackBorderProcessor::handleSettingsUpdate(settings::type type, const QJsonDocument& config) @@ -66,10 +61,7 @@ void BlackBorderProcessor::handleSettingsUpdate(settings::type type, const QJson if (fabs(_oldThreshold - newThreshold) > std::numeric_limits::epsilon()) { _oldThreshold = newThreshold; - - delete _detector; - - _detector = new BlackBorderDetector(newThreshold); + _detector = std::make_unique(_oldThreshold); } Debug(Logger::getInstance("BLACKBORDER", "I"+QString::number(_hyperion->getInstanceIndex())), "Set mode to: %s", QSTRING_CSTR(_detectionMode)); diff --git a/libsrc/boblightserver/BoblightServer.cpp b/libsrc/boblightserver/BoblightServer.cpp index a58257ba..f6acccf8 100644 --- a/libsrc/boblightserver/BoblightServer.cpp +++ b/libsrc/boblightserver/BoblightServer.cpp @@ -63,6 +63,7 @@ void BoblightServer::stop() return; qDeleteAll(_openConnections); + _openConnections.clear(); _server->close(); diff --git a/libsrc/commandline/Parser.cpp b/libsrc/commandline/Parser.cpp index df58fe1f..a2b58765 100644 --- a/libsrc/commandline/Parser.cpp +++ b/libsrc/commandline/Parser.cpp @@ -5,6 +5,7 @@ using namespace commandline; Parser::~Parser() { qDeleteAll(_options); + _options.clear(); } bool Parser::parse(const QStringList &arguments) diff --git a/libsrc/grabber/audio/AudioGrabber.cpp b/libsrc/grabber/audio/AudioGrabber.cpp index 995a1b7c..1e2be84d 100644 --- a/libsrc/grabber/audio/AudioGrabber.cpp +++ b/libsrc/grabber/audio/AudioGrabber.cpp @@ -178,7 +178,7 @@ void AudioGrabber::processAudioFrame(int16_t* buffer, int length) } // Convert to Image - Image finalImage (static_cast(image.width()), static_cast(image.height())); + Image finalImage (image.width(),image.height()); for (int y = 0; y < image.height(); y++) { memcpy((unsigned char*)finalImage.memptr() + y * image.width() * 3, static_cast(image.scanLine(y)), image.width() * 3); diff --git a/libsrc/grabber/audio/AudioWrapper.cpp b/libsrc/grabber/audio/AudioWrapper.cpp index 2c47a3b8..bbee42e9 100644 --- a/libsrc/grabber/audio/AudioWrapper.cpp +++ b/libsrc/grabber/audio/AudioWrapper.cpp @@ -5,7 +5,6 @@ AudioWrapper::AudioWrapper() : GrabberWrapper("AudioGrabber", &_grabber) - , _grabber() { // register the image type qRegisterMetaType>("Image"); diff --git a/libsrc/grabber/osx/OsxFrameGrabber.cpp b/libsrc/grabber/osx/OsxFrameGrabber.cpp index 0e42e529..c31b7606 100644 --- a/libsrc/grabber/osx/OsxFrameGrabber.cpp +++ b/libsrc/grabber/osx/OsxFrameGrabber.cpp @@ -124,6 +124,7 @@ bool OsxFrameGrabber::setDisplayIndex(int index) CGImageRelease(image); } } + delete[] activeDspys; } else { @@ -201,7 +202,7 @@ QJsonObject OsxFrameGrabber::discover(const QJsonObject& params) defaults["video_input"] = video_inputs_default; inputsDiscovered["default"] = defaults; } - delete [] activeDspys; + delete[] activeDspys; } if (inputsDiscovered.isEmpty()) diff --git a/libsrc/grabber/qt/QtGrabber.cpp b/libsrc/grabber/qt/QtGrabber.cpp index 3d2cd51c..f826f506 100644 --- a/libsrc/grabber/qt/QtGrabber.cpp +++ b/libsrc/grabber/qt/QtGrabber.cpp @@ -22,8 +22,8 @@ const bool verbose = false; QtGrabber::QtGrabber(int display, int cropLeft, int cropRight, int cropTop, int cropBottom) : Grabber("QTGRABBER", cropLeft, cropRight, cropTop, cropBottom) , _display(display) - , _calculatedWidth(0) - , _calculatedHeight(0) + , _screenWidth(0) + , _screenHeight(0) , _src_x(0) , _src_y(0) , _src_x_max(0) @@ -233,8 +233,8 @@ int QtGrabber::grabFrame(Image& image) } else { - QImage imageFrame = originalPixmap.toImage().scaled(_calculatedWidth, _calculatedHeight).convertToFormat(QImage::Format_RGB888); - image.resize(static_cast(_calculatedWidth), static_cast(_calculatedHeight)); + QImage imageFrame = originalPixmap.toImage().scaled(_width, _height).convertToFormat(QImage::Format_RGB888); + image.resize(_width, _height); for (int y = 0; y < imageFrame.height(); y++) { @@ -263,27 +263,27 @@ int QtGrabber::updateScreenDimensions(bool force) { geo = _screen->geometry(); } - if (!force && _width == geo.width() && _height == geo.height()) + if (!force && _screenWidth == geo.width() && _height == geo.height()) { // No update required return 0; } - Info(_log, "Update of screen resolution: [%dx%d] to [%dx%d]", _width, _height, geo.width(), geo.height()); - _width = geo.width(); - _height = geo.height(); + Info(_log, "Update of screen resolution: [%dx%d] to [%dx%d]", _screenWidth, _screenHeight, geo.width(), geo.height()); + _screenWidth = geo.width(); + _screenHeight = geo.height(); int width = 0; int height = 0; // Image scaling is performed by Qt - width = (_width > (_cropLeft + _cropRight)) - ? ((_width - _cropLeft - _cropRight) / _pixelDecimation) - : (_width / _pixelDecimation); + width = (_screenWidth > (_cropLeft + _cropRight)) + ? ((_screenWidth - _cropLeft - _cropRight) / _pixelDecimation) + : (_screenWidth / _pixelDecimation); - height = (_height > (_cropTop + _cropBottom)) - ? ((_height - _cropTop - _cropBottom) / _pixelDecimation) - : (_height / _pixelDecimation); + height = (_screenHeight > (_cropTop + _cropBottom)) + ? ((_screenHeight - _cropTop - _cropBottom) / _pixelDecimation) + : (_screenHeight / _pixelDecimation); // calculate final image dimensions and adjust top/left cropping in 3D modes if (_isVirtual) @@ -300,33 +300,33 @@ int QtGrabber::updateScreenDimensions(bool force) switch (_videoMode) { case VideoMode::VIDEO_3DSBS: - _calculatedWidth = width / 2; - _calculatedHeight = height; + _width = width / 2; + _height = height; _src_x = _src_x + (_cropLeft / 2); _src_y = _src_y + _cropTop; - _src_x_max = (_width / 2) - _cropRight - _cropLeft; - _src_y_max = _height - _cropBottom - _cropTop; + _src_x_max = (_screenWidth / 2) - _cropRight - _cropLeft; + _src_y_max = _screenHeight - _cropBottom - _cropTop; break; case VideoMode::VIDEO_3DTAB: - _calculatedWidth = width; - _calculatedHeight = height / 2; + _width = width; + _height = height / 2; _src_x = _src_x + _cropLeft; _src_y = _src_y + (_cropTop / 2); - _src_x_max = _width - _cropRight - _cropLeft; - _src_y_max = (_height / 2) - _cropBottom - _cropTop; + _src_x_max = _screenWidth - _cropRight - _cropLeft; + _src_y_max = (_screenHeight / 2) - _cropBottom - _cropTop; break; case VideoMode::VIDEO_2D: default: - _calculatedWidth = width; - _calculatedHeight = height; + _width = width; + _height = height; _src_x = _src_x + _cropLeft; _src_y = _src_y + _cropTop; - _src_x_max = _width - _cropRight - _cropLeft; - _src_y_max = _height - _cropBottom - _cropTop; + _src_x_max = _screenWidth - _cropRight - _cropLeft; + _src_y_max = _screenHeight - _cropBottom - _cropTop; break; } - Info(_log, "Update output image resolution to [%dx%d]", _calculatedWidth, _calculatedHeight); + Info(_log, "Update output image resolution to [%dx%d]", _width, _height); Debug(_log, "Grab screen area: %d,%d,%d,%d", _src_x, _src_y, _src_x_max, _src_y_max); return 1; @@ -433,10 +433,10 @@ QJsonObject QtGrabber::discover(const QJsonObject& params) if (screens.at(0)->size() != screens.at(0)->virtualSize()) { - QJsonObject in; - in["name"] = "All Displays"; - in["inputIdx"] = screens.size(); - in["virtual"] = true; + QJsonObject input; + input["name"] = "All Displays"; + input["inputIdx"] = screens.size(); + input["virtual"] = true; QJsonArray formats; QJsonObject format; @@ -454,15 +454,19 @@ QJsonObject QtGrabber::discover(const QJsonObject& params) format["resolutions"] = resolutionArray; formats.append(format); - in["formats"] = formats; - video_inputs.append(in); + input["formats"] = formats; + video_inputs.append(input); } inputsDiscovered["video_inputs"] = video_inputs; - QJsonObject defaults, video_inputs_default, resolution_default; + QJsonObject resolution_default; resolution_default["fps"] = _fps; + + QJsonObject video_inputs_default; video_inputs_default["resolution"] = resolution_default; video_inputs_default["inputIdx"] = 0; + + QJsonObject defaults; defaults["video_input"] = video_inputs_default; inputsDiscovered["default"] = defaults; } diff --git a/libsrc/grabber/video/EncoderThread.cpp b/libsrc/grabber/video/EncoderThread.cpp index 3555bb9f..254472c0 100644 --- a/libsrc/grabber/video/EncoderThread.cpp +++ b/libsrc/grabber/video/EncoderThread.cpp @@ -318,7 +318,7 @@ void EncoderThread::processImageMjpeg() } } - Image srcImage(static_cast(_width), static_cast(_height)); + Image srcImage(_width, _height); if (tjDecompress2(_tjInstance, _localData , _size, reinterpret_cast(srcImage.memptr()), _width, 0, _height, diff --git a/libsrc/grabber/x11/X11Grabber.cpp b/libsrc/grabber/x11/X11Grabber.cpp index cf24eea2..b9418b83 100644 --- a/libsrc/grabber/x11/X11Grabber.cpp +++ b/libsrc/grabber/x11/X11Grabber.cpp @@ -18,16 +18,15 @@ X11Grabber::X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom) , _dstFormat(nullptr) , _srcPicture(None) , _dstPicture(None) - , _calculatedWidth(0) - , _calculatedHeight(0) + , _screenWidth(0) + , _screenHeight(0) , _src_x(cropLeft) , _src_y(cropTop) - , _XShmAvailable(false) - , _XRenderAvailable(false) - , _XRandRAvailable(false) + , _xShmAvailable(false) + , _xRenderAvailable(false) + , _xRandRAvailable(false) , _isWayland (false) , _logger{} - , _image(0,0) { _logger = Logger::getInstance("X11"); @@ -53,17 +52,17 @@ void X11Grabber::freeResources() { XDestroyImage(_xImage); } - if (_XRandRAvailable) + if (_xRandRAvailable) { qApp->removeNativeEventFilter(this); } - if(_XShmAvailable) + if(_xShmAvailable) { XShmDetach(_x11Display, &_shminfo); shmdt(_shminfo.shmaddr); - shmctl(_shminfo.shmid, IPC_RMID, 0); + shmctl(_shminfo.shmid, IPC_RMID, nullptr); } - if (_XRenderAvailable) + if (_xRenderAvailable) { XRenderFreePicture(_x11Display, _srcPicture); XRenderFreePicture(_x11Display, _dstPicture); @@ -73,41 +72,41 @@ void X11Grabber::freeResources() void X11Grabber::setupResources() { - if (_XRandRAvailable) + if (_xRandRAvailable) { qApp->installNativeEventFilter(this); } - if(_XShmAvailable) + if(_xShmAvailable) { - _xImage = XShmCreateImage(_x11Display, _windowAttr.visual, _windowAttr.depth, ZPixmap, NULL, &_shminfo, _calculatedWidth, _calculatedHeight); + _xImage = XShmCreateImage(_x11Display, _windowAttr.visual, _windowAttr.depth, ZPixmap, nullptr, &_shminfo, _width, _height); _shminfo.shmid = shmget(IPC_PRIVATE, (size_t) _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777); - _xImage->data = (char*)shmat(_shminfo.shmid,0,0); + _xImage->data = (char*)shmat(_shminfo.shmid,nullptr,0); _shminfo.shmaddr = _xImage->data; _shminfo.readOnly = False; XShmAttach(_x11Display, &_shminfo); } - if (_XRenderAvailable) + if (_xRenderAvailable) { _useImageResampler = false; _imageResampler.setHorizontalPixelDecimation(1); _imageResampler.setVerticalPixelDecimation(1); - if(_XShmPixmapAvailable) + if(_xShmPixmapAvailable) { - _pixmap = XShmCreatePixmap(_x11Display, _window, _xImage->data, &_shminfo, _calculatedWidth, _calculatedHeight, _windowAttr.depth); + _pixmap = XShmCreatePixmap(_x11Display, _window, _xImage->data, &_shminfo, _width, _height, _windowAttr.depth); } else { - _pixmap = XCreatePixmap(_x11Display, _window, _calculatedWidth, _calculatedHeight, _windowAttr.depth); + _pixmap = XCreatePixmap(_x11Display, _window, _width, _height, _windowAttr.depth); } _srcFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual); _dstFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual); _srcPicture = XRenderCreatePicture(_x11Display, _window, _srcFormat, CPRepeat, &_pictAttr); _dstPicture = XRenderCreatePicture(_x11Display, _pixmap, _dstFormat, CPRepeat, &_pictAttr); - XRenderSetPictureFilter(_x11Display, _srcPicture, FilterBilinear, NULL, 0); + XRenderSetPictureFilter(_x11Display, _srcPicture, FilterBilinear, nullptr, 0); } else { @@ -162,19 +161,20 @@ bool X11Grabber::setupDisplay() { _window = DefaultRootWindow(_x11Display); - int dummy, pixmaps_supported; + int dummy; + int pixmaps_supported; - _XRandRAvailable = XRRQueryExtension(_x11Display, &_XRandREventBase, &dummy); - _XRenderAvailable = XRenderQueryExtension(_x11Display, &dummy, &dummy); - _XShmAvailable = XShmQueryExtension(_x11Display); + _xRandRAvailable = (XRRQueryExtension(_x11Display, &_xRandREventBase, &dummy) != 0); + _xRenderAvailable = (XRenderQueryExtension(_x11Display, &dummy, &dummy) != 0); + _xShmAvailable = (XShmQueryExtension(_x11Display) != 0); XShmQueryVersion(_x11Display, &dummy, &dummy, &pixmaps_supported); - _XShmPixmapAvailable = pixmaps_supported && XShmPixmapFormat(_x11Display) == ZPixmap; + _xShmPixmapAvailable = (pixmaps_supported != 0) && XShmPixmapFormat(_x11Display) == ZPixmap; Info(_log, "%s", QSTRING_CSTR(QString("XRandR=[%1] XRender=[%2] XShm=[%3] XPixmap=[%4]") - .arg(_XRandRAvailable ? "available" : "unavailable", - _XRenderAvailable ? "available" : "unavailable", - _XShmAvailable ? "available" : "unavailable", - _XShmPixmapAvailable ? "available" : "unavailable")) + .arg(_xRandRAvailable ? "available" : "unavailable", + _xRenderAvailable ? "available" : "unavailable", + _xShmAvailable ? "available" : "unavailable", + _xShmPixmapAvailable ? "available" : "unavailable")) ); result = (updateScreenDimensions(true) >=0); @@ -186,12 +186,17 @@ bool X11Grabber::setupDisplay() int X11Grabber::grabFrame(Image & image, bool forceUpdate) { - if (!_isEnabled) return 0; + if (!_isEnabled) + { + return 0; + } if (forceUpdate) + { updateScreenDimensions(forceUpdate); + } - if (_XRenderAvailable) + if (_xRenderAvailable) { double scale_x = static_cast(_windowAttr.width / _pixelDecimation) / static_cast(_windowAttr.width); double scale_y = static_cast(_windowAttr.height / _pixelDecimation) / static_cast(_windowAttr.height); @@ -224,20 +229,20 @@ int X11Grabber::grabFrame(Image & image, bool forceUpdate) // src_y = cropTop, mask_x, mask_y, dest_x, dest_y, width, height XRenderComposite( _x11Display, PictOpSrc, _srcPicture, None, _dstPicture, ( _src_x/_pixelDecimation), - (_src_y/_pixelDecimation), 0, 0, 0, 0, _calculatedWidth, _calculatedHeight); + (_src_y/_pixelDecimation), 0, 0, 0, 0, _width, _height); XSync(_x11Display, False); - if (_XShmAvailable) + if (_xShmAvailable) { XShmGetImage(_x11Display, _pixmap, _xImage, 0, 0, AllPlanes); } else { - _xImage = XGetImage(_x11Display, _pixmap, 0, 0, _calculatedWidth, _calculatedHeight, AllPlanes, ZPixmap); + _xImage = XGetImage(_x11Display, _pixmap, 0, 0, _width, _height, AllPlanes, ZPixmap); } } - else if (_XShmAvailable) + else if (_xShmAvailable) { // use xshm XShmGetImage(_x11Display, _window, _xImage, _src_x, _src_y, AllPlanes); @@ -245,7 +250,7 @@ int X11Grabber::grabFrame(Image & image, bool forceUpdate) else { // all things done by xgetimage - _xImage = XGetImage(_x11Display, _window, _src_x, _src_y, _calculatedWidth, _calculatedHeight, AllPlanes, ZPixmap); + _xImage = XGetImage(_x11Display, _window, _src_x, _src_y, _width, _height, AllPlanes, ZPixmap); } if (_xImage == nullptr) @@ -268,46 +273,46 @@ int X11Grabber::updateScreenDimensions(bool force) return -1; } - if (!force && _width == _windowAttr.width && _height == _windowAttr.height) + if (!force && _screenWidth == _windowAttr.width && _screenHeight == _windowAttr.height) { // No update required return 0; } - if (_width || _height) + if ((_screenWidth != 0) || _screenHeight != 0) { freeResources(); } - Info(_log, "Update of screen resolution: [%dx%d] to [%dx%d]", _width, _height, _windowAttr.width, _windowAttr.height); - _width = _windowAttr.width; - _height = _windowAttr.height; + Info(_log, "Update of screen resolution: [%dx%d] to [%dx%d]", _screenWidth, _screenHeight, _windowAttr.width, _windowAttr.height); + _screenWidth = _windowAttr.width; + _screenHeight = _windowAttr.height; int width=0; int height=0; // Image scaling is performed by XRender when available, otherwise by ImageResampler - if (_XRenderAvailable) + if (_xRenderAvailable) { - width = (_width > (_cropLeft + _cropRight)) - ? ((_width - _cropLeft - _cropRight) / _pixelDecimation) - : _width / _pixelDecimation; + width = (_screenWidth > (_cropLeft + _cropRight)) + ? ((_screenWidth - _cropLeft - _cropRight) / _pixelDecimation) + : _screenWidth / _pixelDecimation; - height = (_height > (_cropTop + _cropBottom)) - ? ((_height - _cropTop - _cropBottom) / _pixelDecimation) - : _height / _pixelDecimation; + height = (_screenHeight > (_cropTop + _cropBottom)) + ? ((_screenHeight - _cropTop - _cropBottom) / _pixelDecimation) + : _screenHeight / _pixelDecimation; Info(_log, "Using XRender for grabbing"); } else { - width = (_width > (_cropLeft + _cropRight)) - ? (_width - _cropLeft - _cropRight) - : _width; + width = (_screenWidth > (_cropLeft + _cropRight)) + ? (_screenWidth - _cropLeft - _cropRight) + : _screenWidth; - height = (_height > (_cropTop + _cropBottom)) - ? (_height - _cropTop - _cropBottom) - : _height; + height = (_screenHeight > (_cropTop + _cropBottom)) + ? (_screenHeight - _cropTop - _cropBottom) + : _screenHeight; Info(_log, "Using XGetImage for grabbing"); } @@ -316,29 +321,28 @@ int X11Grabber::updateScreenDimensions(bool force) switch (_videoMode) { case VideoMode::VIDEO_3DSBS: - _calculatedWidth = width /2; - _calculatedHeight = height; + _width = width /2; + _height = height; _src_x = _cropLeft / 2; _src_y = _cropTop; break; case VideoMode::VIDEO_3DTAB: - _calculatedWidth = width; - _calculatedHeight = height / 2; + _width = width; + _height = height / 2; _src_x = _cropLeft; _src_y = _cropTop / 2; break; case VideoMode::VIDEO_2D: default: - _calculatedWidth = width; - _calculatedHeight = height; + _width = width; + _height = height; _src_x = _cropLeft; _src_y = _cropTop; break; } - Info(_log, "Update output image resolution: [%dx%d] to [%dx%d]", _image.width(), _image.height(), _calculatedWidth, _calculatedHeight); - - _image.resize(_calculatedWidth, _calculatedHeight); + Info(_log, "Update output image resolution to [%dx%d]", _width, _height); + _image.resize(_width, _height); setupResources(); return 1; @@ -384,14 +388,14 @@ bool X11Grabber::nativeEventFilter(const QByteArray & eventType, void * message, bool X11Grabber::nativeEventFilter(const QByteArray & eventType, void * message, long int * /*result*/) #endif { - if (!_XRandRAvailable || eventType != "xcb_generic_event_t") { + if (!_xRandRAvailable || eventType != "xcb_generic_event_t") { return false; } - xcb_generic_event_t *e = static_cast(message); - const uint8_t xEventType = XCB_EVENT_RESPONSE_TYPE(e); + xcb_generic_event_t *event = static_cast(message); + const uint8_t xEventType = XCB_EVENT_RESPONSE_TYPE(event); - if (xEventType == _XRandREventBase + XCB_RANDR_SCREEN_CHANGE_NOTIFY) + if (xEventType == _xRandREventBase + XCB_RANDR_SCREEN_CHANGE_NOTIFY) { updateScreenDimensions(true); } @@ -428,7 +432,7 @@ QJsonObject X11Grabber::discover(const QJsonObject& params) } else { - QJsonObject in; + QJsonObject input; QString displayName; char* name; @@ -440,8 +444,8 @@ QJsonObject X11Grabber::discover(const QJsonObject& params) displayName = QString("Display:%1").arg(i); } - in["name"] = displayName; - in["inputIdx"] = i; + input["name"] = displayName; + input["inputIdx"] = i; QJsonArray formats; QJsonArray resolutionArray; @@ -457,19 +461,22 @@ QJsonObject X11Grabber::discover(const QJsonObject& params) format["resolutions"] = resolutionArray; formats.append(format); - in["formats"] = formats; - video_inputs.append(in); + input["formats"] = formats; + video_inputs.append(input); } } if ( !video_inputs.isEmpty() ) { inputsDiscovered["video_inputs"] = video_inputs; - - QJsonObject defaults, video_inputs_default, resolution_default; + QJsonObject resolution_default; resolution_default["fps"] = _fps; + + QJsonObject video_inputs_default; video_inputs_default["resolution"] = resolution_default; video_inputs_default["inputIdx"] = 0; + + QJsonObject defaults; defaults["video_input"] = video_inputs_default; inputsDiscovered["default"] = defaults; } diff --git a/libsrc/hyperion/GrabberWrapper.cpp b/libsrc/hyperion/GrabberWrapper.cpp index 11161837..42a3c69c 100644 --- a/libsrc/hyperion/GrabberWrapper.cpp +++ b/libsrc/hyperion/GrabberWrapper.cpp @@ -27,26 +27,33 @@ bool GrabberWrapper::GLOBAL_GRABBER_AUDIO_ENABLE = false; GrabberWrapper::GrabberWrapper(const QString& grabberName, Grabber * ggrabber, int updateRate_Hz) : _grabberName(grabberName) , _log(Logger::getInstance(grabberName.toUpper())) - , _timer(new QTimer(this)) + , _timer(nullptr) , _updateInterval_ms(1000/updateRate_Hz) , _ggrabber(ggrabber) - , _image(0,0) { GrabberWrapper::instance = this; + _timer.reset(new QTimer(this)); + // Configure the timer to generate events every n milliseconds _timer->setTimerType(Qt::PreciseTimer); _timer->setInterval(_updateInterval_ms); - connect(_timer, &QTimer::timeout, this, &GrabberWrapper::action); + connect(_timer.get(), &QTimer::timeout, this, &GrabberWrapper::action); // connect the image forwarding if (_grabberName.startsWith("V4L")) + { connect(this, &GrabberWrapper::systemImage, GlobalSignals::getInstance(), &GlobalSignals::setV4lImage); + } else if (_grabberName.startsWith("Audio")) + { connect(this, &GrabberWrapper::systemImage, GlobalSignals::getInstance(), &GlobalSignals::setAudioImage); + } else + { connect(this, &GrabberWrapper::systemImage, GlobalSignals::getInstance(), &GlobalSignals::setSystemImage); + } // listen for source requests connect(GlobalSignals::getInstance(), &GlobalSignals::requestSource, this, &GrabberWrapper::handleSourceRequest); @@ -56,6 +63,7 @@ GrabberWrapper::GrabberWrapper(const QString& grabberName, Grabber * ggrabber, i GrabberWrapper::~GrabberWrapper() { + _timer->stop(); GrabberWrapper::instance = nullptr; } @@ -103,19 +111,25 @@ QStringList GrabberWrapper::getActive(int inst, GrabberTypeFilter type) const if (type == GrabberTypeFilter::SCREEN || type == GrabberTypeFilter::ALL) { if (GRABBER_SYS_CLIENTS.contains(inst)) + { result << GRABBER_SYS_CLIENTS.value(inst); + } } if (type == GrabberTypeFilter::VIDEO || type == GrabberTypeFilter::ALL) { if (GRABBER_V4L_CLIENTS.contains(inst)) + { result << GRABBER_V4L_CLIENTS.value(inst); + } } if (type == GrabberTypeFilter::AUDIO || type == GrabberTypeFilter::ALL) { if (GRABBER_AUDIO_CLIENTS.contains(inst)) + { result << GRABBER_AUDIO_CLIENTS.value(inst); + } } return result; @@ -207,7 +221,9 @@ void GrabberWrapper::updateTimer(int interval) _timer->setInterval(_updateInterval_ms); if(timerWasActive) + { _timer->start(); + } } } @@ -268,40 +284,64 @@ void GrabberWrapper::handleSourceRequest(hyperion::Components component, int hyp !_grabberName.startsWith("Audio")) { if (listen) + { GRABBER_SYS_CLIENTS.insert(hyperionInd, _grabberName); + } else + { GRABBER_SYS_CLIENTS.remove(hyperionInd); + } if (GRABBER_SYS_CLIENTS.empty() || !getSysGrabberState()) + { stop(); + } else + { start(); + } } else if (component == hyperion::Components::COMP_V4L && _grabberName.startsWith("V4L")) { if (listen) + { GRABBER_V4L_CLIENTS.insert(hyperionInd, _grabberName); + } else + { GRABBER_V4L_CLIENTS.remove(hyperionInd); + } if (GRABBER_V4L_CLIENTS.empty() || !getV4lGrabberState()) + { stop(); + } else + { start(); + } } else if (component == hyperion::Components::COMP_AUDIO && _grabberName.startsWith("Audio")) { if (listen) + { GRABBER_AUDIO_CLIENTS.insert(hyperionInd, _grabberName); + } else + { GRABBER_AUDIO_CLIENTS.remove(hyperionInd); + } if (GRABBER_AUDIO_CLIENTS.empty() || !getAudioGrabberState()) + { stop(); + } else + { start(); + } } } diff --git a/libsrc/hyperion/Hyperion.cpp b/libsrc/hyperion/Hyperion.cpp index 539b823c..2a2b50d6 100644 --- a/libsrc/hyperion/Hyperion.cpp +++ b/libsrc/hyperion/Hyperion.cpp @@ -200,13 +200,16 @@ void Hyperion::stop() void Hyperion::freeObjects() { - //delete Background effect first that it does not kick in when other priorities are stopped - delete _BGEffectHandler; + //Disconnect Background effect first that it does not kick in when other priorities are stopped + _BGEffectHandler->disconnect(); //Remove all priorities to switch off all leds clear(-1,true); // delete components on exit of hyperion core + + delete _BGEffectHandler; + #if defined(ENABLE_BOBLIGHT_SERVER) delete _boblightServer; #endif diff --git a/libsrc/jsonserver/JsonServer.cpp b/libsrc/jsonserver/JsonServer.cpp index 5e77f95c..22937208 100644 --- a/libsrc/jsonserver/JsonServer.cpp +++ b/libsrc/jsonserver/JsonServer.cpp @@ -35,6 +35,7 @@ JsonServer::JsonServer(const QJsonDocument& config) JsonServer::~JsonServer() { qDeleteAll(_openConnections); + _openConnections.clear(); } void JsonServer::initServer() diff --git a/libsrc/mdns/MdnsBrowser.cpp b/libsrc/mdns/MdnsBrowser.cpp index f4f63500..dd45b226 100644 --- a/libsrc/mdns/MdnsBrowser.cpp +++ b/libsrc/mdns/MdnsBrowser.cpp @@ -2,9 +2,8 @@ #include #include -//Qt includes +// Qt includes #include - #include #include #include @@ -19,7 +18,8 @@ namespace { const bool verboseBrowser = false; -} //End of constants + const int SERVICE_LOOKUP_RETRIES = 5; +} // End of constants MdnsBrowser::MdnsBrowser(QObject* parent) : QObject(parent) @@ -30,7 +30,7 @@ MdnsBrowser::MdnsBrowser(QObject* parent) MdnsBrowser::~MdnsBrowser() { - qDeleteAll(_browsedServiceTypes); + _browsedServiceTypes.clear(); } void MdnsBrowser::browseForServiceType(const QByteArray& serviceType) @@ -38,11 +38,11 @@ void MdnsBrowser::browseForServiceType(const QByteArray& serviceType) if (!_browsedServiceTypes.contains(serviceType)) { DebugIf(verboseBrowser, _log, "Start new mDNS browser for serviceType [%s], Thread: %s", serviceType.constData(), QSTRING_CSTR(QThread::currentThread()->objectName())); - QMdnsEngine::Browser* newBrowser = new QMdnsEngine::Browser(&_server, serviceType, &_cache); + QSharedPointer newBrowser = QSharedPointer::create(&_server, serviceType, &_cache); - QObject::connect(newBrowser, &QMdnsEngine::Browser::serviceAdded, this, &MdnsBrowser::onServiceAdded); - QObject::connect(newBrowser, &QMdnsEngine::Browser::serviceUpdated, this, &MdnsBrowser::onServiceUpdated); - QObject::connect(newBrowser, &QMdnsEngine::Browser::serviceRemoved, this, &MdnsBrowser::onServiceRemoved); + QObject::connect(newBrowser.get(), &QMdnsEngine::Browser::serviceAdded, this, &MdnsBrowser::onServiceAdded); + QObject::connect(newBrowser.get(), &QMdnsEngine::Browser::serviceUpdated, this, &MdnsBrowser::onServiceUpdated); + QObject::connect(newBrowser.get(), &QMdnsEngine::Browser::serviceRemoved, this, &MdnsBrowser::onServiceRemoved); _browsedServiceTypes.insert(serviceType, newBrowser); } @@ -124,8 +124,8 @@ QHostAddress MdnsBrowser::getHostFirstAddress(const QByteArray& hostname) { DebugIf(verboseBrowser, _log, "IP-address for hostname [%s] not yet in cache, start resolver.", toBeResolvedHostName.constData()); qRegisterMetaType("Message"); - auto* resolver = new QMdnsEngine::Resolver(&_server, toBeResolvedHostName, &_cache); - connect(resolver, &QMdnsEngine::Resolver::resolved, this, &MdnsBrowser::onHostNameResolved); + _resolver.reset(new QMdnsEngine::Resolver(&_server, toBeResolvedHostName, &_cache)); + connect(_resolver.get(), &QMdnsEngine::Resolver::resolved, this, &MdnsBrowser::onHostNameResolved); } } } @@ -149,7 +149,7 @@ void MdnsBrowser::onHostNameResolved(const QHostAddress& address) bool MdnsBrowser::resolveAddress(Logger* log, const QString& hostname, QHostAddress& hostAddress, std::chrono::milliseconds timeout) { - DebugIf(verboseBrowser, _log, "Get address for hostname [%s], Thread: %s", QSTRING_CSTR(hostname), QSTRING_CSTR(QThread::currentThread()->objectName())); + DebugIf(verboseBrowser, log, "Get address for hostname [%s], Thread: %s", QSTRING_CSTR(hostname), QSTRING_CSTR(QThread::currentThread()->objectName())); bool isHostAddressOK{ false }; if (hostname.endsWith(".local") || hostname.endsWith(".local.")) @@ -158,20 +158,20 @@ bool MdnsBrowser::resolveAddress(Logger* log, const QString& hostname, QHostAddr if (hostAddress.isNull()) { - DebugIf(verboseBrowser, _log, "Wait for resolver on hostname [%s]", QSTRING_CSTR(hostname)); + DebugIf(verboseBrowser, log, "Wait for resolver on hostname [%s]", QSTRING_CSTR(hostname)); QEventLoop loop; - QTimer t; - QObject::connect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, &loop, &QEventLoop::quit); + QTimer timer; + QObject::connect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, &loop, &QEventLoop::quit); weakConnect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, - [&hostAddress, hostname](const QHostAddress& resolvedAddress) { - DebugIf(verboseBrowser, Logger::getInstance("MDNS"), "Resolver resolved hostname [%s] to address [%s], Thread: %s", QSTRING_CSTR(hostname), QSTRING_CSTR(resolvedAddress.toString()), QSTRING_CSTR(QThread::currentThread()->objectName())); + [&hostAddress, hostname, log](const QHostAddress& resolvedAddress) { + DebugIf(verboseBrowser, log, "Resolver resolved hostname [%s] to address [%s], Thread: %s", QSTRING_CSTR(hostname), QSTRING_CSTR(resolvedAddress.toString()), QSTRING_CSTR(QThread::currentThread()->objectName())); hostAddress = resolvedAddress; }); - QTimer::connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit); - t.start(static_cast(timeout.count())); + QTimer::connect(&timer, &QTimer::timeout, &loop, &QEventLoop::quit); + timer.start(static_cast(timeout.count())); loop.exec(); } @@ -206,8 +206,8 @@ QMdnsEngine::Record MdnsBrowser::getServiceInstanceRecord(const QByteArray& serv } QMdnsEngine::Record srvRecord; - bool found{ false }; - int retries = 5; + bool found { false }; + int retries { SERVICE_LOOKUP_RETRIES }; do { if (_cache.lookupRecord(service, QMdnsEngine::SRV, srvRecord)) @@ -393,10 +393,10 @@ QJsonArray MdnsBrowser::getServicesDiscoveredJson(const QByteArray& serviceType, QMap txtAttributes = txtRecord.attributes(); QVariantMap txtMap; - QMapIterator i(txtAttributes); - while (i.hasNext()) { - i.next(); - txtMap.insert(i.key(), i.value()); + QMapIterator iterator(txtAttributes); + while (iterator.hasNext()) { + iterator.next(); + txtMap.insert(iterator.key(), iterator.value()); } obj.insert("txt", QJsonObject::fromVariantMap(txtMap)); } diff --git a/libsrc/mdns/MdnsProvider.cpp b/libsrc/mdns/MdnsProvider.cpp index 40e17c7b..b894cac8 100644 --- a/libsrc/mdns/MdnsProvider.cpp +++ b/libsrc/mdns/MdnsProvider.cpp @@ -1,7 +1,7 @@ #include #include -//Qt includes +// Qt includes #include #include @@ -12,7 +12,7 @@ namespace { const bool verboseProvider = false; -} //End of constants +} // End of constants MdnsProvider::MdnsProvider(QObject* parent) : QObject(parent) @@ -24,58 +24,59 @@ MdnsProvider::MdnsProvider(QObject* parent) void MdnsProvider::init() { - _server = new QMdnsEngine::Server(); - _hostname = new QMdnsEngine::Hostname(_server); + _server.reset(new QMdnsEngine::Server()); + _hostname.reset(new QMdnsEngine::Hostname(_server.data())); - connect(_hostname, &QMdnsEngine::Hostname::hostnameChanged, this, &MdnsProvider::onHostnameChanged); + connect(_hostname.data(), &QMdnsEngine::Hostname::hostnameChanged, this, &MdnsProvider::onHostnameChanged); DebugIf(verboseProvider, _log, "Hostname [%s], isRegistered [%d]", _hostname->hostname().constData(), _hostname->isRegistered()); } MdnsProvider::~MdnsProvider() { - qDeleteAll(_providedServiceTypes); - - _hostname->deleteLater(); - _server->deleteLater(); + _providedServiceTypes.clear(); } void MdnsProvider::publishService(const QString& serviceType, quint16 servicePort, const QByteArray& serviceName) { - QMdnsEngine::Provider* provider(nullptr); - QByteArray type = MdnsServiceRegister::getServiceType(serviceType); + if (!type.isEmpty()) { DebugIf(verboseProvider, _log, "Publish new mDNS serviceType [%s], Thread: %s", type.constData(), QSTRING_CSTR(QThread::currentThread()->objectName())); if (!_providedServiceTypes.contains(type)) { - provider = new QMdnsEngine::Provider(_server, _hostname); - _providedServiceTypes.insert(type, provider); + QSharedPointer newProvider = QSharedPointer::create(_server.data(), _hostname.data()); + _providedServiceTypes.insert(type, newProvider); + + } + + QSharedPointer provider = _providedServiceTypes.value(type); + if (!provider.isNull()) + { + QMdnsEngine::Service service; + service.setType(type); + service.setPort(servicePort); + + QByteArray name(QHostInfo::localHostName().toUtf8()); + if (!serviceName.isEmpty()) + { + name.prepend(serviceName + "@"); + } + service.setName(name); + + QByteArray uuid = AuthManager::getInstance()->getID().toUtf8(); + const QMap attributes = {{"id", uuid}, {"version", HYPERION_VERSION}}; + service.setAttributes(attributes); + + DebugIf(verboseProvider, _log, "[%s], Name: [%s], Port: [%u] ", service.type().constData(), service.name().constData(), service.port()); + + provider->update(service); } else { - provider = _providedServiceTypes[type]; + Error(_log, "Not able to get hold of mDNS serviceType [%s]", type.constData()); } - - QMdnsEngine::Service service; - service.setType(type); - service.setPort(servicePort); - - QByteArray name(QHostInfo::localHostName().toUtf8()); - if (!serviceName.isEmpty()) - { - name.prepend(serviceName + "@"); - } - service.setName(name); - - QByteArray id = AuthManager::getInstance()->getID().toUtf8(); - const QMap attributes = { {"id", id}, {"version", HYPERION_VERSION} }; - service.setAttributes(attributes); - - DebugIf(verboseProvider, _log, "[%s], Name: [%s], Port: [%u] ", service.type().constData(), service.name().constData(), service.port()); - - provider->update(service); } } diff --git a/libsrc/utils/ImageResampler.cpp b/libsrc/utils/ImageResampler.cpp index c93dc70d..94b606da 100644 --- a/libsrc/utils/ImageResampler.cpp +++ b/libsrc/utils/ImageResampler.cpp @@ -159,10 +159,8 @@ void ImageResampler::processImage(const uint8_t * data, int width, int height, i break; } break; -#ifdef HAVE_TURBO_JPEG case PixelFormat::MJPEG: break; -#endif case PixelFormat::NO_CHANGE: Error(Logger::getInstance("ImageResampler"), "Invalid pixel format given"); break; diff --git a/libsrc/utils/Logger.cpp b/libsrc/utils/Logger.cpp index b34981c9..9822501f 100644 --- a/libsrc/utils/Logger.cpp +++ b/libsrc/utils/Logger.cpp @@ -2,7 +2,6 @@ #include #include -#include #ifndef _WIN32 #include @@ -15,7 +14,8 @@ #include #include #include -#include +#include + #if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0)) QRecursiveMutex Logger::MapLock; @@ -38,6 +38,7 @@ const size_t MAX_IDENTIFICATION_LENGTH = 22; QAtomicInteger LoggerCount = 0; QAtomicInteger LoggerId = 0; +const int MAX_LOG_MSG_BUFFERED = 500; const int MaxRepeatCountSize = 200; QThreadStorage RepeatCount; QThreadStorage RepeatMessage; @@ -51,8 +52,7 @@ Logger* Logger::getInstance(const QString & name, const QString & subName, Logge if (log == nullptr) { log = new Logger(name, subName, minLevel); - LoggerMap.insert(name, log); // compat version, replace it with following line if we have 100% c++11 - //LoggerMap.emplace(name, log); // not compat with older linux distro's e.g. wheezy + LoggerMap.insert(name + subName, log); connect(log, &Logger::newLogMessage, LoggerManager::getInstance(), &LoggerManager::handleNewLogMessage); } @@ -105,7 +105,7 @@ Logger::LogLevel Logger::getLogLevel(const QString & name, const QString & subNa Logger::Logger (const QString & name, const QString & subName, LogLevel minLevel) : QObject() , _name(name) - , _subname(subName) + , _subName(subName) , _syslogEnabled(true) , _loggerId(LoggerId++) , _minLevel(static_cast(minLevel)) @@ -161,7 +161,7 @@ void Logger::write(const Logger::T_LOG_MESSAGE & message) .toStdString() << std::endl; - newLogMessage(message); + emit newLogMessage(message); } void Logger::Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...) @@ -195,7 +195,7 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u }; if (RepeatMessage.localData().loggerName == _name && - RepeatMessage.localData().loggerSubName == _subname && + RepeatMessage.localData().loggerSubName == _subName && RepeatMessage.localData().function == func && RepeatMessage.localData().message == msg && RepeatMessage.localData().line == line) @@ -213,7 +213,7 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u Logger::T_LOG_MESSAGE logMsg; logMsg.loggerName = _name; - logMsg.loggerSubName = _subname; + logMsg.loggerSubName = _subName; logMsg.function = QString(func); logMsg.line = line; logMsg.fileName = FileUtils::getBaseName(sourceFile); @@ -233,11 +233,36 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u LoggerManager::LoggerManager() : QObject() - , _loggerMaxMsgBufferSize(200) + , _loggerMaxMsgBufferSize(MAX_LOG_MSG_BUFFERED) { _logMessageBuffer.reserve(_loggerMaxMsgBufferSize); } +QJsonArray LoggerManager::getLogMessageBuffer(Logger::LogLevel filter) const +{ + QJsonArray messageArray; + { + for (const auto &logLine : std::as_const(_logMessageBuffer)) + { + if (logLine.level >= filter) + { + QJsonObject message; + message["loggerName"] = logLine.loggerName; + message["loggerSubName"] = logLine.loggerSubName; + message["function"] = logLine.function; + message["line"] = QString::number(logLine.line); + message["fileName"] = logLine.fileName; + message["message"] = logLine.message; + message["levelString"] = logLine.levelString; + message["utime"] = QString::number(logLine.utime); + + messageArray.append(message); + } + } + } + return messageArray; +} + void LoggerManager::handleNewLogMessage(const Logger::T_LOG_MESSAGE & msg) { _logMessageBuffer.push_back(msg); diff --git a/libsrc/utils/RgbChannelAdjustment.cpp b/libsrc/utils/RgbChannelAdjustment.cpp index 25f24a91..2079c7aa 100644 --- a/libsrc/utils/RgbChannelAdjustment.cpp +++ b/libsrc/utils/RgbChannelAdjustment.cpp @@ -1,16 +1,14 @@ #include RgbChannelAdjustment::RgbChannelAdjustment(QString channelName) - : _channelName(channelName) - , _log(Logger::getInstance(channelName)) - , _brightness(0) + : RgbChannelAdjustment(0, 0, 0, channelName) { - resetInitialized(); } -RgbChannelAdjustment::RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB, QString channelName) +RgbChannelAdjustment::RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB, QString channelName ) : _channelName(channelName) - , _log(Logger::getInstance(channelName)) + , _log(Logger::getInstance("CHANNEL_" + channelName.toUpper())) + , _brightness(0) { setAdjustment(adjustR, adjustG, adjustB); } diff --git a/libsrc/utils/RgbTransform.cpp b/libsrc/utils/RgbTransform.cpp index cc1a74e0..9a988ed5 100644 --- a/libsrc/utils/RgbTransform.cpp +++ b/libsrc/utils/RgbTransform.cpp @@ -2,13 +2,15 @@ #include RgbTransform::RgbTransform() + : RgbTransform::RgbTransform(1.0, 1.0, 1.0, 0.0, false, 100, 100) { - init(1.0, 1.0, 1.0, 0.0, false, 100, 100); } RgbTransform::RgbTransform(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation) + : _brightness(brightness) + , _brightnessCompensation(brightnessCompensation) { - init(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, brightness, brightnessCompensation); + init(gammaR, gammaG, gammaB, backlightThreshold, backlightColored, _brightness, _brightnessCompensation); } void RgbTransform::init(double gammaR, double gammaG, double gammaB, double backlightThreshold, bool backlightColored, uint8_t brightness, uint8_t brightnessCompensation) diff --git a/libsrc/webserver/WebServer.cpp b/libsrc/webserver/WebServer.cpp index a5733d95..b2da8704 100644 --- a/libsrc/webserver/WebServer.cpp +++ b/libsrc/webserver/WebServer.cpp @@ -16,6 +16,13 @@ namespace { const char HTTPS_SERVICE_TYPE[] = "https"; const char HYPERION_SERVICENAME[] = "Hyperion"; + const char WEBSERVER_DEFAULT_PATH[] = ":/webconfig"; + const char WEBSERVER_DEFAULT_CRT_PATH[] = ":/hyperion.crt"; + const char WEBSERVER_DEFAULT_KEY_PATH[] = ":/hyperion.key"; + + quint16 WEBSERVER_DEFAULT_PORT = 8090; + quint16 WBSERVERR_DEFAULT_SSL_PORT = 8092; + } //End of constants WebServer::WebServer(const QJsonDocument& config, bool useSsl, QObject* parent) @@ -23,6 +30,7 @@ WebServer::WebServer(const QJsonDocument& config, bool useSsl, QObject* parent) , _config(config) , _useSsl(useSsl) , _log(Logger::getInstance("WEBSERVER")) + , _port(WEBSERVER_DEFAULT_PORT) , _server() { } @@ -41,7 +49,6 @@ void WebServer::initServer() if (_useSsl) { _server->setUseSecure(); - WEBSERVER_DEFAULT_PORT = 8092; } connect(_server, &QtHttpServer::started, this, &WebServer::onServerStarted); @@ -111,7 +118,7 @@ void WebServer::handleSettingsUpdate(settings::type type, const QJsonDocument& c _staticFileServing->setBaseUrl(_baseUrl); // ssl different port - quint16 newPort = _useSsl ? obj["sslPort"].toInt(WEBSERVER_DEFAULT_PORT) : obj["port"].toInt(WEBSERVER_DEFAULT_PORT); + quint16 newPort = _useSsl ? obj["sslPort"].toInt(WBSERVERR_DEFAULT_SSL_PORT) : obj["port"].toInt(WEBSERVER_DEFAULT_PORT); if (_port != newPort) { _port = newPort; diff --git a/src/hyperion-aml/hyperion-aml.cpp b/src/hyperion-aml/hyperion-aml.cpp index 7bcc106e..c0a3caff 100644 --- a/src/hyperion-aml/hyperion-aml.cpp +++ b/src/hyperion-aml/hyperion-aml.cpp @@ -164,5 +164,8 @@ int main(int argc, char ** argv) Error(log, "%s", e.what()); return -1; } + + Logger::deleteInstance(); + return 0; } diff --git a/src/hyperion-dispmanx/hyperion-dispmanx.cpp b/src/hyperion-dispmanx/hyperion-dispmanx.cpp index 55ccee04..888c7ff1 100644 --- a/src/hyperion-dispmanx/hyperion-dispmanx.cpp +++ b/src/hyperion-dispmanx/hyperion-dispmanx.cpp @@ -167,6 +167,8 @@ int main(int argc, char ** argv) Error(log, "%s", e.what()); return -1; } + + Logger::deleteInstance(); return 0; } diff --git a/src/hyperion-framebuffer/hyperion-framebuffer.cpp b/src/hyperion-framebuffer/hyperion-framebuffer.cpp index 8f743d48..e4c4f4e6 100644 --- a/src/hyperion-framebuffer/hyperion-framebuffer.cpp +++ b/src/hyperion-framebuffer/hyperion-framebuffer.cpp @@ -167,5 +167,8 @@ int main(int argc, char ** argv) Error(log, "%s", e.what()); return -1; } + + Logger::deleteInstance(); + return 0; } diff --git a/src/hyperion-osx/hyperion-osx.cpp b/src/hyperion-osx/hyperion-osx.cpp index 7a907935..83caf8c8 100644 --- a/src/hyperion-osx/hyperion-osx.cpp +++ b/src/hyperion-osx/hyperion-osx.cpp @@ -162,5 +162,8 @@ int main(int argc, char ** argv) Error(log, "%s", e.what()); return -1; } + + Logger::deleteInstance(); + return 0; } diff --git a/src/hyperion-qt/hyperion-qt.cpp b/src/hyperion-qt/hyperion-qt.cpp index 2e12f2f6..692ca9df 100644 --- a/src/hyperion-qt/hyperion-qt.cpp +++ b/src/hyperion-qt/hyperion-qt.cpp @@ -167,5 +167,8 @@ int main(int argc, char ** argv) Error(log, "%s", e.what()); return -1; } + + Logger::deleteInstance(); + return 0; } diff --git a/src/hyperion-remote/hyperion-remote.cpp b/src/hyperion-remote/hyperion-remote.cpp index e7fdc453..277f1b2a 100644 --- a/src/hyperion-remote/hyperion-remote.cpp +++ b/src/hyperion-remote/hyperion-remote.cpp @@ -410,5 +410,7 @@ int main(int argc, char * argv[]) return 1; } + Logger::deleteInstance(); + return 0; } diff --git a/src/hyperion-v4l2/hyperion-v4l2.cpp b/src/hyperion-v4l2/hyperion-v4l2.cpp index daef9567..b166948b 100644 --- a/src/hyperion-v4l2/hyperion-v4l2.cpp +++ b/src/hyperion-v4l2/hyperion-v4l2.cpp @@ -287,5 +287,7 @@ int main(int argc, char** argv) return 1; } + Logger::deleteInstance(); + return 0; } diff --git a/src/hyperion-x11/hyperion-x11.cpp b/src/hyperion-x11/hyperion-x11.cpp index d506bf1d..3cac09cb 100644 --- a/src/hyperion-x11/hyperion-x11.cpp +++ b/src/hyperion-x11/hyperion-x11.cpp @@ -166,5 +166,7 @@ int main(int argc, char ** argv) return -1; } + Logger::deleteInstance(); + return 0; } diff --git a/src/hyperion-xcb/hyperion-xcb.cpp b/src/hyperion-xcb/hyperion-xcb.cpp index 06a94f8d..16e0af1b 100644 --- a/src/hyperion-xcb/hyperion-xcb.cpp +++ b/src/hyperion-xcb/hyperion-xcb.cpp @@ -165,5 +165,7 @@ int main(int argc, char ** argv) return -1; } + Logger::deleteInstance(); + return 0; } diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index 0416aa70..74d71df6 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -1,5 +1,3 @@ -#include -#include #include #include @@ -10,8 +8,6 @@ #include #include #include -#include -#include #include #include @@ -92,8 +88,8 @@ HyperionDaemon::HyperionDaemon(const QString& rootPath, QObject* parent, bool lo , _osxGrabber(nullptr) , _qtGrabber(nullptr) , _dxGrabber(nullptr) - , _ssdp(nullptr) , _audioGrabber(nullptr) + , _ssdp(nullptr) , _eventHandler(nullptr) , _osEventHandler(nullptr) , _eventScheduler(nullptr) @@ -239,9 +235,13 @@ void HyperionDaemon::handleInstanceStateChange(InstanceState state, quint8 insta break; case InstanceState::H_STOPPED: + case InstanceState::H_ON_STOP: + case InstanceState::H_CREATED: + case InstanceState::H_DELETED: break; default: + qWarning() << "HyperionDaemon::handleInstanceStateChange - Unhandled state:" << static_cast(state); break; } } @@ -271,30 +271,27 @@ void HyperionDaemon::freeObjects() #ifdef ENABLE_MDNS if (_mDNSProvider != nullptr) { - auto mDnsThread = _mDNSProvider->thread(); + auto *mDnsThread = _mDNSProvider->thread(); mDnsThread->quit(); mDnsThread->wait(); - delete mDnsThread; _mDNSProvider = nullptr; } #endif if (_jsonServer != nullptr) { - auto jsonThread = _jsonServer->thread(); + auto *jsonThread = _jsonServer->thread(); jsonThread->quit(); jsonThread->wait(); - delete jsonThread; _jsonServer = nullptr; } #if defined(ENABLE_FLATBUF_SERVER) if (_flatBufferServer != nullptr) { - auto flatBufferServerThread = _flatBufferServer->thread(); + auto *flatBufferServerThread = _flatBufferServer->thread(); flatBufferServerThread->quit(); flatBufferServerThread->wait(); - delete flatBufferServerThread; _flatBufferServer = nullptr; } #endif @@ -302,10 +299,9 @@ void HyperionDaemon::freeObjects() #if defined(ENABLE_PROTOBUF_SERVER) if (_protoServer != nullptr) { - auto protoServerThread = _protoServer->thread(); + auto *protoServerThread = _protoServer->thread(); protoServerThread->quit(); protoServerThread->wait(); - delete protoServerThread; _protoServer = nullptr; } #endif @@ -313,28 +309,25 @@ void HyperionDaemon::freeObjects() //ssdp before webserver if (_ssdp != nullptr) { - auto ssdpThread = _ssdp->thread(); + auto *ssdpThread = _ssdp->thread(); ssdpThread->quit(); ssdpThread->wait(); - delete ssdpThread; _ssdp = nullptr; } if (_webserver != nullptr) { - auto webserverThread = _webserver->thread(); + auto *webserverThread = _webserver->thread(); webserverThread->quit(); - webserverThread->wait(); - delete webserverThread; + webserverThread->wait();; _webserver = nullptr; } if (_sslWebserver != nullptr) { - auto sslWebserverThread = _sslWebserver->thread(); + auto *sslWebserverThread = _sslWebserver->thread(); sslWebserverThread->quit(); sslWebserverThread->wait(); - delete sslWebserverThread; _sslWebserver = nullptr; } @@ -342,14 +335,15 @@ void HyperionDaemon::freeObjects() _instanceManager->stopAll(); delete _amlGrabber; - if (_dispmanx != nullptr) - delete _dispmanx; + delete _dispmanx; delete _fbGrabber; delete _osxGrabber; delete _qtGrabber; delete _dxGrabber; delete _videoGrabber; delete _audioGrabber; + delete _x11Grabber; + delete _xcbGrabber; _videoGrabber = nullptr; _amlGrabber = nullptr; @@ -359,6 +353,8 @@ void HyperionDaemon::freeObjects() _qtGrabber = nullptr; _dxGrabber = nullptr; _audioGrabber = nullptr; + _x11Grabber = nullptr; + _xcbGrabber = nullptr; } void HyperionDaemon::startNetworkServices() @@ -934,6 +930,8 @@ void HyperionDaemon::startCecHandler() connect(cecHandlerThread, &QThread::started, _cecHandler, &CECHandler::start); connect(cecHandlerThread, &QThread::finished, _cecHandler, &CECHandler::stop); + connect(cecHandlerThread, &QThread::finished, _cecHandler, &CECHandler::deleteLater); + connect(this, &HyperionDaemon::settingsChanged, _cecHandler, &CECHandler::handleSettingsUpdate); Info(_log, "CEC event handler created"); @@ -949,13 +947,11 @@ void HyperionDaemon::stopCecHandler() #if defined(ENABLE_CEC) if (_cecHandler != nullptr) { - auto cecHandlerThread = _cecHandler->thread(); + auto *cecHandlerThread = _cecHandler->thread(); cecHandlerThread->quit(); cecHandlerThread->wait(); - delete cecHandlerThread; _cecHandler = nullptr; } Info(_log, "CEC handler stopped"); #endif } - diff --git a/src/hyperiond/hyperiond.h b/src/hyperiond/hyperiond.h index 8134d423..f0198f6d 100644 --- a/src/hyperiond/hyperiond.h +++ b/src/hyperiond/hyperiond.h @@ -193,7 +193,7 @@ private: HyperionIManager* _instanceManager; AuthManager* _authManager; #ifdef ENABLE_MDNS - MdnsProvider* _mDNSProvider; + MdnsProvider* _mDNSProvider; #endif NetOrigin* _netOrigin; #if defined(ENABLE_EFFECTENGINE) @@ -217,7 +217,7 @@ private: OsEventHandler* _osEventHandler; EventScheduler* _eventScheduler; #ifdef ENABLE_CEC -CECHandler* _cecHandler; + CECHandler* _cecHandler; #endif #if defined(ENABLE_FLATBUF_SERVER)