Skip to content

Commit e52fd7b

Browse files
authored
Fix crash on startup X server is not available (#895)
1 parent 6f5f28c commit e52fd7b

File tree

7 files changed

+118
-82
lines changed

7 files changed

+118
-82
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7676
- Decrease compile time (#886)
7777
- Fix some data synchronization error (#890)
7878
- Fix Qt screenhot crash (#889)
79+
- Fix crash on startup if no X server available (#892)
7980
- Fix RPC restart of Hyperion (#894)
8081

8182
### Removed

include/grabber/V4L2Wrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ public slots:
3232
void setCecDetectionEnable(bool enable);
3333
void setDeviceVideoStandard(QString device, VideoStandard videoStandard);
3434
void handleCecEvent(CECEvent event);
35+
void handleSettingsUpdate(const settings::type& type, const QJsonDocument& config) override;
3536

3637
private slots:
3738
void newFrame(const Image<ColorRgb> & image);

include/hyperion/GrabberWrapper.h

+11
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ class GrabberWrapper : public QObject
5151
///
5252
virtual void stop();
5353

54+
///
55+
/// Check if grabber is active
56+
///
57+
virtual bool isActive() const;
58+
5459
///
5560
/// @brief Get a list of all available V4L devices
5661
/// @return List of all available V4L devices on success else empty List
@@ -146,6 +151,12 @@ private slots:
146151
/// Will start and stop grabber based on active listeners count
147152
void handleSourceRequest(const hyperion::Components& component, const int hyperionInd, const bool listen);
148153

154+
///
155+
/// @brief Update Update capture rate
156+
/// @param type interval between frames in millisecons
157+
///
158+
void updateTimer(int interval);
159+
149160
protected:
150161
QString _grabberName;
151162

libsrc/grabber/v4l2/V4L2Wrapper.cpp

+45
Original file line numberDiff line numberDiff line change
@@ -109,3 +109,48 @@ void V4L2Wrapper::handleCecEvent(CECEvent event)
109109
{
110110
_grabber.handleCecEvent(event);
111111
}
112+
113+
void V4L2Wrapper::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
114+
{
115+
if(type == settings::V4L2 && _grabberName.startsWith("V4L"))
116+
{
117+
// extract settings
118+
const QJsonObject& obj = config.object();
119+
120+
// pixel decimation for v4l
121+
_grabber.setPixelDecimation(obj["sizeDecimation"].toInt(8));
122+
123+
// crop for v4l
124+
_grabber.setCropping(
125+
obj["cropLeft"].toInt(0),
126+
obj["cropRight"].toInt(0),
127+
obj["cropTop"].toInt(0),
128+
obj["cropBottom"].toInt(0));
129+
130+
// device input
131+
_grabber.setInput(obj["input"].toInt(-1));
132+
133+
// device resolution
134+
_grabber.setWidthHeight(obj["width"].toInt(0), obj["height"].toInt(0));
135+
136+
// device framerate
137+
_grabber.setFramerate(obj["fps"].toInt(15));
138+
139+
// CEC Standby
140+
_grabber.setCecDetectionEnable(obj["cecDetection"].toBool(true));
141+
142+
_grabber.setSignalDetectionEnable(obj["signalDetection"].toBool(true));
143+
_grabber.setSignalDetectionOffset(
144+
obj["sDHOffsetMin"].toDouble(0.25),
145+
obj["sDVOffsetMin"].toDouble(0.25),
146+
obj["sDHOffsetMax"].toDouble(0.75),
147+
obj["sDVOffsetMax"].toDouble(0.75));
148+
_grabber.setSignalThreshold(
149+
obj["redSignalThreshold"].toDouble(0.0)/100.0,
150+
obj["greenSignalThreshold"].toDouble(0.0)/100.0,
151+
obj["blueSignalThreshold"].toDouble(0.0)/100.0);
152+
_grabber.setDeviceVideoStandard(
153+
obj["device"].toString("auto"),
154+
parseVideoStandard(obj["standard"].toString("no-change")));
155+
}
156+
}

libsrc/grabber/x11/X11Wrapper.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,11 @@ void X11Wrapper::action()
2525
}
2626
}
2727

28-
if (_grabber.updateScreenDimensions() >= 0 )
28+
if (isActive())
2929
{
30-
transferFrame(_grabber);
30+
if (_grabber.updateScreenDimensions() >= 0 )
31+
{
32+
transferFrame(_grabber);
33+
}
3134
}
3235
}

libsrc/hyperion/GrabberWrapper.cpp

+42-73
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ void GrabberWrapper::stop()
6161
}
6262
}
6363

64+
bool GrabberWrapper::isActive() const
65+
{
66+
return _timer->isActive();
67+
}
68+
6469
QStringList GrabberWrapper::availableGrabbers()
6570
{
6671
QStringList grabbers;
@@ -110,85 +115,49 @@ void GrabberWrapper::setCropping(unsigned cropLeft, unsigned cropRight, unsigned
110115
_ggrabber->setCropping(cropLeft, cropRight, cropTop, cropBottom);
111116
}
112117

118+
void GrabberWrapper::updateTimer(int interval)
119+
{
120+
if(_updateInterval_ms != interval)
121+
{
122+
_updateInterval_ms = interval;
123+
124+
const bool& timerWasActive = _timer->isActive();
125+
_timer->stop();
126+
_timer->setInterval(_updateInterval_ms);
127+
128+
if(timerWasActive)
129+
_timer->start();
130+
}
131+
}
132+
113133
void GrabberWrapper::handleSettingsUpdate(const settings::type& type, const QJsonDocument& config)
114134
{
115-
if(type == settings::V4L2 || type == settings::SYSTEMCAPTURE)
135+
if(type == settings::SYSTEMCAPTURE && !_grabberName.startsWith("V4L"))
116136
{
117137
// extract settings
118138
const QJsonObject& obj = config.object();
119139

120-
if(type == settings::SYSTEMCAPTURE && !_grabberName.startsWith("V4L"))
121-
{
122-
// width/height
123-
_ggrabber->setWidthHeight(obj["width"].toInt(96), obj["height"].toInt(96));
124-
125-
// display index for MAC
126-
_ggrabber->setDisplayIndex(obj["display"].toInt(0));
127-
128-
// device path for Framebuffer
129-
_ggrabber->setDevicePath(obj["device"].toString("/dev/fb0"));
130-
131-
// pixel decimation for x11
132-
_ggrabber->setPixelDecimation(obj["pixelDecimation"].toInt(8));
133-
134-
// crop for system capture
135-
_ggrabber->setCropping(
136-
obj["cropLeft"].toInt(0),
137-
obj["cropRight"].toInt(0),
138-
obj["cropTop"].toInt(0),
139-
obj["cropBottom"].toInt(0));
140-
141-
// eval new update timer (not for v4l)
142-
if(_updateInterval_ms != 1000/obj["frequency_Hz"].toInt(10))
143-
{
144-
_updateInterval_ms = 1000/obj["frequency_Hz"].toInt(10);
145-
const bool& timerWasActive = _timer->isActive();
146-
_timer->stop();
147-
_timer->setInterval(_updateInterval_ms);
148-
if(timerWasActive)
149-
_timer->start();
150-
}
151-
}
152-
153-
// v4l instances only!
154-
if(type == settings::V4L2 && _grabberName.startsWith("V4L"))
155-
{
156-
// pixel decimation for v4l
157-
_ggrabber->setPixelDecimation(obj["sizeDecimation"].toInt(8));
158-
159-
// crop for v4l
160-
_ggrabber->setCropping(
161-
obj["cropLeft"].toInt(0),
162-
obj["cropRight"].toInt(0),
163-
obj["cropTop"].toInt(0),
164-
obj["cropBottom"].toInt(0));
165-
166-
// device input
167-
_ggrabber->setInput(obj["input"].toInt(-1));
168-
169-
// device resolution
170-
_ggrabber->setWidthHeight(obj["width"].toInt(0), obj["height"].toInt(0));
171-
172-
// device framerate
173-
_ggrabber->setFramerate(obj["fps"].toInt(15));
174-
175-
// CEC Standby
176-
_ggrabber->setCecDetectionEnable(obj["cecDetection"].toBool(true));
177-
178-
_ggrabber->setSignalDetectionEnable(obj["signalDetection"].toBool(true));
179-
_ggrabber->setSignalDetectionOffset(
180-
obj["sDHOffsetMin"].toDouble(0.25),
181-
obj["sDVOffsetMin"].toDouble(0.25),
182-
obj["sDHOffsetMax"].toDouble(0.75),
183-
obj["sDVOffsetMax"].toDouble(0.75));
184-
_ggrabber->setSignalThreshold(
185-
obj["redSignalThreshold"].toDouble(0.0)/100.0,
186-
obj["greenSignalThreshold"].toDouble(0.0)/100.0,
187-
obj["blueSignalThreshold"].toDouble(0.0)/100.0);
188-
_ggrabber->setDeviceVideoStandard(
189-
obj["device"].toString("auto"),
190-
parseVideoStandard(obj["standard"].toString("no-change")));
191-
}
140+
// width/height
141+
_ggrabber->setWidthHeight(obj["width"].toInt(96), obj["height"].toInt(96));
142+
143+
// display index for MAC
144+
_ggrabber->setDisplayIndex(obj["display"].toInt(0));
145+
146+
// device path for Framebuffer
147+
_ggrabber->setDevicePath(obj["device"].toString("/dev/fb0"));
148+
149+
// pixel decimation for x11
150+
_ggrabber->setPixelDecimation(obj["pixelDecimation"].toInt(8));
151+
152+
// crop for system capture
153+
_ggrabber->setCropping(
154+
obj["cropLeft"].toInt(0),
155+
obj["cropRight"].toInt(0),
156+
obj["cropTop"].toInt(0),
157+
obj["cropBottom"].toInt(0));
158+
159+
// eval new update time
160+
updateTimer(1000/obj["frequency_Hz"].toInt(10));
192161
}
193162
}
194163

libsrc/utils/Logger.cpp

+13-7
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,13 @@ Logger::Logger (const QString & name, LogLevel minLevel)
128128
{
129129
qRegisterMetaType<Logger::T_LOG_MESSAGE>();
130130

131-
int count = LoggerCount.fetchAndAddOrdered(1);
132-
133-
if (_syslogEnabled && count == 1)
131+
if (LoggerCount.fetchAndAddOrdered(1) == 1)
134132
{
135133
#ifndef _WIN32
136-
openlog (_appname.toLocal8Bit(), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0);
134+
if (_syslogEnabled)
135+
{
136+
openlog (_appname.toLocal8Bit(), LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL0);
137+
}
137138
#endif
138139
}
139140
}
@@ -142,11 +143,16 @@ Logger::~Logger()
142143
{
143144
//Debug(this, "logger '%s' destroyed", QSTRING_CSTR(_name) );
144145

145-
int count = LoggerCount.fetchAndSubOrdered(1);
146+
147+
if (LoggerCount.fetchAndSubOrdered(1) == 0)
148+
{
146149
#ifndef _WIN32
147-
if (_syslogEnabled && count == 0)
148-
closelog();
150+
if (_syslogEnabled)
151+
{
152+
closelog();
153+
}
149154
#endif
155+
}
150156
}
151157

152158
void Logger::write(const Logger::T_LOG_MESSAGE & message) const

0 commit comments

Comments
 (0)