Start SmartPointers (#1679)

* Refactor to fix #1671

* Add GUI/NonGUI mode to info page

* Do not show lock config, if in non-UI mode

* Updae Changelog

* Correct includes

* Ensure key member initialization - RGB Channels

* Ensure key member initialization - WebServer

* Update RGBChannels

* Fix initialization order

* Fix key when inserting new logger in LoggerMap,
Prepare logBuffer-JSON snapshot view in LoggerManager,
Increase buffered loglines to 500

* Fix Memory leak in GrabberWrapper

* Fix Memory leak in BlackBorderProcessor

* Fix Memory leak in BlackBorderProcessor

* use ninja generator under macos

* Fix BGEffectHandler destruction

* Fix Mdns code

* Clear list after applying qDeleteAll

* Fix deletion of CecHandler

* Fix memory leak caused by wrong buffer allocation

* Remove extra pixel consistently

* Change mDNS to Qt SmartPointers

* Correct removal

* Fix usage of _width/_height (they are the output resolution, not the screen resolution)
That avoids unnecessary resizing of the output image with every transferFrame call

* Move main non Thread Objects to Smart Pointers

* Refactor Hyperion Daemon unsing smartpointers

* Correction

* Correct typos/ align text

* Fix startGrabberDispmanx

* Fix startGrabberDispmanx

* Address CodeQL finding

* Create Screen grabbers via Template

* Fix typo

* Change way of logging

* Revert change

* Address deprecation warning

* Correct auto screen grabber evaluation

---------

Co-authored-by: Paulchen-Panther <16664240+Paulchen-Panther@users.noreply.github.com>
This commit is contained in:
LordGrey 2024-02-25 17:35:39 +01:00 committed by GitHub
parent bb40778a3d
commit 31df065c0f
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
65 changed files with 818 additions and 927 deletions

View File

@ -88,6 +88,7 @@ Note: The wizard will configure an APIv2 capable bridge always with Entertainmen
- Changed default build from Stretch to Buster
- Support Qt 6.7, Update to Protobuf 25.1, Update mbedTLS to v3.4.0, Update flatbuffers to v23.5.26
- Use C++17 standard as default
- Started using SmartPointers (#981)
- Added Pull Request (PR) installation script, allowing users to test development builds savely on Linux
- Fixed missing include limits in QJsonSchemaChecker - Thanks @Portisch
- Fixed dependencies for deb packages in Debian Bookworm (#1579) - Thanks @hg42, @Psirus

View File

@ -13,10 +13,9 @@ class EventHandler : public QObject
Q_OBJECT
public:
EventHandler();
~EventHandler() override;
static EventHandler* getInstance();
static QScopedPointer<EventHandler>& getInstance();
public slots:
@ -40,6 +39,12 @@ protected:
Logger * _log {};
private:
EventHandler();
EventHandler(const EventHandler&) = delete;
EventHandler& operator=(const EventHandler&) = delete;
static QScopedPointer<EventHandler> instance;
bool _isSuspended;
bool _isIdle;
};

View File

@ -12,6 +12,9 @@ class AmlogicWrapper : public GrabberWrapper
{
Q_OBJECT
public:
static constexpr const char* GRABBERTYPE = "Amlogic";
///
/// Constructs the Amlogic frame grabber
///
@ -22,6 +25,12 @@ public:
AmlogicWrapper(int pixelDecimation=GrabberWrapper::DEFAULT_PIXELDECIMATION,
int updateRate_Hz=GrabberWrapper::DEFAULT_RATE_HZ);
///
/// Constructs the Amlogic frame grabber from configuration settings
///
AmlogicWrapper(const QJsonDocument& grabberConfig = QJsonDocument());
public slots:
///
/// Performs a single frame grab and computes the led-colors

View File

@ -6,6 +6,8 @@
class DirectXWrapper: public GrabberWrapper
{
public:
static constexpr const char* GRABBERTYPE = "DirectX";
///
/// Constructs the DirectX grabber with a specified grab size and update rate.
///
@ -25,6 +27,11 @@ public:
int cropTop=0, int cropBottom=0
);
///
/// Constructs the QT frame grabber from configuration settings
///
DirectXWrapper(const QJsonDocument& grabberConfig = QJsonDocument());
///
/// Destructor of this DirectX grabber. Releases any claimed resources.
///

View File

@ -36,9 +36,9 @@ public:
///
/// @brief Determine if the bcm library is available.
///
/// @return Zero, on success (i.e. library is present), else negative
/// @return true, on success (i.e. library is present), else false
///
bool isAvailable();
bool isAvailable() override;
///
/// @brief Opens the input device.

View File

@ -13,6 +13,9 @@ class DispmanxWrapper: public GrabberWrapper
{
Q_OBJECT
public:
static constexpr const char* GRABBERTYPE = "DispmanX";
///
/// Constructs the dispmanx frame grabber with a specified grab size and update rate.
///
@ -23,9 +26,12 @@ public:
int pixelDecimation=GrabberWrapper::DEFAULT_PIXELDECIMATION
);
bool screenInit();
///
/// Constructs the QT frame grabber from configuration settings
///
DispmanxWrapper(const QJsonDocument& grabberConfig = QJsonDocument());
bool available = false;
bool screenInit();
///
/// Starts the grabber which produces led values with the specified update rate

View File

@ -17,7 +17,7 @@ public:
///
/// @param[in] device The framebuffer device name/path
///
FramebufferFrameGrabber(const QString & device="/dev/fb0");
FramebufferFrameGrabber(int deviceIdx = 0);
~FramebufferFrameGrabber() override;
@ -45,7 +45,7 @@ public:
///@brief Set new width and height for framegrabber, overwrite Grabber.h implementation
bool setWidthHeight(int width, int height) override;
QString getPath() const {return _fbDevice;}
QString getPath() const {return QString("/dev/fb%1").arg(_input);}
///
/// @brief Discover Framebuffer screens available (for configuration).
@ -62,7 +62,7 @@ private:
bool closeDevice();
bool getScreenInfo();
/// Framebuffer device e.g. /dev/fb0
// /// Framebuffer device e.g. /dev/fb0
QString _fbDevice;
int _fbfd;

View File

@ -12,18 +12,26 @@ class FramebufferWrapper: public GrabberWrapper
{
Q_OBJECT
public:
static constexpr const char* GRABBERTYPE = "FB";
///
/// Constructs the framebuffer frame grabber with a specified grab size and update rate.
///
/// @param[in] updateRate_Hz The image grab rate [Hz]
/// @param[in] device Framebuffer device name/path
/// @param[in] deviceIdx Framebuffer device index
/// @param[in] pixelDecimation Decimation factor for image [pixels]
///
FramebufferWrapper( int updateRate_Hz=GrabberWrapper::DEFAULT_RATE_HZ,
const QString & device = "/dev/fb0",
int deviceIdx = 0,
int pixelDecimation=GrabberWrapper::DEFAULT_PIXELDECIMATION
);
///
/// Constructs the QT frame grabber from configuration settings
///
FramebufferWrapper(const QJsonDocument& grabberConfig = QJsonDocument());
public slots:
///
/// Performs a single frame grab and computes the led-colors

View File

@ -11,6 +11,8 @@ class OsxWrapper: public GrabberWrapper
{
Q_OBJECT
public:
static constexpr const char* GRABBERTYPE = "OSX";
///
/// Constructs the osx frame grabber with a specified grab size and update rate.
///
@ -23,6 +25,12 @@ public:
int pixelDecimation=GrabberWrapper::DEFAULT_PIXELDECIMATION
);
///
/// Constructs the QT frame grabber from configuration settings
///
OsxWrapper(const QJsonDocument& grabberConfig = QJsonDocument());
public slots:
///
/// Performs a single frame grab and computes the led-colors

View File

@ -1,5 +1,8 @@
#pragma once
#include <QJsonObject>
#include <QStringLiteral>
#include <hyperion/GrabberWrapper.h>
#include <grabber/qt/QtGrabber.h>
@ -8,7 +11,10 @@
///
class QtWrapper: public GrabberWrapper
{
public:
static constexpr const char* GRABBERTYPE = "Qt";
///
/// Constructs the QT frame grabber with a specified grab size and update rate.
///
@ -19,7 +25,6 @@ public:
/// @param[in] cropRight Remove from right [pixels]
/// @param[in] cropTop Remove from top [pixels]
/// @param[in] cropBottom Remove from bottom [pixels]
///
QtWrapper( int updateRate_Hz=GrabberWrapper::DEFAULT_RATE_HZ,
int display=0,
@ -28,6 +33,11 @@ public:
int cropTop=0, int cropBottom=0
);
///
/// Constructs the QT frame grabber from configuration settings
///
QtWrapper(const QJsonDocument& grabberConfig = QJsonDocument());
///
/// Starts the grabber which produces led values with the specified update rate
///

View File

@ -7,7 +7,6 @@
#undef None
#endif
///
/// The X11Wrapper uses an instance of the X11Grabber to obtain ImageRgb's from the displayed content.
/// This ImageRgb is processed to a ColorRgb for each led and committed to the attached Hyperion.
@ -15,6 +14,8 @@
class X11Wrapper: public GrabberWrapper
{
public:
static constexpr const char* GRABBERTYPE = "X11";
///
/// Constructs the X11 frame grabber with a specified grab size and update rate.
///
@ -27,6 +28,11 @@ public:
int cropTop=0, int cropBottom=0
);
///
/// Constructs the X11 frame grabber from configuration settings
///
X11Wrapper(const QJsonDocument& grabberConfig = QJsonDocument());
///
/// Destructor of this frame grabber. Releases any claimed resources.
///

View File

@ -11,12 +11,30 @@
class XcbWrapper: public GrabberWrapper
{
public:
static constexpr const char* GRABBERTYPE = "XCB";
///
/// Constructs the XCB frame grabber with a specified grab size and update rate.
///
/// @param[in] updateRate_Hz The image grab rate [Hz]
/// @param[in] pixelDecimation Decimation factor for image [pixels]
/// @param[in] cropLeft Remove from left [pixels]
/// @param[in] cropRight Remove from right [pixels]
/// @param[in] cropTop Remove from top [pixels]
/// @param[in] cropBottom Remove from bottom [pixels]
///
XcbWrapper( int updateRate_Hz=GrabberWrapper::DEFAULT_RATE_HZ,
int pixelDecimation=GrabberWrapper::DEFAULT_PIXELDECIMATION,
int cropLeft=0, int cropRight=0,
int cropTop=0, int cropBottom=0
);
///
/// Constructs the XCB frame grabber from configuration settings
///
XcbWrapper(const QJsonDocument& grabberConfig = QJsonDocument());
~XcbWrapper() override;
public slots:

View File

@ -113,6 +113,13 @@ public:
QString getGrabberName() const { return _grabberName; }
///
/// @brief Determine if the grabber is available.
///
/// @return true, on success (i.e. library is present), else false
///
virtual bool isAvailable() { return _isAvailable; }
public slots:
virtual void handleEvent(Event event) {}
@ -168,10 +175,15 @@ protected:
// Device states
/// Is the device available?
bool _isAvailable;
/// Is the device enabled?
bool _isEnabled;
/// Is the device in error state and stopped?
bool _isDeviceInError;
};

View File

@ -32,6 +32,14 @@ class GrabberWrapper : public QObject
{
Q_OBJECT
public:
static constexpr const char* GRABBERTYPE = "Base";
template<typename GrabberType>
static QSharedPointer<GrabberType> create(const QJsonDocument& config) {
return QSharedPointer<GrabberType>::create(config);
}
GrabberWrapper(const QString& grabberName, Grabber * ggrabber,int updateRate_Hz = DEFAULT_RATE_HZ);
~GrabberWrapper() override;
@ -71,6 +79,11 @@ public:
///
virtual bool isActive() const;
virtual bool isAvailable() { return _isAvailable; }
QString getName() { return _grabberName; }
///
/// @brief Get active grabber name
/// @param hyperionInd The instance index
@ -195,4 +208,6 @@ protected:
/// The image used for grabbing frames
Image<ColorRgb> _image;
bool _isAvailable;
};

View File

@ -17,6 +17,7 @@
#include <QByteArray>
#include <QMap>
#include <QJsonArray>
#include <QScopedPointer>
#include <QSharedPointer>
// Utility includes
@ -39,21 +40,17 @@ private:
///
// Run MdnsBrowser as singleton
MdnsBrowser(QObject* parent = nullptr);
~MdnsBrowser() override;
public:
static MdnsBrowser& getInstance()
{
static MdnsBrowser* instance = new MdnsBrowser();
return *instance;
}
MdnsBrowser(const MdnsBrowser&) = delete;
MdnsBrowser(MdnsBrowser&&) = delete;
MdnsBrowser& operator=(const MdnsBrowser&) = delete;
MdnsBrowser& operator=(MdnsBrowser&&) = delete;
static QScopedPointer<MdnsBrowser> instance;
public:
~MdnsBrowser() override;
static QScopedPointer<MdnsBrowser>& getInstance();
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;

View File

@ -7,6 +7,7 @@
#include <QAtomicInteger>
#include <QList>
#include <QJsonArray>
#include <QScopedPointer>
#if (QT_VERSION >= QT_VERSION_CHECK(5, 14, 0))
#include <QRecursiveMutex>
@ -106,8 +107,19 @@ class LoggerManager : public QObject
{
Q_OBJECT
private:
// Run LoggerManager as singleton
LoggerManager();
LoggerManager(const LoggerManager&) = delete;
LoggerManager(LoggerManager&&) = delete;
LoggerManager& operator=(const LoggerManager&) = delete;
LoggerManager& operator=(LoggerManager&&) = delete;
static QScopedPointer<LoggerManager> instance;
public:
static LoggerManager* getInstance();
~LoggerManager() override;
static QScopedPointer<LoggerManager>& getInstance();
public slots:
void handleNewLogMessage(const Logger::T_LOG_MESSAGE&);
@ -117,7 +129,6 @@ signals:
void newLogMessage(const Logger::T_LOG_MESSAGE&);
private:
LoggerManager();
QList<Logger::T_LOG_MESSAGE> _logMessageBuffer;
const int _loggerMaxMsgBufferSize;

View File

@ -111,7 +111,7 @@ namespace NetUtils {
if (hostname.endsWith(".local") || hostname.endsWith(".local."))
{
QHostAddress resolvedAddress;
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "resolveAddress",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "resolveAddress",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(bool, isHostAddressOK),
Q_ARG(Logger*, log), Q_ARG(QString, hostname), Q_ARG(QHostAddress&, resolvedAddress));
@ -163,7 +163,7 @@ namespace NetUtils {
if (hostname.endsWith("._tcp.local"))
{
//Treat hostname as service instance name that requires to be resolved into an mDNS-Hostname first
QMdnsEngine::Record service = MdnsBrowser::getInstance().getServiceInstanceRecord(hostname.toUtf8());
QMdnsEngine::Record service = MdnsBrowser::getInstance().data()->getServiceInstanceRecord(hostname.toUtf8());
if (!service.target().isEmpty())
{
Info(log, "Resolved service [%s] to mDNS hostname [%s], service port [%d]", QSTRING_CSTR(hostname), service.target().constData(), service.port());

View File

@ -4,6 +4,7 @@
#include <QObject>
#include <QString>
#include <QJsonDocument>
#include <QScopedPointer>
// hyperion / utils
#include <utils/Logger.h>
@ -64,7 +65,7 @@ public slots:
void onServerStopped ();
void onServerStarted (quint16 port);
void onServerError (QString msg);
void onServerError (const QString& msg);
///
/// @brief Handle settings update from Hyperion Settingsmanager emit or this constructor
@ -90,7 +91,7 @@ private:
QString _baseUrl;
quint16 _port;
StaticFileServing* _staticFileServing;
QtHttpServer* _server;
QScopedPointer<QtHttpServer> _server;
bool _inited = false;
};

View File

@ -142,7 +142,7 @@ void JsonAPI::initialize()
}
//notify eventhadler on suspend/resume/idle requests
connect(this, &JsonAPI::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
connect(this, &JsonAPI::signalEvent, EventHandler::getInstance().data(), &EventHandler::handleEvent);
connect(_ledStreamTimer, &QTimer::timeout, this, &JsonAPI::streamLedColorsUpdate, Qt::UniqueConnection);
}
@ -1077,7 +1077,7 @@ void JsonAPI::handleConfigRestoreCommand(const QJsonObject &message, const QStri
}
}
void JsonAPI::handleSchemaGetCommand(const QJsonObject &message, const QString &command, int tan)
void JsonAPI::handleSchemaGetCommand(const QJsonObject& /*message*/, const QString &command, int tan)
{
// create result
QJsonObject schemaJson, alldevices, properties;
@ -1226,7 +1226,7 @@ void JsonAPI::handleLoggingCommand(const QJsonObject &message, const QString &co
if (!_streaming_logging_activated)
{
_streaming_logging_reply["command"] = command + "-update";
connect(LoggerManager::getInstance(), &LoggerManager::newLogMessage, this, &JsonAPI::incommingLogMessage);
connect(LoggerManager::getInstance().data(), &LoggerManager::newLogMessage, this, &JsonAPI::incommingLogMessage);
emit incommingLogMessage (Logger::T_LOG_MESSAGE{}); // needed to trigger log sending
Debug(_log, "log streaming activated for client %s", _peerAddress.toStdString().c_str());
@ -1236,7 +1236,7 @@ void JsonAPI::handleLoggingCommand(const QJsonObject &message, const QString &co
{
if (_streaming_logging_activated)
{
disconnect(LoggerManager::getInstance(), &LoggerManager::newLogMessage, this, &JsonAPI::incommingLogMessage);
disconnect(LoggerManager::getInstance().data(), &LoggerManager::newLogMessage, this, &JsonAPI::incommingLogMessage);
_streaming_logging_activated = false;
Debug(_log, "log streaming deactivated for client %s", _peerAddress.toStdString().c_str());
}
@ -1700,59 +1700,54 @@ void JsonAPI::handleInputSourceCommand(const QJsonObject& message, const QString
QJsonObject device;
#ifdef ENABLE_QT
QtGrabber* qtgrabber = new QtGrabber();
QScopedPointer<QtGrabber> qtgrabber(new QtGrabber());
device = qtgrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete qtgrabber;
#endif
#ifdef ENABLE_DX
DirectXGrabber* dxgrabber = new DirectXGrabber();
QScopedPointer<DirectXGrabber> dxgrabber (new DirectXGrabber());
device = dxgrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete dxgrabber;
#endif
#ifdef ENABLE_X11
X11Grabber* x11Grabber = new X11Grabber();
QScopedPointer<X11Grabber> x11Grabber(new X11Grabber());
device = x11Grabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete x11Grabber;
#endif
#ifdef ENABLE_XCB
XcbGrabber* xcbGrabber = new XcbGrabber();
QScopedPointer<XcbGrabber> xcbGrabber (new XcbGrabber());
device = xcbGrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete xcbGrabber;
#endif
//Ignore FB for Amlogic, as it is embedded in the Amlogic grabber itself
#if defined(ENABLE_FB) && !defined(ENABLE_AMLOGIC)
FramebufferFrameGrabber* fbGrabber = new FramebufferFrameGrabber();
QScopedPointer<FramebufferFrameGrabber> fbGrabber(new FramebufferFrameGrabber());
device = fbGrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete fbGrabber;
#endif
#if defined(ENABLE_DISPMANX)
DispmanxFrameGrabber* dispmanx = new DispmanxFrameGrabber();
QScopedPointer<DispmanxFrameGrabber> dispmanx(new DispmanxFrameGrabber());
if (dispmanx->isAvailable())
{
device = dispmanx->discover(params);
@ -1761,27 +1756,24 @@ void JsonAPI::handleInputSourceCommand(const QJsonObject& message, const QString
videoInputs.append(device);
}
}
delete dispmanx;
#endif
#if defined(ENABLE_AMLOGIC)
AmlogicGrabber* amlGrabber = new AmlogicGrabber();
QScopedPointer<AmlogicGrabber> amlGrabber(new AmlogicGrabber());
device = amlGrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete amlGrabber;
#endif
#if defined(ENABLE_OSX)
OsxFrameGrabber* osxGrabber = new OsxFrameGrabber();
QScopedPointer<OsxFrameGrabber> osxGrabber(new OsxFrameGrabber());
device = osxGrabber->discover(params);
if (!device.isEmpty() )
{
videoInputs.append(device);
}
delete osxGrabber;
#endif
}
@ -1826,10 +1818,10 @@ void JsonAPI::handleServiceCommand(const QJsonObject &message, const QString &co
if (!serviceType.isEmpty())
{
#ifdef ENABLE_MDNS
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, serviceType));
serviceList = MdnsBrowser::getInstance().getServicesDiscoveredJson(serviceType, MdnsServiceRegister::getServiceNameFilter(type), DEFAULT_DISCOVER_TIMEOUT);
serviceList = MdnsBrowser::getInstance().data()->getServicesDiscoveredJson(serviceType, MdnsServiceRegister::getServiceNameFilter(type), DEFAULT_DISCOVER_TIMEOUT);
#endif
servicesOfType.insert(type, serviceList);
@ -1983,7 +1975,7 @@ void JsonAPI::incommingLogMessage(const Logger::T_LOG_MESSAGE &msg)
if (!_streaming_logging_activated)
{
_streaming_logging_activated = true;
QMetaObject::invokeMethod(LoggerManager::getInstance(), "getLogMessageBuffer",
QMetaObject::invokeMethod(LoggerManager::getInstance().data(), "getLogMessageBuffer",
Qt::DirectConnection,
Q_RETURN_ARG(QJsonArray, messageArray),
Q_ARG(Logger::LogLevel, _log->getLogLevel()));
@ -2033,7 +2025,7 @@ void JsonAPI::handleTokenResponse(bool success, const QString &token, const QStr
sendErrorReply("Token request timeout or denied", cmd, tan);
}
void JsonAPI::handleInstanceStateChange(InstanceState state, quint8 instance, const QString &name)
void JsonAPI::handleInstanceStateChange(InstanceState state, quint8 instance, const QString& /*name */)
{
switch (state)
{

View File

@ -38,6 +38,7 @@ CECHandler::CECHandler(const QJsonDocument& config, QObject * parent)
CECHandler::~CECHandler()
{
Info(_logger, "CEC handler stopped");
}
void CECHandler::handleSettingsUpdate(settings::type type, const QJsonDocument& config)
@ -165,7 +166,7 @@ bool CECHandler::enable()
else
{
_isOpen=true;
QObject::connect(this, &CECHandler::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
QObject::connect(this, &CECHandler::signalEvent, EventHandler::getInstance().data(), &EventHandler::handleEvent);
#ifdef VERBOSE_CEC
std::cout << "Found Devices: " << scan().toStdString() << std::endl;
#endif
@ -188,7 +189,7 @@ void CECHandler::disable()
{
if (_isInitialised)
{
QObject::disconnect(this, &CECHandler::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
QObject::disconnect(this, &CECHandler::signalEvent, EventHandler::getInstance().data(), &EventHandler::handleEvent);
_cecAdapter->Close();
_isOpen=false;
Info(_logger, "CEC handler disabled");

View File

@ -7,6 +7,8 @@
#include <utils/Process.h>
#include <hyperion/HyperionIManager.h>
QScopedPointer<EventHandler> EventHandler::instance;
EventHandler::EventHandler()
: _isSuspended(false)
, _isIdle(false)
@ -15,6 +17,7 @@ EventHandler::EventHandler()
_log = Logger::getInstance("EVENTS");
QObject::connect(this, &EventHandler::signalEvent, HyperionIManager::getInstance(), &HyperionIManager::handleEvent);
Debug(_log, "Hyperion event handler created");
}
EventHandler::~EventHandler()
@ -22,10 +25,14 @@ EventHandler::~EventHandler()
QObject::disconnect(this, &EventHandler::signalEvent, HyperionIManager::getInstance(), &HyperionIManager::handleEvent);
}
EventHandler* EventHandler::getInstance()
QScopedPointer<EventHandler>& EventHandler::getInstance()
{
static EventHandler instance;
return &instance;
if (!instance)
{
instance.reset(new EventHandler());
}
return instance;
}
void EventHandler::suspend()

View File

@ -15,14 +15,16 @@ EventScheduler::EventScheduler()
qRegisterMetaType<Event>("Event");
_log = Logger::getInstance("EVENTS-SCHED");
QObject::connect(this, &EventScheduler::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
QObject::connect(this, &EventScheduler::signalEvent, EventHandler::getInstance().data(), &EventHandler::handleEvent);
Debug(_log, "Hyperion event scheduler created");
}
EventScheduler::~EventScheduler()
{
QObject::disconnect(this, &EventScheduler::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
QObject::disconnect(this, &EventScheduler::signalEvent, EventHandler::getInstance().data(), &EventHandler::handleEvent);
clearTimers();
Info(_log, "Event scheduler stopped");
Info(_log, "Hyperion event scheduler stopped");
}
void EventScheduler::handleSettingsUpdate(settings::type type, const QJsonDocument& config)

View File

@ -39,12 +39,14 @@ OsEventHandlerBase::OsEventHandlerBase()
{
_isService = true;
}
QObject::connect(this, &OsEventHandlerBase::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
QObject::connect(this, &OsEventHandlerBase::signalEvent, EventHandler::getInstance().data(), &EventHandler::handleEvent);
Debug(_log, "Operating System event handler created");
}
OsEventHandlerBase::~OsEventHandlerBase()
{
QObject::disconnect(this, &OsEventHandlerBase::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
QObject::disconnect(this, &OsEventHandlerBase::signalEvent, EventHandler::getInstance().data(), &EventHandler::handleEvent);
OsEventHandlerBase::unregisterLockHandler();
OsEventHandlerBase::unregisterOsEventHandler();

View File

@ -125,6 +125,6 @@ void FlatBufferServer::stopServer()
client->forceClose();
}
_server->close();
Info(_log, "Stopped");
Info(_log, "FlatBuffer-Server stopped");
}
}

View File

@ -48,7 +48,7 @@ MessageForwarder::MessageForwarder(Hyperion* hyperion)
qRegisterMetaType<TargetHost>("TargetHost");
#ifdef ENABLE_MDNS
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, MdnsServiceRegister::getServiceType("jsonapi")));
#endif
@ -257,7 +257,7 @@ int MessageForwarder::startJsonTargets(const QJsonObject& config)
#ifdef ENABLE_MDNS
if (!addr.isEmpty())
{
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, MdnsServiceRegister::getServiceType("jsonapi")));
}
#endif
@ -362,7 +362,7 @@ int MessageForwarder::startFlatbufferTargets(const QJsonObject& config)
#ifdef ENABLE_MDNS
if (!addr.isEmpty())
{
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, MdnsServiceRegister::getServiceType("flatbuffer")));
}
#endif

View File

@ -27,7 +27,7 @@
namespace {
const bool verbose = false;
const char DEFAULT_FB_DEVICE[] = "/dev/fb0";
const int DEFAULT_FB_DEVICE_IDX = 0;
const char DEFAULT_VIDEO_DEVICE[] = "/dev/amvideo";
const char DEFAULT_CAPTURE_DEVICE[] = "/dev/amvideocap0";
const int AMVIDEOCAP_WAIT_MAX_MS = 40;
@ -36,11 +36,11 @@ const int AMVIDEOCAP_DEFAULT_RATE_HZ = 25;
} //End of constants
AmlogicGrabber::AmlogicGrabber()
: Grabber("AMLOGICGRABBER") // Minimum required width or height is 160
: Grabber("GRABBER-AMLOGIC") // Minimum required width or height is 160
, _captureDev(-1)
, _videoDev(-1)
, _lastError(0)
, _fbGrabber(DEFAULT_FB_DEVICE)
, _fbGrabber(DEFAULT_FB_DEVICE_IDX)
, _grabbingModeNotification(0)
{
_image_ptr = _image_bgr.memptr();
@ -57,7 +57,7 @@ bool AmlogicGrabber::setupScreen()
{
bool rc (false);
QSize screenSize = _fbGrabber.getScreenSize(DEFAULT_FB_DEVICE);
QSize screenSize = _fbGrabber.getScreenSize();
if ( !screenSize.isEmpty() )
{
if (setWidthHeight(screenSize.width(), screenSize.height()))

View File

@ -1,12 +1,18 @@
#include <grabber/amlogic/AmlogicWrapper.h>
AmlogicWrapper::AmlogicWrapper(int pixelDecimation, int updateRate_Hz)
: GrabberWrapper("Amlogic", &_grabber, updateRate_Hz)
: GrabberWrapper(GRABBERTYPE, &_grabber, updateRate_Hz)
, _grabber()
{
_grabber.setPixelDecimation(pixelDecimation);
}
AmlogicWrapper::AmlogicWrapper(const QJsonDocument& grabberConfig)
: GrabberWrapper(GRABBERTYPE, &_grabber)
{
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
}
void AmlogicWrapper::action()
{
transferFrame(_grabber);

View File

@ -10,7 +10,7 @@ namespace {
} //End of constants
DirectXGrabber::DirectXGrabber(int display, int cropLeft, int cropRight, int cropTop, int cropBottom)
: Grabber("DXGRABBER", cropLeft, cropRight, cropTop, cropBottom)
: Grabber("GRABBER-DIRECTX", cropLeft, cropRight, cropTop, cropBottom)
, _display(unsigned(display))
, _displayWidth(0)
, _displayHeight(0)

View File

@ -5,13 +5,19 @@ DirectXWrapper::DirectXWrapper( int updateRate_Hz,
int pixelDecimation,
int cropLeft, int cropRight, int cropTop, int cropBottom
)
: GrabberWrapper("DirectX", &_grabber, updateRate_Hz)
: GrabberWrapper(GRABBERTYPE, &_grabber, updateRate_Hz)
, _grabber(display, cropLeft, cropRight, cropTop, cropBottom)
{
_grabber.setPixelDecimation(pixelDecimation);
}
DirectXWrapper::DirectXWrapper(const QJsonDocument& grabberConfig)
: GrabberWrapper(GRABBERTYPE, &_grabber)
{
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
}
void DirectXWrapper::action()
{
transferFrame(_grabber);

View File

@ -19,7 +19,7 @@ namespace {
#include "grabber/dispmanx/DispmanxFrameGrabber.h"
DispmanxFrameGrabber::DispmanxFrameGrabber()
: Grabber("DISPMANXGRABBER")
: Grabber("GRABBER-DISPMANX")
, _lib(nullptr)
, _vc_display(0)
, _vc_resource(0)

View File

@ -3,15 +3,20 @@
DispmanxWrapper::DispmanxWrapper( int updateRate_Hz,
int pixelDecimation
)
: GrabberWrapper("Dispmanx", &_grabber, updateRate_Hz)
, _grabber()
: GrabberWrapper(GRABBERTYPE, &_grabber, updateRate_Hz)
{
if (available = _grabber.isAvailable())
if (_isAvailable)
{
_grabber.setPixelDecimation(pixelDecimation);
}
}
DispmanxWrapper::DispmanxWrapper(const QJsonDocument& grabberConfig)
: GrabberWrapper(GRABBERTYPE, &_grabber)
{
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
}
bool DispmanxWrapper::open()
{
return _grabber.open();

View File

@ -30,11 +30,11 @@ const char DISCOVERY_FILEPATTERN[] = "fb?";
// Local includes
#include <grabber/framebuffer/FramebufferFrameGrabber.h>
FramebufferFrameGrabber::FramebufferFrameGrabber(const QString & device)
: Grabber("FRAMEBUFFERGRABBER")
, _fbDevice(device)
, _fbfd (-1)
FramebufferFrameGrabber::FramebufferFrameGrabber(int deviceIdx)
: Grabber("GRABBER-FB")
, _fbfd (-1)
{
_input = deviceIdx;
_useImageResampler = true;
}
@ -105,6 +105,7 @@ bool FramebufferFrameGrabber::openDevice()
{
bool rc = true;
_fbDevice = getPath();
/* Open the framebuffer device */
_fbfd = ::open(QSTRING_CSTR(_fbDevice), O_RDONLY);
if (_fbfd < 0)
@ -136,8 +137,7 @@ QSize FramebufferFrameGrabber::getScreenSize() const
QSize FramebufferFrameGrabber::getScreenSize(const QString& device) const
{
int width (0);
int height(0);
QSize size;
int fbfd = ::open(QSTRING_CSTR(device), O_RDONLY);
if (fbfd != -1)
@ -146,13 +146,13 @@ QSize FramebufferFrameGrabber::getScreenSize(const QString& device) const
int result = ioctl (fbfd, FBIOGET_VSCREENINFO, &vinfo);
if (result == 0)
{
width = static_cast<int>(vinfo.xres);
height = static_cast<int>(vinfo.yres);
DebugIf(verbose, _log, "FB device [%s] found with resolution: %dx%d", QSTRING_CSTR(device), width, height);
size.setWidth(static_cast<int>(vinfo.xres));
size.setHeight(static_cast<int>(vinfo.yres));
DebugIf(verbose, _log, "FB device [%s] found with resolution: %dx%d", QSTRING_CSTR(device), size.width(), size.height());
}
::close(fbfd);
}
return QSize(width, height);
return size;
}
bool FramebufferFrameGrabber::getScreenInfo()

View File

@ -1,14 +1,20 @@
#include <grabber/framebuffer/FramebufferWrapper.h>
FramebufferWrapper::FramebufferWrapper( int updateRate_Hz,
const QString & device,
int deviceIdx,
int pixelDecimation)
: GrabberWrapper("FrameBuffer", &_grabber, updateRate_Hz)
, _grabber(device)
: GrabberWrapper(GRABBERTYPE, &_grabber, updateRate_Hz)
, _grabber(deviceIdx)
{
_grabber.setPixelDecimation(pixelDecimation);
}
FramebufferWrapper::FramebufferWrapper(const QJsonDocument& grabberConfig)
: GrabberWrapper(GRABBERTYPE, &_grabber)
{
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
}
void FramebufferWrapper::action()
{
transferFrame(_grabber);

View File

@ -16,7 +16,7 @@ const bool verbose = false;
} //End of constants
OsxFrameGrabber::OsxFrameGrabber(int display)
: Grabber("OSXGRABBER")
: Grabber("GRABBER-OSX")
, _screenIndex(display)
{
_isEnabled = false;

View File

@ -4,12 +4,18 @@ OsxWrapper::OsxWrapper( int updateRate_Hz,
int display,
int pixelDecimation
)
: GrabberWrapper("OSX", &_grabber, updateRate_Hz)
: GrabberWrapper(GRABBERTYPE, &_grabber, updateRate_Hz)
, _grabber(display)
{
_grabber.setPixelDecimation(pixelDecimation);
}
OsxWrapper::OsxWrapper(const QJsonDocument& grabberConfig)
: GrabberWrapper(GRABBERTYPE, &_grabber)
{
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
}
void OsxWrapper::action()
{
transferFrame(_grabber);

View File

@ -20,8 +20,9 @@ const bool verbose = false;
} //End of constants
QtGrabber::QtGrabber(int display, int cropLeft, int cropRight, int cropTop, int cropBottom)
: Grabber("QTGRABBER", cropLeft, cropRight, cropTop, cropBottom)
: Grabber("GRABBER-QT", cropLeft, cropRight, cropTop, cropBottom)
, _display(display)
, _numberOfSDisplays(0)
, _screenWidth(0)
, _screenHeight(0)
, _src_x(0)
@ -32,7 +33,6 @@ QtGrabber::QtGrabber(int display, int cropLeft, int cropRight, int cropTop, int
, _screen(nullptr)
, _isVirtual(false)
{
_logger = Logger::getInstance("Qt");
_useImageResampler = false;
}

View File

@ -5,12 +5,18 @@ QtWrapper::QtWrapper( int updateRate_Hz,
int pixelDecimation,
int cropLeft, int cropRight, int cropTop, int cropBottom
)
: GrabberWrapper("Qt", &_grabber, updateRate_Hz)
: GrabberWrapper(GRABBERTYPE, &_grabber, updateRate_Hz)
, _grabber(display, cropLeft, cropRight, cropTop, cropBottom)
{
_grabber.setPixelDecimation(pixelDecimation);
}
QtWrapper::QtWrapper(const QJsonDocument& grabberConfig)
: GrabberWrapper(GRABBERTYPE, &_grabber)
{
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
}
bool QtWrapper::open()
{
return _grabber.open();

View File

@ -10,7 +10,7 @@ namespace {
} //End of constants
X11Grabber::X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom)
: Grabber("X11GRABBER", cropLeft, cropRight, cropTop, cropBottom)
: Grabber("GRABBER-X11", cropLeft, cropRight, cropTop, cropBottom)
, _x11Display(nullptr)
, _xImage(nullptr)
, _pixmap(None)
@ -28,8 +28,6 @@ X11Grabber::X11Grabber(int cropLeft, int cropRight, int cropTop, int cropBottom)
, _isWayland (false)
, _logger{}
{
_logger = Logger::getInstance("X11");
_useImageResampler = false;
_imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XRender, XShmGetImage or XGetImage
memset(&_pictAttr, 0, sizeof(_pictAttr));

View File

@ -3,13 +3,19 @@
X11Wrapper::X11Wrapper( int updateRate_Hz,
int pixelDecimation,
int cropLeft, int cropRight, int cropTop, int cropBottom)
: GrabberWrapper("X11", &_grabber, updateRate_Hz)
: GrabberWrapper(GRABBERTYPE, &_grabber, updateRate_Hz)
, _grabber(cropLeft, cropRight, cropTop, cropBottom)
, _init(false)
{
_grabber.setPixelDecimation(pixelDecimation);
}
X11Wrapper::X11Wrapper(const QJsonDocument& grabberConfig)
: GrabberWrapper(GRABBERTYPE, &_grabber)
{
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
}
X11Wrapper::~X11Wrapper()
{
if ( _init )

View File

@ -18,7 +18,7 @@ namespace {
#define DOUBLE_TO_FIXED(d) ((xcb_render_fixed_t) ((d) * 65536))
XcbGrabber::XcbGrabber(int cropLeft, int cropRight, int cropTop, int cropBottom)
: Grabber("XCBGRABBER", cropLeft, cropRight, cropTop, cropBottom)
: Grabber("GRABBER-XCB", cropLeft, cropRight, cropTop, cropBottom)
, _connection{}
, _screen{}
, _pixmap{}
@ -41,8 +41,6 @@ XcbGrabber::XcbGrabber(int cropLeft, int cropRight, int cropTop, int cropBottom)
, _shmData{}
, _XcbRandREventBase{-1}
{
_logger = Logger::getInstance("XCB");
// cropping is performed by XcbRender, XcbShmGetImage or XcbGetImage
_useImageResampler = false;
_imageResampler.setCropping(0, 0, 0, 0);

View File

@ -3,13 +3,19 @@
XcbWrapper::XcbWrapper( int updateRate_Hz,
int pixelDecimation,
int cropLeft, int cropRight, int cropTop, int cropBottom)
: GrabberWrapper("Xcb", &_grabber, updateRate_Hz)
: GrabberWrapper(GRABBERTYPE, &_grabber, updateRate_Hz)
, _grabber(cropLeft, cropRight, cropTop, cropBottom)
, _init(false)
{
_grabber.setPixelDecimation(pixelDecimation);
}
XcbWrapper::XcbWrapper(const QJsonDocument& grabberConfig)
: GrabberWrapper(GRABBERTYPE, &_grabber)
{
this->handleSettingsUpdate(settings::SYSTEMCAPTURE, grabberConfig);
}
XcbWrapper::~XcbWrapper()
{
if ( _init )

View File

@ -18,6 +18,7 @@ Grabber::Grabber(const QString& grabberName, int cropLeft, int cropRight, int cr
, _cropRight(0)
, _cropTop(0)
, _cropBottom(0)
, _isAvailable(true)
, _isEnabled(true)
, _isDeviceInError(false)
{

View File

@ -26,10 +26,11 @@ bool GrabberWrapper::GLOBAL_GRABBER_AUDIO_ENABLE = false;
GrabberWrapper::GrabberWrapper(const QString& grabberName, Grabber * ggrabber, int updateRate_Hz)
: _grabberName(grabberName)
, _log(Logger::getInstance(grabberName.toUpper()))
, _log(Logger::getInstance(("Grabber-" + grabberName).toUpper()))
, _timer(nullptr)
, _updateInterval_ms(1000/updateRate_Hz)
, _ggrabber(ggrabber)
, _isAvailable(true)
{
GrabberWrapper::instance = this;
@ -58,7 +59,7 @@ GrabberWrapper::GrabberWrapper(const QString& grabberName, Grabber * ggrabber, i
// listen for source requests
connect(GlobalSignals::getInstance(), &GlobalSignals::requestSource, this, &GrabberWrapper::handleSourceRequest);
QObject::connect(EventHandler::getInstance(), &EventHandler::signalEvent, this, &GrabberWrapper::handleEvent);
QObject::connect(EventHandler::getInstance().data(), &EventHandler::signalEvent, this, &GrabberWrapper::handleEvent);
}
GrabberWrapper::~GrabberWrapper()
@ -75,7 +76,7 @@ bool GrabberWrapper::start()
if (!_timer->isActive())
{
// Start the timer with the pre configured interval
Debug(_log,"Grabber start()");
Info(_log,"%s grabber started", QSTRING_CSTR(getName()));
_timer->start();
}
@ -89,7 +90,7 @@ void GrabberWrapper::stop()
if (_timer->isActive())
{
// Stop the timer, effectively stopping the process
Debug(_log,"Grabber stop()");
Info(_log,"%s grabber stopped", QSTRING_CSTR(getName()));
_timer->stop();
}
}

View File

@ -247,7 +247,7 @@ void HyperionIManager::handleFinished()
Hyperion* hyperion = qobject_cast<Hyperion*>(sender());
quint8 instance = hyperion->getInstanceIndex();
Info(_log,"Hyperion instance '%s' has been stopped", QSTRING_CSTR(_instanceTable->getNamebyIndex(instance)));
Info(_log,"Hyperion instance '%s' stopped", QSTRING_CSTR(_instanceTable->getNamebyIndex(instance)));
_runningInstances.remove(instance);
hyperion->thread()->deleteLater();

View File

@ -29,11 +29,12 @@ JsonServer::JsonServer(const QJsonDocument& config)
, _netOrigin(NetOrigin::getInstance())
, _config(config)
{
Debug(_log, "Created instance");
Debug(_log, "JSON API server created");
}
JsonServer::~JsonServer()
{
stop();
qDeleteAll(_openConnections);
_openConnections.clear();
}
@ -66,10 +67,12 @@ void JsonServer::start()
void JsonServer::stop()
{
if(!_server->isListening())
{
return;
}
_server->close();
Info(_log, "Stopped");
Info(_log, "JSON-Server stopped");
}
void JsonServer::handleSettingsUpdate(settings::type type, const QJsonDocument& config)

View File

@ -100,7 +100,7 @@ void LedDevice::stop()
this->stopEnableAttemptsTimer();
this->disable();
this->stopRefreshTimer();
Info(_log, " Stopped LedDevice '%s'", QSTRING_CSTR(_activeDeviceType));
Info(_log, "Stopped LedDevice '%s'", QSTRING_CSTR(_activeDeviceType));
}
int LedDevice::open()

View File

@ -53,7 +53,7 @@ LedDeviceCololight::LedDeviceCololight(const QJsonObject& deviceConfig)
, _sequenceNumber(1)
{
#ifdef ENABLE_MDNS
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, MdnsServiceRegister::getServiceType(_activeDeviceType)));
#endif
@ -679,7 +679,7 @@ QJsonObject LedDeviceCololight::discover(const QJsonObject& /*params*/)
#ifdef ENABLE_MDNS
QString discoveryMethod("mDNS");
deviceList = MdnsBrowser::getInstance().getServicesDiscoveredJson(
deviceList = MdnsBrowser::getInstance().data()->getServicesDiscoveredJson(
MdnsServiceRegister::getServiceType(_activeDeviceType),
MdnsServiceRegister::getServiceNameFilter(_activeDeviceType),
DEFAULT_DISCOVER_TIMEOUT

View File

@ -111,7 +111,7 @@ LedDeviceNanoleaf::LedDeviceNanoleaf(const QJsonObject& deviceConfig)
, _panelLedCount(0)
{
#ifdef ENABLE_MDNS
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, MdnsServiceRegister::getServiceType(_activeDeviceType)));
#endif
}
@ -461,7 +461,7 @@ QJsonObject LedDeviceNanoleaf::discover(const QJsonObject& /*params*/)
#ifdef ENABLE_MDNS
QString discoveryMethod("mDNS");
deviceList = MdnsBrowser::getInstance().getServicesDiscoveredJson(
deviceList = MdnsBrowser::getInstance().data()->getServicesDiscoveredJson(
MdnsServiceRegister::getServiceType(_activeDeviceType),
MdnsServiceRegister::getServiceNameFilter(_activeDeviceType),
DEFAULT_DISCOVER_TIMEOUT

View File

@ -349,7 +349,7 @@ LedDevicePhilipsHueBridge::LedDevicePhilipsHueBridge(const QJsonObject &deviceCo
, _isHueEntertainmentReady(false)
{
#ifdef ENABLE_MDNS
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, MdnsServiceRegister::getServiceType(_activeDeviceType)));
#endif
}
@ -1294,7 +1294,7 @@ QJsonObject LedDevicePhilipsHueBridge::discover(const QJsonObject& /*params*/)
#ifdef ENABLE_MDNS
QString discoveryMethod("mDNS");
deviceList = MdnsBrowser::getInstance().getServicesDiscoveredJson(
deviceList = MdnsBrowser::getInstance().data()->getServicesDiscoveredJson(
MdnsServiceRegister::getServiceType(_activeDeviceType),
MdnsServiceRegister::getServiceNameFilter(_activeDeviceType),
DEFAULT_DISCOVER_TIMEOUT

View File

@ -99,7 +99,7 @@ LedDeviceWled::LedDeviceWled(const QJsonObject &deviceConfig)
,_isStreamToSegment(false)
{
#ifdef ENABLE_MDNS
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, MdnsServiceRegister::getServiceType(_activeDeviceType)));
#endif
}
@ -547,7 +547,7 @@ QJsonObject LedDeviceWled::discover(const QJsonObject& /*params*/)
#ifdef ENABLE_MDNS
QString discoveryMethod("mDNS");
deviceList = MdnsBrowser::getInstance().getServicesDiscoveredJson(
deviceList = MdnsBrowser::getInstance().data()->getServicesDiscoveredJson(
MdnsServiceRegister::getServiceType(_activeDeviceType),
MdnsServiceRegister::getServiceNameFilter(_activeDeviceType),
DEFAULT_DISCOVER_TIMEOUT

View File

@ -1006,7 +1006,7 @@ LedDeviceYeelight::LedDeviceYeelight(const QJsonObject &deviceConfig)
,_musicModeServerPort(-1)
{
#ifdef ENABLE_MDNS
QMetaObject::invokeMethod(&MdnsBrowser::getInstance(), "browseForServiceType",
QMetaObject::invokeMethod(MdnsBrowser::getInstance().data(), "browseForServiceType",
Qt::QueuedConnection, Q_ARG(QByteArray, MdnsServiceRegister::getServiceType(_activeDeviceType)));
#endif
}
@ -1391,7 +1391,7 @@ QJsonObject LedDeviceYeelight::discover(const QJsonObject& /*params*/)
#ifdef ENABLE_MDNS
QString discoveryMethod("mDNS");
deviceList = MdnsBrowser::getInstance().getServicesDiscoveredJson(
deviceList = MdnsBrowser::getInstance().data()->getServicesDiscoveredJson(
MdnsServiceRegister::getServiceType(_activeDeviceType),
MdnsServiceRegister::getServiceNameFilter(_activeDeviceType),
DEFAULT_DISCOVER_TIMEOUT

View File

@ -21,6 +21,8 @@ namespace {
const int SERVICE_LOOKUP_RETRIES = 5;
} // End of constants
QScopedPointer<MdnsBrowser> MdnsBrowser::instance;
MdnsBrowser::MdnsBrowser(QObject* parent)
: QObject(parent)
, _log(Logger::getInstance("MDNS"))
@ -33,6 +35,16 @@ MdnsBrowser::~MdnsBrowser()
_browsedServiceTypes.clear();
}
QScopedPointer<MdnsBrowser>& MdnsBrowser::getInstance()
{
if (!instance)
{
instance.reset(new MdnsBrowser());
}
return instance;
}
void MdnsBrowser::browseForServiceType(const QByteArray& serviceType)
{
if (!_browsedServiceTypes.contains(serviceType))
@ -163,8 +175,8 @@ bool MdnsBrowser::resolveAddress(Logger* log, const QString& hostname, QHostAddr
QEventLoop loop;
QTimer timer;
QObject::connect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, &loop, &QEventLoop::quit);
weakConnect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved,
QObject::connect(MdnsBrowser::getInstance().data(), &MdnsBrowser::addressResolved, &loop, &QEventLoop::quit);
weakConnect(MdnsBrowser::getInstance().data(), &MdnsBrowser::addressResolved,
[&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;
@ -182,7 +194,7 @@ bool MdnsBrowser::resolveAddress(Logger* log, const QString& hostname, QHostAddr
}
else
{
QObject::disconnect(&MdnsBrowser::getInstance(), &MdnsBrowser::addressResolved, nullptr, nullptr);
QObject::disconnect(MdnsBrowser::getInstance().data(), &MdnsBrowser::addressResolved, nullptr, nullptr);
Error(log, "Resolved mDNS hostname [%s] timed out", QSTRING_CSTR(hostname));
}
}

View File

@ -34,6 +34,7 @@ void MdnsProvider::init()
MdnsProvider::~MdnsProvider()
{
_providedServiceTypes.clear();
Info(_log, "mDNS info service stopped");
}
void MdnsProvider::publishService(const QString& serviceType, quint16 servicePort, const QByteArray& serviceName)

View File

@ -20,7 +20,6 @@ static const QString SSDP_IDENTIFIER("urn:hyperion-project.org:device:basic:1");
SSDPHandler::SSDPHandler(WebServer* webserver, quint16 flatBufPort, quint16 protoBufPort, quint16 jsonServerPort, quint16 sslPort, const QString& name, QObject* parent)
: SSDPServer(parent)
, _webserver(webserver)
, _localAddress()
#if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
, _NCA(nullptr)
#endif
@ -30,6 +29,8 @@ SSDPHandler::SSDPHandler(WebServer* webserver, quint16 flatBufPort, quint16 prot
setJsonServerPort(jsonServerPort);
setSSLServerPort(sslPort);
setHyperionName(name);
Debug(_log, "SSDP info service created");
}
SSDPHandler::~SSDPHandler()
@ -87,6 +88,7 @@ void SSDPHandler::stopServer()
{
sendAnnounceList(false);
SSDPServer::stop();
Info(_log, "SSDP info service stopped");
}
void SSDPHandler::handleSettingsUpdate(settings::type type, const QJsonDocument& config)

View File

@ -53,7 +53,7 @@ Logger* Logger::getInstance(const QString & name, const QString & subName, Logge
{
log = new Logger(name, subName, minLevel);
LoggerMap.insert(name + subName, log);
connect(log, &Logger::newLogMessage, LoggerManager::getInstance(), &LoggerManager::handleNewLogMessage);
connect(log, &Logger::newLogMessage, LoggerManager::getInstance().data(), &LoggerManager::handleNewLogMessage);
}
return log;
@ -151,9 +151,8 @@ void Logger::write(const Logger::T_LOG_MESSAGE & message)
name.resize(MAX_IDENTIFICATION_LENGTH, ' ');
const QDateTime timestamp = QDateTime::fromMSecsSinceEpoch(message.utime);
std::cout << QString("%1 %2 : <%3> %4%5")
.arg(timestamp.toString("yyyy-MM-ddThh:mm:ss.zzz"))
.arg(timestamp.toString(Qt::ISODateWithMs))
.arg(name)
.arg(LogLevelStrings[message.level])
.arg(location)
@ -169,8 +168,10 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u
Logger::LogLevel globalLevel = static_cast<Logger::LogLevel>(int(GLOBAL_MIN_LOG_LEVEL));
if ( (globalLevel == Logger::UNSET && level < _minLevel) // no global level, use level from logger
|| (globalLevel > Logger::UNSET && level < globalLevel) ) // global level set, use global level
|| (globalLevel > Logger::UNSET && level < globalLevel) ) // global level set, use global level
{
return;
}
const size_t max_msg_length = 1024;
char msg[max_msg_length];
@ -188,7 +189,9 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u
write(repMsg);
#ifndef _WIN32
if ( _syslogEnabled && repMsg.level >= Logger::WARNING )
{
syslog (LogLevelSysLog[repMsg.level], "Previous line repeats %d times", RepeatCount.localData());
}
#endif
RepeatCount.setLocalData(0);
@ -201,14 +204,20 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u
RepeatMessage.localData().line == line)
{
if (RepeatCount.localData() >= MaxRepeatCountSize)
{
repeatedSummary();
}
else
{
RepeatCount.setLocalData(RepeatCount.localData() + 1);
}
}
else
{
if (RepeatCount.localData())
{
repeatedSummary();
}
Logger::T_LOG_MESSAGE logMsg;
@ -225,12 +234,16 @@ void Logger::Message(LogLevel level, const char* sourceFile, const char* func, u
write(logMsg);
#ifndef _WIN32
if ( _syslogEnabled && level >= Logger::WARNING )
{
syslog (LogLevelSysLog[level], "%s", msg);
}
#endif
RepeatMessage.setLocalData(logMsg);
}
}
QScopedPointer<LoggerManager> LoggerManager::instance;
LoggerManager::LoggerManager()
: QObject()
, _loggerMaxMsgBufferSize(MAX_LOG_MSG_BUFFERED)
@ -238,6 +251,14 @@ LoggerManager::LoggerManager()
_logMessageBuffer.reserve(_loggerMaxMsgBufferSize);
}
LoggerManager::~LoggerManager()
{
// delete components
Logger::deleteInstance();
_logMessageBuffer.clear();
}
QJsonArray LoggerManager::getLogMessageBuffer(Logger::LogLevel filter) const
{
QJsonArray messageArray;
@ -274,8 +295,12 @@ void LoggerManager::handleNewLogMessage(const Logger::T_LOG_MESSAGE & msg)
emit newLogMessage(msg);
}
LoggerManager* LoggerManager::getInstance()
QScopedPointer<LoggerManager>& LoggerManager::getInstance()
{
static LoggerManager instance;
return &instance;
if (!instance)
{
instance.reset(new LoggerManager());
}
return instance;
}

View File

@ -31,7 +31,6 @@ WebServer::WebServer(const QJsonDocument& config, bool useSsl, QObject* parent)
, _useSsl(useSsl)
, _log(Logger::getInstance("WEBSERVER"))
, _port(WEBSERVER_DEFAULT_PORT)
, _server()
{
}
@ -43,7 +42,7 @@ WebServer::~WebServer()
void WebServer::initServer()
{
Debug(_log, "Initialize %s-Webserver", _useSsl ? "https" : "http");
_server = new QtHttpServer(this);
_server.reset(new QtHttpServer(this));
_server->setServerName(QStringLiteral("Hyperion %1-Webserver").arg(_useSsl ? "https" : "http"));
if (_useSsl)
@ -51,13 +50,13 @@ void WebServer::initServer()
_server->setUseSecure();
}
connect(_server, &QtHttpServer::started, this, &WebServer::onServerStarted);
connect(_server, &QtHttpServer::stopped, this, &WebServer::onServerStopped);
connect(_server, &QtHttpServer::error, this, &WebServer::onServerError);
connect(_server.get(), &QtHttpServer::started, this, &WebServer::onServerStarted);
connect(_server.get(), &QtHttpServer::stopped, this, &WebServer::onServerStopped);
connect(_server.get(), &QtHttpServer::error, this, &WebServer::onServerError);
// create StaticFileServing
_staticFileServing = new StaticFileServing(this);
connect(_server, &QtHttpServer::requestNeedsReply, _staticFileServing, &StaticFileServing::onRequestNeedsReply);
connect(_server.get(), &QtHttpServer::requestNeedsReply, _staticFileServing, &StaticFileServing::onRequestNeedsReply);
// init
handleSettingsUpdate(settings::WEBSERVER, _config);
@ -83,11 +82,11 @@ void WebServer::onServerStarted(quint16 port)
void WebServer::onServerStopped()
{
Info(_log, "Stopped %s", _server->getServerName().toStdString().c_str());
Info(_log, "%s stopped", _server->getServerName().toStdString().c_str());
emit stateChange(false);
}
void WebServer::onServerError(QString msg)
void WebServer::onServerError(const QString& msg)
{
Error(_log, "%s", msg.toStdString().c_str());
}
@ -112,7 +111,9 @@ void WebServer::handleSettingsUpdate(settings::type type, const QJsonDocument& c
}
}
else
{
_baseUrl = WEBSERVER_DEFAULT_PATH;
}
Debug(_log, "Set document root to: %s", _baseUrl.toUtf8().constData());
_staticFileServing->setBaseUrl(_baseUrl);
@ -127,7 +128,9 @@ void WebServer::handleSettingsUpdate(settings::type type, const QJsonDocument& c
// eval if the port is available, will be incremented if not
if (!_server->isListening())
{
NetUtils::portAvailable(_port, _log);
}
// on ssl we want .key .cert and probably key password
if (_useSsl)
@ -149,7 +152,9 @@ void WebServer::handleSettingsUpdate(settings::type type, const QJsonDocument& c
}
}
else
{
keyPath = WEBSERVER_DEFAULT_KEY_PATH;
}
// check crtPath
if ((crtPath != WEBSERVER_DEFAULT_CRT_PATH) && !crtPath.trimmed().isEmpty())
@ -162,7 +167,9 @@ void WebServer::handleSettingsUpdate(settings::type type, const QJsonDocument& c
}
}
else
{
crtPath = WEBSERVER_DEFAULT_CRT_PATH;
}
// load and verify crt
QFile cfile(crtPath);
@ -174,9 +181,13 @@ void WebServer::handleSettingsUpdate(settings::type type, const QJsonDocument& c
// Filter for valid certs
for (const auto& entry : cList) {
if (!entry.isNull() && QDateTime::currentDateTime().daysTo(entry.expiryDate()) > 0)
{
validList.append(entry);
}
else
{
Error(_log, "The provided SSL certificate is invalid/not supported/reached expiry date ('%s')", crtPath.toUtf8().constData());
}
}
if (!validList.isEmpty()) {

View File

@ -23,9 +23,11 @@ WebSocketClient::WebSocketClient(QtHttpRequest* request, QTcpSocket* sock, bool
const QString client = request->getClientInfo().clientAddress.toString();
// Json processor
_jsonAPI = new JsonAPI(client, _log, localConnection, this);
connect(_jsonAPI, &JsonAPI::callbackMessage, this, &WebSocketClient::sendMessage);
connect(_jsonAPI, &JsonAPI::forceClose, this,[this]() { this->sendClose(CLOSECODE::NORMAL); });
_jsonAPI.reset(new JsonAPI(client, _log, localConnection, this));
connect(_jsonAPI.get(), &JsonAPI::callbackMessage, this, &WebSocketClient::sendMessage);
connect(_jsonAPI.get(), &JsonAPI::forceClose, this,[this]() { this->sendClose(CLOSECODE::NORMAL); });
connect(this, &WebSocketClient::handleMessage, _jsonAPI.get(), &JsonAPI::handleMessage);
Debug(_log, "New connection from %s", QSTRING_CSTR(client));
@ -129,7 +131,7 @@ void WebSocketClient::handleWebSocketFrame()
if (_frameOpCode == OPCODE::TEXT)
{
_jsonAPI->handleMessage(QString(_wsReceiveBuffer));
emit handleMessage(QString(_wsReceiveBuffer),"");
}
else
{

View File

@ -2,6 +2,9 @@
#include <utils/Logger.h>
#include "WebSocketUtils.h"
#include <api/JsonAPI.h>
#include <QScopedPointer>
class QTcpSocket;
@ -28,7 +31,7 @@ private:
QTcpSocket* _socket;
Logger* _log;
Hyperion* _hyperion;
JsonAPI* _jsonAPI;
QScopedPointer<JsonAPI> _jsonAPI;
void getWsFrameHeader(WebSocketHeader* header);
void sendClose(int status, const QString& reason = "");
@ -73,4 +76,7 @@ private:
private slots:
void handleWebSocketFrame();
qint64 sendMessage(QJsonObject obj);
signals:
void handleMessage(const QString &message, const QString &httpAuthHeader);
};

View File

@ -2,13 +2,13 @@
#include "FramebufferWrapper.h"
FramebufferWrapper::FramebufferWrapper( int updateRate_Hz,
const QString & device,
int deviceIdx,
int pixelDecimation,
int cropLeft, int cropRight,
int cropTop, int cropBottom
) :
_timer(this),
_grabber(device)
_grabber(deviceIdx)
{
_grabber.setFramerate(updateRate_Hz);
_grabber.setCropping(cropLeft, cropRight, cropTop, cropBottom);

View File

@ -12,7 +12,7 @@ class FramebufferWrapper : public QObject
public:
FramebufferWrapper( int updateRate_Hz=GrabberWrapper::DEFAULT_RATE_HZ,
const QString & device = "/dev/fb0",
int deviceIdx = 0,
int pixelDecimation=GrabberWrapper::DEFAULT_PIXELDECIMATION,
int cropLeft=0, int cropRight=0,
int cropTop=0, int cropBottom=0

View File

@ -50,7 +50,7 @@ int main(int argc, char ** argv)
// create the option parser and initialize all parameters
Parser parser("FrameBuffer capture application for Hyperion. Will automatically search a Hyperion server if -a option isn't used. Please note that if you have more than one server running it's more or less random which one will be used.");
Option & argDevice = parser.add<Option> ('d', "device", "Set the framebuffer device [default: %1]", "/dev/fb0");
IntOption & argDeviceIdx = parser.add<IntOption> ('d', "deviceIdx", "Set the framebuffer device index [default: %1]", 0);
IntOption & argFps = parser.add<IntOption> ('f', "framerate", QString("Capture frame rate. Range %1-%2fps").arg(GrabberWrapper::DEFAULT_MIN_GRAB_RATE_HZ).arg(GrabberWrapper::DEFAULT_MAX_GRAB_RATE_HZ), QString::number(GrabberWrapper::DEFAULT_RATE_HZ), GrabberWrapper::DEFAULT_MIN_GRAB_RATE_HZ, GrabberWrapper::DEFAULT_MAX_GRAB_RATE_HZ);
IntOption & argSizeDecimation = parser.add<IntOption> ('s', "size-decimator", "Decimation factor for the output image size [default=%1]", QString::number(GrabberWrapper::DEFAULT_PIXELDECIMATION), 1);
@ -88,7 +88,7 @@ int main(int argc, char ** argv)
FramebufferWrapper fbWrapper(
argFps.getInt(parser),
argDevice.value(parser),
argDeviceIdx.getInt(parser),
argSizeDecimation.getInt(parser),
argCropLeft.getInt(parser),
argCropRight.getInt(parser),

File diff suppressed because it is too large Load Diff

View File

@ -1,8 +1,12 @@
#pragma once
#ifndef HYPERIOND_H
#define HYPERIOND_H
#include <memory>
#include <QApplication>
#include <QObject>
#include <QJsonObject>
#include <QScopedPointer>
#include <hyperion/HyperionIManager.h>
@ -110,7 +114,7 @@ public:
///
/// @brief Get webserver pointer (systray)
///
WebServer *getWebServerInstance() { return _webserver; }
WebServer *getWebServerInstance() { return _webserver.data(); }
///
/// @brief Get the current videoMode
@ -122,14 +126,11 @@ public:
///
QJsonDocument getSetting(settings::type type) const;
void startNetworkServices();
void startEventServices();
static HyperionDaemon* getInstance() { return daemon; }
static HyperionDaemon* daemon;
public slots:
void freeObjects();
void stoppServices();
signals:
///////////////////////////////////////
@ -176,67 +177,100 @@ private slots:
void handleInstanceStateChange(InstanceState state, quint8 instance);
private:
void createGrabberDispmanx(const QJsonObject & grabberConfig);
void createGrabberAmlogic(const QJsonObject & grabberConfig);
void createGrabberFramebuffer(const QJsonObject & grabberConfig);
void createGrabberOsx(const QJsonObject & grabberConfig);
void createGrabberX11(const QJsonObject & grabberConfig);
void createGrabberXcb(const QJsonObject & grabberConfig);
void createGrabberQt(const QJsonObject & grabberConfig);
void createGrabberDx(const QJsonObject & grabberConfig);
void createGrabberAudio(const QJsonObject & grabberConfig);
void startCecHandler();
void stopCecHandler();
void createNetworkServices();
void startNetworkServices();
void stopNetworkServices();
void startEventServices();
void stopEventServices();
void startGrabberServices();
void stopGrabberServices();
void updateScreenGrabbers(const QJsonDocument& grabberConfig);
void updateVideoGrabbers(const QJsonObject& grabberConfig);
void updateAudioGrabbers(const QJsonObject& grabberConfig);
QString evalScreenGrabberType();
template<typename GrabberType>
void startGrabber(QScopedPointer<GrabberWrapper>& sharedGrabber, const QJsonDocument& grabberConfig, bool enableGrabber = true) {
QString typeName = GrabberType::GRABBERTYPE;
if (!enableGrabber)
{
Debug(_log, "The %s grabber is not enabled on this platform", QSTRING_CSTR(typeName));
sharedGrabber.reset();
return;
}
std::unique_ptr<GrabberType> grabber = std::make_unique<GrabberType>(grabberConfig);
if (!grabber)
{
Error(_log, "Failed to cast grabber type %s to GrabberWrapper", QSTRING_CSTR(typeName));
}
else
{
if (!grabber->isAvailable())
{
Debug(_log, "The %s grabber is not available on this platform", QSTRING_CSTR(typeName));
return;
}
connect(this, &HyperionDaemon::videoMode, grabber.get(), &GrabberType::setVideoMode);
connect(this, &HyperionDaemon::settingsChanged, grabber.get(), &GrabberType::handleSettingsUpdate);
Info(_log, "%s grabber created", QSTRING_CSTR(typeName));
grabber->tryStart();
// Transfer ownership to sharedGrabber
sharedGrabber.reset(grabber.release());
}
}
Logger* _log;
/// Core services
QScopedPointer<HyperionIManager> _instanceManager;
QScopedPointer<SettingsManager> _settingsManager;
Logger* _log;
HyperionIManager* _instanceManager;
AuthManager* _authManager;
#ifdef ENABLE_MDNS
MdnsProvider* _mDNSProvider;
#endif
NetOrigin* _netOrigin;
#if defined(ENABLE_EFFECTENGINE)
PythonInit* _pyInit;
#endif
WebServer* _webserver;
WebServer* _sslWebserver;
JsonServer* _jsonServer;
VideoWrapper* _videoGrabber;
DispmanxWrapper* _dispmanx;
X11Wrapper* _x11Grabber;
XcbWrapper* _xcbGrabber;
AmlogicWrapper* _amlGrabber;
FramebufferWrapper* _fbGrabber;
OsxWrapper* _osxGrabber;
QtWrapper* _qtGrabber;
DirectXWrapper* _dxGrabber;
AudioWrapper* _audioGrabber;
SSDPHandler* _ssdp;
EventHandler* _eventHandler;
OsEventHandler* _osEventHandler;
EventScheduler* _eventScheduler;
#ifdef ENABLE_CEC
CECHandler* _cecHandler;
/// Network services
QScopedPointer<AuthManager> _authManager;
QScopedPointer<NetOrigin> _netOrigin;
QScopedPointer<JsonServer, QScopedPointerDeleteLater> _jsonServer;
QScopedPointer<WebServer, QScopedPointerDeleteLater> _webserver;
QScopedPointer<WebServer, QScopedPointerDeleteLater> _sslWebserver;
QScopedPointer<SSDPHandler, QScopedPointerDeleteLater> _ssdp;
#ifdef ENABLE_MDNS
QScopedPointer<MdnsProvider, QScopedPointerDeleteLater> _mDNSProvider;
#endif
#if defined(ENABLE_FLATBUF_SERVER)
QScopedPointer<FlatBufferServer, QScopedPointerDeleteLater> _flatBufferServer;
#endif
#if defined(ENABLE_PROTOBUF_SERVER)
QScopedPointer<ProtoServer, QScopedPointerDeleteLater> _protoServer;
#endif
#if defined(ENABLE_FLATBUF_SERVER)
FlatBufferServer* _flatBufferServer;
#endif
#if defined(ENABLE_PROTOBUF_SERVER)
ProtoServer* _protoServer;
#endif
int _grabber_width;
int _grabber_height;
int _grabber_pixelDecimation;
int _grabber_frequency;
int _grabber_cropLeft;
int _grabber_cropRight;
int _grabber_cropTop;
int _grabber_cropBottom;
/// Event services
QScopedPointer<EventHandler> _eventHandler;
QScopedPointer<OsEventHandler> _osEventHandler;
QScopedPointer<EventScheduler> _eventScheduler;
#ifdef ENABLE_CEC
QScopedPointer<CECHandler> _cecHandler;
#endif
/// Grabber services
QScopedPointer<GrabberWrapper> _screenGrabber;
QScopedPointer<VideoWrapper> _videoGrabber;
QScopedPointer<AudioWrapper> _audioGrabber;
QString _prevType;
VideoMode _currVideoMode;
SettingsManager* _settingsManager;
};
#endif // HYPERIOND_H

View File

@ -389,9 +389,6 @@ int main(int argc, char** argv)
Error(log, "Hyperion aborted: %s", e.what());
}
// delete components
Logger::deleteInstance();
#ifdef _WIN32
if (parser.isSet(consoleOption))
{

View File

@ -45,7 +45,7 @@ SysTray::SysTray(HyperionDaemon *hyperiond)
// instance changes
connect(_instanceManager, &HyperionIManager::instanceStateChanged, this, &SysTray::handleInstanceStateChange);
connect(this, &SysTray::signalEvent, EventHandler::getInstance(), &EventHandler::handleEvent);
connect(this, &SysTray::signalEvent, EventHandler::getInstance().data(), &EventHandler::handleEvent);
}
SysTray::~SysTray()