2016-05-30 22:38:40 +02:00
# include <unistd.h>
2016-06-29 11:18:32 +02:00
# include <cassert>
2016-07-24 15:18:34 +02:00
# include <stdlib.h>
2013-08-22 22:06:13 +02:00
2013-08-13 11:10:45 +02:00
# include <QCoreApplication>
2013-08-24 11:51:52 +02:00
# include <QResource>
2014-01-28 22:27:02 +01:00
# include <QLocale>
2016-05-24 19:56:43 +02:00
# include <QFile>
2016-06-17 01:25:40 +02:00
# include <QHostInfo>
2016-06-25 15:15:23 +02:00
# include <QHostAddress>
2016-08-04 10:53:26 +02:00
# include <QString>
# include <QJsonDocument>
# include <QJsonObject>
# include <QJsonValue>
2016-06-20 23:41:07 +02:00
# include <cstdint>
# include <limits>
2013-08-13 11:10:45 +02:00
2013-11-19 23:02:41 +01:00
# include "HyperionConfig.h"
2016-08-04 10:53:26 +02:00
# include <utils/jsonschema/JsonFactory.h> // DEPRECATED | Remove this only when the conversion have been completed from JsonCpp to QTJson
# include <utils/jsonschema/QJsonFactory.h>
2013-08-14 10:54:49 +02:00
# include <hyperion/Hyperion.h>
2016-08-06 08:28:42 +02:00
# include <hyperion/PriorityMuxer.h>
2013-11-24 16:10:48 +01:00
# include <effectengine/EffectEngine.h>
2016-05-31 22:55:11 +02:00
# include <bonjour/bonjourserviceregister.h>
# include <bonjour/bonjourrecord.h>
2013-08-17 15:39:29 +02:00
# include <jsonserver/JsonServer.h>
2016-06-12 22:27:24 +02:00
# include <protoserver/ProtoServer.h>
# include <boblightserver/BoblightServer.h>
2016-06-20 08:38:12 +02:00
# include <udplistener/UDPListener.h>
2016-05-30 22:38:40 +02:00
2016-06-17 01:25:40 +02:00
# include "hyperiond.h"
2013-11-08 22:18:10 +01:00
2013-08-22 22:06:13 +02:00
2016-08-06 08:28:42 +02:00
HyperionDaemon : : HyperionDaemon ( QString configFile , QObject * parent )
2016-06-19 00:56:47 +02:00
: QObject ( parent )
, _log ( Logger : : getInstance ( " MAIN " ) )
2016-07-10 22:04:31 +02:00
, _kodiVideoChecker ( nullptr )
2016-06-19 00:56:47 +02:00
, _jsonServer ( nullptr )
, _protoServer ( nullptr )
, _boblightServer ( nullptr )
2016-06-20 08:38:12 +02:00
, _udpListener ( nullptr )
2016-06-19 00:56:47 +02:00
, _v4l2Grabber ( nullptr )
, _dispmanx ( nullptr )
2016-07-24 15:18:34 +02:00
, _x11Grabber ( nullptr )
2016-06-19 00:56:47 +02:00
, _amlGrabber ( nullptr )
, _fbGrabber ( nullptr )
, _osxGrabber ( nullptr )
2016-06-20 09:10:23 +02:00
, _hyperion ( nullptr )
2016-06-19 00:56:47 +02:00
{
2016-08-06 08:28:42 +02:00
loadConfig ( configFile ) ;
2016-08-04 10:53:26 +02:00
2016-08-06 08:28:42 +02:00
_hyperion = Hyperion : : initInstance ( _config , configFile . toStdString ( ) ) ;
2016-06-27 23:56:21 +02:00
if ( Logger : : getLogLevel ( ) = = Logger : : WARNING )
{
2016-08-04 10:53:26 +02:00
if ( _qconfig . contains ( " logger " ) )
2016-06-27 23:56:21 +02:00
{
2016-08-04 10:53:26 +02:00
const QJsonObject & logConfig = _qconfig [ " logger " ] . toObject ( ) ;
std : : string level = logConfig [ " level " ] . toString ( " warn " ) . toStdString ( ) ; // silent warn verbose debug
2016-06-27 23:56:21 +02:00
if ( level = = " silent " ) Logger : : setLogLevel ( Logger : : OFF ) ;
else if ( level = = " warn " ) Logger : : setLogLevel ( Logger : : WARNING ) ;
else if ( level = = " verbose " ) Logger : : setLogLevel ( Logger : : INFO ) ;
else if ( level = = " debug " ) Logger : : setLogLevel ( Logger : : DEBUG ) ;
else Error ( Logger : : getInstance ( " LOGGER " ) , " log level '%s' used in config is unknown. valid: silent warn verbose debug " , level . c_str ( ) ) ;
}
}
else
{
2016-08-04 10:53:26 +02:00
WarningIf ( _qconfig . contains ( " logger " ) , Logger : : getInstance ( " LOGGER " ) , " Logger settings overriden by command line argument " ) ;
2016-06-27 23:56:21 +02:00
}
2016-08-06 08:28:42 +02:00
Info ( _log , " Hyperion initialised " ) ;
2016-06-19 00:56:47 +02:00
}
HyperionDaemon : : ~ HyperionDaemon ( )
{
delete _amlGrabber ;
delete _dispmanx ;
delete _fbGrabber ;
delete _osxGrabber ;
delete _v4l2Grabber ;
2016-07-10 22:04:31 +02:00
delete _kodiVideoChecker ;
2016-06-19 00:56:47 +02:00
delete _jsonServer ;
delete _protoServer ;
delete _boblightServer ;
2016-06-20 08:38:12 +02:00
delete _udpListener ;
2016-06-20 09:10:23 +02:00
delete _hyperion ;
2016-06-19 00:56:47 +02:00
}
void HyperionDaemon : : run ( )
{
2016-06-20 23:41:07 +02:00
startInitialEffect ( ) ;
2016-07-10 22:04:31 +02:00
createKODIVideoChecker ( ) ;
2016-06-19 00:56:47 +02:00
// ---- network services -----
startNetworkServices ( ) ;
// ---- grabber -----
createGrabberV4L2 ( ) ;
2016-07-24 15:18:34 +02:00
createSystemFrameGrabber ( ) ;
2016-06-19 00:56:47 +02:00
2016-07-27 22:52:59 +02:00
# if !defined(ENABLE_DISPMANX) && !defined(ENABLE_OSX) && !defined(ENABLE_FB) && !defined(ENABLE_X11) && !defined(ENABLE_AMLOGIC)
2016-08-04 10:53:26 +02:00
WarningIf ( _qconfig . contains ( " framegrabber " ) , _log , " No grabber can be instantiated, because all grabbers have been left out from the build " ) ;
2016-06-19 00:56:47 +02:00
# endif
2016-08-06 08:28:42 +02:00
Info ( _log , " Hyperion started " ) ;
2016-06-19 00:56:47 +02:00
}
2016-08-04 10:53:26 +02:00
void HyperionDaemon : : loadConfig ( const QString & configFile )
{
2016-08-06 08:28:42 +02:00
Info ( _log , " Selected configuration file: %s " , configFile . toUtf8 ( ) . constData ( ) ) ;
2016-08-04 10:53:26 +02:00
// make sure the resources are loaded (they may be left out after static linking)
Q_INIT_RESOURCE ( resource ) ;
QJsonParseError error ;
// read the json schema from the resource
QFile schemaData ( " :/hyperion-schema " ) ;
if ( ! schemaData . open ( QIODevice : : ReadOnly ) )
{
std : : stringstream error ;
error < < " Schema not found: " < < schemaData . errorString ( ) . toStdString ( ) ;
throw std : : runtime_error ( error . str ( ) ) ;
}
QByteArray schema = schemaData . readAll ( ) ;
QJsonDocument schemaJson = QJsonDocument : : fromJson ( schema , & error ) ;
if ( error . error ! = QJsonParseError : : NoError )
{
// report to the user the failure and their locations in the document.
int errorLine ( 0 ) , errorColumn ( 0 ) ;
for ( int i = 0 , count = qMin ( error . offset , schema . size ( ) ) ; i < count ; + + i )
{
+ + errorColumn ;
if ( schema . at ( i ) = = ' \n ' )
{
errorColumn = 0 ;
+ + errorLine ;
}
}
std : : stringstream sstream ;
sstream < < " ERROR: Json schema wrong: " < < error . errorString ( ) . toStdString ( ) < < " at Line: " < < errorLine < < " , Column: " < < errorColumn ;
throw std : : runtime_error ( sstream . str ( ) ) ;
}
QJsonSchemaChecker schemaChecker ;
schemaChecker . setSchema ( schemaJson . object ( ) ) ;
2016-08-06 08:28:42 +02:00
_config = JsonFactory : : readJson ( configFile . toStdString ( ) ) ; // DEPRECATED | Remove this only when the conversion have been completed from JsonCpp to QTJson
2016-08-04 10:53:26 +02:00
_qconfig = QJsonFactory : : readJson ( configFile ) ;
if ( ! schemaChecker . validate ( _qconfig ) )
{
for ( std : : list < std : : string > : : const_iterator i = schemaChecker . getMessages ( ) . begin ( ) ; i ! = schemaChecker . getMessages ( ) . end ( ) ; + + i )
{
std : : cout < < * i < < std : : endl ;
}
throw std : : runtime_error ( " ERROR: Json validation failed " ) ;
}
}
2016-06-19 00:56:47 +02:00
2016-06-20 23:41:07 +02:00
void HyperionDaemon : : startInitialEffect ( )
2013-08-24 11:51:52 +02:00
{
2016-08-06 08:28:42 +02:00
# define FGCONFIG_ARRAY fgEffectConfig.toArray()
# define BGCONFIG_ARRAY bgEffectConfig.toArray()
2016-06-17 01:25:40 +02:00
Hyperion * hyperion = Hyperion : : getInstance ( ) ;
2013-08-24 11:51:52 +02:00
2013-10-13 14:48:59 +02:00
// create boot sequence if the configuration is present
2016-06-20 23:41:07 +02:00
if ( _config . isMember ( " initialEffect " ) )
2013-08-25 18:20:19 +02:00
{
2016-08-06 08:28:42 +02:00
const QJsonObject & effectConfig = _qconfig [ " initialEffect " ] . toObject ( ) ;
const int FG_PRIORITY = 0 ;
2016-06-20 23:41:07 +02:00
const int DURATION_INFINITY = 0 ;
2016-08-06 08:28:42 +02:00
const int BG_PRIORITY = PriorityMuxer : : LOWEST_PRIORITY - 1 ;
2015-08-20 09:51:44 +02:00
2016-03-12 19:21:47 +01:00
// clear the leds
2016-08-06 08:28:42 +02:00
hyperion - > setColor ( FG_PRIORITY , ColorRgb : : BLACK , DURATION_INFINITY , false ) ;
2016-01-31 22:38:30 +01:00
2016-06-20 23:41:07 +02:00
// initial foreground effect/color
2016-08-06 08:28:42 +02:00
const QJsonValue fgEffectConfig = effectConfig [ " foreground-effect " ] ;
2016-06-20 23:41:07 +02:00
int default_fg_duration_ms = 3000 ;
2016-08-06 08:28:42 +02:00
int fg_duration_ms = effectConfig [ " foreground-effect-duration_ms " ] . toInt ( default_fg_duration_ms ) ;
2016-06-20 23:41:07 +02:00
if ( fg_duration_ms = = DURATION_INFINITY )
2016-01-31 22:38:30 +01:00
{
2016-06-20 23:41:07 +02:00
fg_duration_ms = default_fg_duration_ms ;
Warning ( _log , " foreground effect duration 'infinity' is forbidden, set to default value %d ms " , default_fg_duration_ms ) ;
2013-12-13 19:59:01 +01:00
}
2016-08-06 08:28:42 +02:00
if ( ! fgEffectConfig . isNull ( ) & & fgEffectConfig . isArray ( ) & & FGCONFIG_ARRAY . size ( ) = = 3 )
2013-12-13 19:59:01 +01:00
{
2016-06-20 23:41:07 +02:00
ColorRgb fg_color = {
2016-08-06 08:28:42 +02:00
( uint8_t ) FGCONFIG_ARRAY . at ( 0 ) . toInt ( 0 ) ,
( uint8_t ) FGCONFIG_ARRAY . at ( 1 ) . toInt ( 0 ) ,
( uint8_t ) FGCONFIG_ARRAY . at ( 2 ) . toInt ( 0 )
2016-03-12 19:21:47 +01:00
} ;
2016-08-06 08:28:42 +02:00
hyperion - > setColor ( FG_PRIORITY , fg_color , fg_duration_ms , false ) ;
2016-06-20 23:41:07 +02:00
Info ( _log , " Inital foreground color set (%d %d %d) " , fg_color . red , fg_color . green , fg_color . blue ) ;
}
2016-08-06 08:28:42 +02:00
else if ( ! fgEffectConfig . isNull ( ) & & fgEffectConfig . isArray ( ) & & FGCONFIG_ARRAY . size ( ) = = 1 & & FGCONFIG_ARRAY . at ( 0 ) . isString ( ) )
2016-06-20 23:41:07 +02:00
{
2016-08-06 08:28:42 +02:00
const std : : string fgEffectName = FGCONFIG_ARRAY . at ( 0 ) . toString ( ) . toStdString ( ) ;
int result = effectConfig . contains ( " foreground-effect-args " )
// ? hyperion->setEffect(fgEffectName, effectConfig["foreground-effect-args"], FG_PRIORITY, fg_duration_ms)
? hyperion - > setEffect ( fgEffectName , _config [ " initialEffect " ] [ " foreground-effect-args " ] , FG_PRIORITY , fg_duration_ms )
: hyperion - > setEffect ( fgEffectName , FG_PRIORITY , fg_duration_ms ) ;
Info ( _log , " Inital foreground effect '%s' %s " , fgEffectName . c_str ( ) , ( ( result = = 0 ) ? " started " : " failed " ) ) ;
2013-10-16 18:04:43 +02:00
}
2016-03-12 19:21:47 +01:00
2016-06-20 23:41:07 +02:00
// initial background effect/color
2016-08-06 08:28:42 +02:00
const QJsonValue bgEffectConfig = effectConfig [ " background-effect " ] ;
if ( ! bgEffectConfig . isNull ( ) & & bgEffectConfig . isArray ( ) & & BGCONFIG_ARRAY . size ( ) = = 3 )
2016-06-20 23:41:07 +02:00
{
ColorRgb bg_color = {
2016-08-06 08:28:42 +02:00
( uint8_t ) BGCONFIG_ARRAY . at ( 0 ) . toInt ( 0 ) ,
( uint8_t ) BGCONFIG_ARRAY . at ( 1 ) . toInt ( 0 ) ,
( uint8_t ) BGCONFIG_ARRAY . at ( 2 ) . toInt ( 0 )
2016-06-20 23:41:07 +02:00
} ;
2016-08-06 08:28:42 +02:00
hyperion - > setColor ( BG_PRIORITY , bg_color , DURATION_INFINITY , false ) ;
2016-06-20 23:41:07 +02:00
Info ( _log , " Inital background color set (%d %d %d) " , bg_color . red , bg_color . green , bg_color . blue ) ;
}
2016-08-06 08:28:42 +02:00
else if ( ! bgEffectConfig . isNull ( ) & & bgEffectConfig . isArray ( ) & & BGCONFIG_ARRAY . size ( ) = = 1 & & BGCONFIG_ARRAY . at ( 0 ) . isString ( ) )
2016-06-20 23:41:07 +02:00
{
2016-08-06 08:28:42 +02:00
const std : : string bgEffectName = BGCONFIG_ARRAY . at ( 0 ) . toString ( ) . toStdString ( ) ;
int result = effectConfig . contains ( " background-effect-args " )
// ? hyperion->setEffect(bgEffectName, effectConfig["background-effect-args"], BG_PRIORITY, fg_duration_ms)
? hyperion - > setEffect ( bgEffectName , _config [ " initialEffect " ] [ " background-effect-args " ] , BG_PRIORITY , DURATION_INFINITY )
: hyperion - > setEffect ( bgEffectName , BG_PRIORITY , DURATION_INFINITY ) ;
2016-06-20 23:41:07 +02:00
Info ( _log , " Inital background effect '%s' %s " , bgEffectName . c_str ( ) , ( ( result = = 0 ) ? " started " : " failed " ) ) ;
}
2013-08-25 18:20:19 +02:00
}
2016-08-06 08:28:42 +02:00
# undef FGCONFIG_ARRAY
# undef BGCONFIG_ARRAY
2016-05-30 22:38:40 +02:00
}
2013-08-23 18:24:10 +02:00
2016-05-30 22:38:40 +02:00
2016-07-10 22:04:31 +02:00
// create KODI video checker if the _configuration is present
void HyperionDaemon : : createKODIVideoChecker ( )
2016-05-30 22:38:40 +02:00
{
2016-08-04 10:53:26 +02:00
bool kodiCheckerConfigured = _qconfig . contains ( " kodiVideoChecker " ) ;
2016-07-10 22:04:31 +02:00
2016-08-04 10:53:26 +02:00
const QJsonObject & videoCheckerConfig = _qconfig [ " kodiVideoChecker " ] . toObject ( ) ;
2016-07-10 22:04:31 +02:00
_kodiVideoChecker = KODIVideoChecker : : initInstance (
2016-08-04 10:53:26 +02:00
videoCheckerConfig [ " kodiAddress " ] . toString ( " 127.0.0.1 " ) ,
videoCheckerConfig [ " kodiTcpPort " ] . toInt ( 9090 ) ,
videoCheckerConfig [ " grabVideo " ] . toBool ( true ) ,
videoCheckerConfig [ " grabPictures " ] . toBool ( true ) ,
videoCheckerConfig [ " grabAudio " ] . toBool ( true ) ,
videoCheckerConfig [ " grabMenu " ] . toBool ( false ) ,
videoCheckerConfig [ " grabPause " ] . toBool ( true ) ,
videoCheckerConfig [ " grabScreensaver " ] . toBool ( false ) ,
videoCheckerConfig [ " enable3DDetection " ] . toBool ( true ) ) ;
2016-08-06 08:28:42 +02:00
Debug ( _log , " KODI checker created " ) ;
2016-07-10 22:04:31 +02:00
2016-08-04 10:53:26 +02:00
if ( kodiCheckerConfigured & & videoCheckerConfig [ " enable " ] . toBool ( true ) )
2013-10-13 14:48:59 +02:00
{
2016-07-10 22:04:31 +02:00
_kodiVideoChecker - > start ( ) ;
2013-08-24 11:51:52 +02:00
}
2016-05-30 22:38:40 +02:00
}
2013-08-23 20:44:53 +02:00
2016-06-19 00:56:47 +02:00
void HyperionDaemon : : startNetworkServices ( )
2016-05-30 22:38:40 +02:00
{
2016-07-10 22:04:31 +02:00
KODIVideoChecker * kodiVideoChecker = KODIVideoChecker : : getInstance ( ) ;
2016-06-17 01:25:40 +02:00
2016-02-16 15:41:40 +01:00
// Create Json server if configuration is present
2016-06-08 11:53:01 +02:00
unsigned int jsonPort = 19444 ;
2016-08-04 10:53:26 +02:00
if ( _qconfig . contains ( " jsonServer " ) )
2016-02-16 15:41:40 +01:00
{
2016-08-04 10:53:26 +02:00
const QJsonObject & jsonServerConfig = _qconfig [ " jsonServer " ] . toObject ( ) ;
2016-06-08 11:53:01 +02:00
//jsonEnable = jsonServerConfig.get("enable", true).asBool();
2016-08-04 10:53:26 +02:00
jsonPort = jsonServerConfig [ " port " ] . toInt ( jsonPort ) ;
2016-02-16 15:41:40 +01:00
}
2016-08-04 10:53:26 +02:00
_jsonServer = new JsonServer ( jsonPort ) ;
2016-06-19 00:56:47 +02:00
Info ( _log , " Json server created and started on port %d " , _jsonServer - > getPort ( ) ) ;
2016-06-08 11:53:01 +02:00
2016-02-16 15:41:40 +01:00
// Create Proto server if configuration is present
2016-06-08 11:53:01 +02:00
unsigned int protoPort = 19445 ;
2016-08-04 10:53:26 +02:00
if ( _qconfig . contains ( " protoServer " ) )
2016-02-16 15:41:40 +01:00
{
2016-08-04 10:53:26 +02:00
const QJsonObject & protoServerConfig = _qconfig [ " protoServer " ] . toObject ( ) ;
2016-06-08 11:53:01 +02:00
//protoEnable = protoServerConfig.get("enable", true).asBool();
2016-08-04 10:53:26 +02:00
protoPort = protoServerConfig [ " port " ] . toInt ( protoPort ) ;
2016-06-08 11:53:01 +02:00
}
2016-08-04 10:53:26 +02:00
_protoServer = new ProtoServer ( protoPort ) ;
2016-07-10 22:04:31 +02:00
if ( kodiVideoChecker ! = nullptr )
2016-06-08 11:53:01 +02:00
{
2016-07-10 22:04:31 +02:00
QObject : : connect ( kodiVideoChecker , SIGNAL ( grabbingMode ( GrabbingMode ) ) , _protoServer , SIGNAL ( grabbingMode ( GrabbingMode ) ) ) ;
QObject : : connect ( kodiVideoChecker , SIGNAL ( videoMode ( VideoMode ) ) , _protoServer , SIGNAL ( videoMode ( VideoMode ) ) ) ;
2016-06-08 11:53:01 +02:00
}
2016-06-19 00:56:47 +02:00
Info ( _log , " Proto server created and started on port %d " , _protoServer - > getPort ( ) ) ;
2016-06-04 19:26:34 +02:00
2016-06-19 00:56:47 +02:00
// Create Boblight server if configuration is present
2016-08-04 10:53:26 +02:00
if ( _qconfig . contains ( " boblightServer " ) )
2016-06-19 00:56:47 +02:00
{
2016-08-04 10:53:26 +02:00
const QJsonObject & boblightServerConfig = _qconfig [ " boblightServer " ] . toObject ( ) ;
2016-06-27 22:43:43 +02:00
_boblightServer = new BoblightServer (
2016-08-04 10:53:26 +02:00
boblightServerConfig [ " priority " ] . toInt ( 710 ) ,
boblightServerConfig [ " port " ] . toInt ( )
2016-06-27 22:43:43 +02:00
) ;
Debug ( _log , " Boblight server created " ) ;
2016-08-04 10:53:26 +02:00
if ( boblightServerConfig [ " enable " ] . toBool ( true ) )
2016-06-20 15:17:29 +02:00
{
2016-06-27 22:43:43 +02:00
_boblightServer - > start ( ) ;
2016-06-20 15:17:29 +02:00
}
2016-06-19 00:56:47 +02:00
}
2016-06-08 11:53:01 +02:00
2016-06-20 23:41:07 +02:00
// Create UDP listener if configuration is present
2016-08-04 10:53:26 +02:00
if ( _qconfig . contains ( " udpListener " ) )
2016-06-20 23:41:07 +02:00
{
2016-08-04 10:53:26 +02:00
const QJsonObject & udpListenerConfig = _qconfig [ " udpListener " ] . toObject ( ) ;
2016-06-27 09:27:11 +02:00
_udpListener = new UDPListener (
2016-08-04 10:53:26 +02:00
udpListenerConfig [ " priority " ] . toInt ( 700 ) ,
udpListenerConfig [ " timeout " ] . toInt ( 10000 ) ,
udpListenerConfig [ " address " ] . toString ( " " ) ,
udpListenerConfig [ " port " ] . toInt ( 2801 ) ,
udpListenerConfig [ " shared " ] . toBool ( false ) ) ;
2016-06-27 22:43:43 +02:00
Debug ( _log , " UDP listener created " ) ;
2016-06-27 09:27:11 +02:00
2016-08-04 10:53:26 +02:00
if ( udpListenerConfig [ " enable " ] . toBool ( true ) )
2016-06-20 15:17:29 +02:00
{
2016-06-27 09:27:11 +02:00
_udpListener - > start ( ) ;
2016-06-20 15:17:29 +02:00
}
2016-06-20 23:41:07 +02:00
}
2016-06-20 08:38:12 +02:00
2016-06-20 15:17:29 +02:00
// zeroconf description - $leddevicename@$hostname
2016-08-04 10:53:26 +02:00
const QJsonObject & deviceConfig = _qconfig [ " device " ] . toObject ( ) ;
const std : : string mDNSDescr = ( deviceConfig [ " name " ] . toString ( " " ) . toStdString ( )
2016-06-20 15:17:29 +02:00
+ " @ " +
QHostInfo : : localHostName ( ) . toStdString ( )
) ;
// zeroconf udp listener
if ( _udpListener ! = nullptr ) {
BonjourServiceRegister * bonjourRegister_udp = new BonjourServiceRegister ( ) ;
bonjourRegister_udp - > registerService (
BonjourRecord ( mDNSDescr . c_str ( ) , " _hyperiond-rgbled._udp " , QString ( ) ) ,
_udpListener - > getPort ( )
) ;
2016-07-11 17:08:22 +02:00
Debug ( _log , " UDP LIstener mDNS responder started " ) ;
2016-06-20 15:17:29 +02:00
}
2016-06-19 00:56:47 +02:00
// zeroconf json
2016-06-14 20:14:06 +02:00
BonjourServiceRegister * bonjourRegister_json = new BonjourServiceRegister ( ) ;
2016-06-20 15:17:29 +02:00
bonjourRegister_json - > registerService (
BonjourRecord ( mDNSDescr . c_str ( ) , " _hyperiond-json._tcp " , QString ( ) ) ,
_jsonServer - > getPort ( )
) ;
2016-07-11 17:08:22 +02:00
Debug ( _log , " Json mDNS responder started " ) ;
2016-06-08 11:53:01 +02:00
2016-06-19 00:56:47 +02:00
// zeroconf proto
2016-06-14 20:14:06 +02:00
BonjourServiceRegister * bonjourRegister_proto = new BonjourServiceRegister ( ) ;
2016-06-20 15:17:29 +02:00
bonjourRegister_proto - > registerService (
BonjourRecord ( mDNSDescr . c_str ( ) , " _hyperiond-proto._tcp " , QString ( ) ) ,
_protoServer - > getPort ( )
) ;
2016-07-11 17:08:22 +02:00
Debug ( _log , " Proto mDNS responder started " ) ;
2016-05-30 22:38:40 +02:00
}
2016-02-16 15:41:40 +01:00
2016-07-24 15:18:34 +02:00
void HyperionDaemon : : createSystemFrameGrabber ( )
2016-05-30 22:38:40 +02:00
{
2016-08-04 10:53:26 +02:00
if ( _qconfig . contains ( " framegrabber " ) )
2013-10-13 14:48:59 +02:00
{
2016-08-04 10:53:26 +02:00
const QJsonObject & grabberConfig = _qconfig [ " framegrabber " ] . toObject ( ) ;
if ( grabberConfig [ " enable " ] . toBool ( true ) )
2016-07-13 12:14:02 +02:00
{
2016-08-04 10:53:26 +02:00
_grabber_width = grabberConfig [ " width " ] . toInt ( 96 ) ;
_grabber_height = grabberConfig [ " height " ] . toInt ( 96 ) ;
_grabber_frequency = grabberConfig [ " frequency_Hz " ] . toInt ( 10 ) ;
_grabber_priority = grabberConfig [ " priority " ] . toInt ( 900 ) ;
2016-07-27 22:52:59 +02:00
2016-08-04 10:53:26 +02:00
_grabber_cropLeft = grabberConfig [ " cropLeft " ] . toInt ( 0 ) ;
_grabber_cropRight = grabberConfig [ " cropRight " ] . toInt ( 0 ) ;
_grabber_cropTop = grabberConfig [ " cropTop " ] . toInt ( 0 ) ;
_grabber_cropBottom = grabberConfig [ " cropBottom " ] . toInt ( 0 ) ;
2016-07-27 22:52:59 +02:00
2016-07-24 15:18:34 +02:00
# ifdef ENABLE_OSX
2016-08-04 10:53:26 +02:00
QString type = " osx " ;
2016-07-24 15:18:34 +02:00
# else
2016-08-04 10:53:26 +02:00
QString type = grabberConfig [ " type " ] . toString ( " auto " ) ;
2016-07-24 15:18:34 +02:00
# endif
QFile amvideo ( " /dev/amvideo " ) ;
// auto eval of type
if ( type = = " auto " )
{
// dispmanx -> on raspi
// TODO currently a compile option
# ifdef ENABLE_DISPMANX
if ( true )
# else
if ( false )
# endif
{
type = " dispmanx " ;
}
// amlogic -> /dev/amvideo exists
else if ( amvideo . exists ( ) )
{
type = " amlogic " ;
}
// x11 -> if DISPLAY is set
else if ( getenv ( " DISPLAY " ) ! = NULL )
{
type = " x11 " ;
}
// framebuffer -> if nothing other applies
else
{
2016-08-08 00:17:00 +02:00
type = " framebuffer " ;
2016-07-24 15:18:34 +02:00
}
2016-08-04 10:53:26 +02:00
Info ( _log , " set screen capture device to '%s' " , type . constData ( ) ) ;
2016-07-24 15:18:34 +02:00
}
if ( type = = " framebuffer " ) createGrabberFramebuffer ( grabberConfig ) ;
2016-07-27 22:52:59 +02:00
else if ( type = = " dispmanx " ) createGrabberDispmanx ( ) ;
else if ( type = = " amlogic " ) { createGrabberAmlogic ( ) ; createGrabberFramebuffer ( grabberConfig ) ; }
2016-07-24 15:18:34 +02:00
else if ( type = = " osx " ) createGrabberOsx ( grabberConfig ) ;
else if ( type = = " x11 " ) createGrabberX11 ( grabberConfig ) ;
2016-08-04 10:53:26 +02:00
else WarningIf ( type ! = " " , _log , " unknown framegrabber type '%s' " , type . constData ( ) ) ;
2016-07-24 15:18:34 +02:00
InfoIf ( type = = " " , _log , " screen capture device disabled " ) ;
2016-07-13 12:14:02 +02:00
}
2013-10-13 14:48:59 +02:00
}
2016-07-24 15:18:34 +02:00
}
2016-07-27 22:52:59 +02:00
void HyperionDaemon : : createGrabberDispmanx ( )
2016-07-24 15:18:34 +02:00
{
# ifdef ENABLE_DISPMANX
2016-07-27 22:52:59 +02:00
_dispmanx = new DispmanxWrapper ( _grabber_width , _grabber_height , _grabber_frequency , _grabber_priority ) ;
_dispmanx - > setCropping ( _grabber_cropLeft , _grabber_cropRight , _grabber_cropTop , _grabber_cropBottom ) ;
2016-07-24 15:18:34 +02:00
QObject : : connect ( _kodiVideoChecker , SIGNAL ( grabbingMode ( GrabbingMode ) ) , _dispmanx , SLOT ( setGrabbingMode ( GrabbingMode ) ) ) ;
QObject : : connect ( _kodiVideoChecker , SIGNAL ( videoMode ( VideoMode ) ) , _dispmanx , SLOT ( setVideoMode ( VideoMode ) ) ) ;
QObject : : connect ( _dispmanx , SIGNAL ( emitImage ( int , const Image < ColorRgb > & , const int ) ) , _protoServer , SLOT ( sendImageToProtoSlaves ( int , const Image < ColorRgb > & , const int ) ) ) ;
_dispmanx - > start ( ) ;
Info ( _log , " DISPMANX frame grabber created and started " ) ;
2016-06-19 00:56:47 +02:00
# else
2016-08-04 10:53:26 +02:00
ErrorIf ( _qconfig . contains ( " framegrabber " ) , _log , " The dispmanx framegrabber can not be instantiated, because it has been left out from the build " ) ;
2015-01-18 00:04:45 +01:00
# endif
2016-06-17 01:25:40 +02:00
}
2013-10-13 14:48:59 +02:00
2016-06-17 01:25:40 +02:00
2016-07-27 22:52:59 +02:00
void HyperionDaemon : : createGrabberAmlogic ( )
2016-07-24 15:18:34 +02:00
{
# ifdef ENABLE_AMLOGIC
2016-07-27 22:52:59 +02:00
_amlGrabber = new AmlogicWrapper ( _grabber_width , _grabber_height , _grabber_frequency , _grabber_priority - 1 ) ;
2016-07-24 15:18:34 +02:00
QObject : : connect ( _kodiVideoChecker , SIGNAL ( grabbingMode ( GrabbingMode ) ) , _amlGrabber , SLOT ( setGrabbingMode ( GrabbingMode ) ) ) ;
QObject : : connect ( _kodiVideoChecker , SIGNAL ( videoMode ( VideoMode ) ) , _amlGrabber , SLOT ( setVideoMode ( VideoMode ) ) ) ;
QObject : : connect ( _amlGrabber , SIGNAL ( emitImage ( int , const Image < ColorRgb > & , const int ) ) , _protoServer , SLOT ( sendImageToProtoSlaves ( int , const Image < ColorRgb > & , const int ) ) ) ;
_amlGrabber - > start ( ) ;
Info ( _log , " AMLOGIC grabber created and started " ) ;
# else
Error ( _log , " The AMLOGIC grabber can not be instantiated, because it has been left out from the build " ) ;
# endif
}
2016-08-04 10:53:26 +02:00
void HyperionDaemon : : createGrabberX11 ( const QJsonObject & grabberConfig )
2016-07-24 15:18:34 +02:00
{
# ifdef ENABLE_X11
_x11Grabber = new X11Wrapper (
2016-08-04 10:53:26 +02:00
grabberConfig [ " useXGetImage " ] . toBool ( false ) ,
2016-07-27 22:52:59 +02:00
_grabber_cropLeft , _grabber_cropRight , _grabber_cropTop , _grabber_cropBottom ,
2016-08-04 10:53:26 +02:00
grabberConfig [ " horizontalPixelDecimation " ] . toInt ( 8 ) ,
grabberConfig [ " verticalPixelDecimation " ] . toInt ( 8 ) ,
2016-07-27 22:52:59 +02:00
_grabber_frequency , _grabber_priority ) ;
2016-07-24 15:18:34 +02:00
QObject : : connect ( _kodiVideoChecker , SIGNAL ( grabbingMode ( GrabbingMode ) ) , _x11Grabber , SLOT ( setGrabbingMode ( GrabbingMode ) ) ) ;
QObject : : connect ( _kodiVideoChecker , SIGNAL ( videoMode ( VideoMode ) ) , _x11Grabber , SLOT ( setVideoMode ( VideoMode ) ) ) ;
QObject : : connect ( _x11Grabber , SIGNAL ( emitImage ( int , const Image < ColorRgb > & , const int ) ) , _protoServer , SLOT ( sendImageToProtoSlaves ( int , const Image < ColorRgb > & , const int ) ) ) ;
_x11Grabber - > start ( ) ;
Info ( _log , " X11 grabber created and started " ) ;
# else
Error ( _log , " The X11 grabber can not be instantiated, because it has been left out from the build " ) ;
# endif
}
2016-08-04 10:53:26 +02:00
void HyperionDaemon : : createGrabberFramebuffer ( const QJsonObject & grabberConfig )
2016-07-24 15:18:34 +02:00
{
# ifdef ENABLE_FB
// Construct and start the framebuffer grabber if the configuration is present
_fbGrabber = new FramebufferWrapper (
2016-08-04 10:53:26 +02:00
grabberConfig [ " device " ] . toString ( " /dev/fb0 " ) . toStdString ( ) ,
2016-07-27 22:52:59 +02:00
_grabber_width , _grabber_height , _grabber_frequency , _grabber_priority ) ;
2016-07-24 15:18:34 +02:00
QObject : : connect ( _kodiVideoChecker , SIGNAL ( grabbingMode ( GrabbingMode ) ) , _fbGrabber , SLOT ( setGrabbingMode ( GrabbingMode ) ) ) ;
QObject : : connect ( _kodiVideoChecker , SIGNAL ( videoMode ( VideoMode ) ) , _fbGrabber , SLOT ( setVideoMode ( VideoMode ) ) ) ;
QObject : : connect ( _fbGrabber , SIGNAL ( emitImage ( int , const Image < ColorRgb > & , const int ) ) , _protoServer , SLOT ( sendImageToProtoSlaves ( int , const Image < ColorRgb > & , const int ) ) ) ;
_fbGrabber - > start ( ) ;
Info ( _log , " Framebuffer grabber created and started " ) ;
# else
Error ( _log , " The framebuffer grabber can not be instantiated, because it has been left out from the build " ) ;
# endif
}
2016-08-04 10:53:26 +02:00
void HyperionDaemon : : createGrabberOsx ( const QJsonObject & grabberConfig )
2016-07-24 15:18:34 +02:00
{
# ifdef ENABLE_OSX
// Construct and start the osx grabber if the configuration is present
_osxGrabber = new OsxWrapper (
2016-08-04 10:53:26 +02:00
grabberConfig [ " display " ] . toInt ( 0 ) ,
2016-07-27 22:52:59 +02:00
_grabber_width , _grabber_height , _grabber_frequency , _grabber_priority ) ;
2016-07-24 15:18:34 +02:00
QObject : : connect ( _kodiVideoChecker , SIGNAL ( grabbingMode ( GrabbingMode ) ) , _osxGrabber , SLOT ( setGrabbingMode ( GrabbingMode ) ) ) ;
QObject : : connect ( _kodiVideoChecker , SIGNAL ( videoMode ( VideoMode ) ) , _osxGrabber , SLOT ( setVideoMode ( VideoMode ) ) ) ;
QObject : : connect ( _osxGrabber , SIGNAL ( emitImage ( int , const Image < ColorRgb > & , const int ) ) , _protoServer , SLOT ( sendImageToProtoSlaves ( int , const Image < ColorRgb > & , const int ) ) ) ;
_osxGrabber - > start ( ) ;
Info ( _log , " OSX grabber created and started " ) ;
# else
Error ( _log , " The osx grabber can not be instantiated, because it has been left out from the build " ) ;
# endif
}
2016-06-19 00:56:47 +02:00
void HyperionDaemon : : createGrabberV4L2 ( )
2016-05-30 22:38:40 +02:00
{
2014-02-21 22:30:34 +01:00
// construct and start the v4l2 grabber if the configuration is present
2016-08-04 10:53:26 +02:00
if ( _qconfig . contains ( " grabber-v4l2 " ) )
2014-02-21 22:30:34 +01:00
{
2016-08-04 10:53:26 +02:00
const QJsonObject & grabberConfig = _qconfig [ " grabber-v4l2 " ] . toObject ( ) ;
2016-08-11 07:13:11 +02:00
# ifdef ENABLE_V4L2
_v4l2Grabber = new V4L2Wrapper (
grabberConfig [ " device " ] . toString ( " /dev/video0 " ) . toStdString ( ) ,
grabberConfig [ " input " ] . toInt ( 0 ) ,
parseVideoStandard ( grabberConfig [ " standard " ] . toString ( " no-change " ) . toStdString ( ) ) ,
parsePixelFormat ( grabberConfig [ " pixelFormat " ] . toString ( " no-change " ) . toStdString ( ) ) ,
grabberConfig [ " width " ] . toInt ( - 1 ) ,
grabberConfig [ " height " ] . toInt ( - 1 ) ,
grabberConfig [ " frameDecimation " ] . toInt ( 2 ) ,
grabberConfig [ " sizeDecimation " ] . toInt ( 8 ) ,
grabberConfig [ " redSignalThreshold " ] . toDouble ( 0.0 ) ,
grabberConfig [ " greenSignalThreshold " ] . toDouble ( 0.0 ) ,
grabberConfig [ " blueSignalThreshold " ] . toDouble ( 0.0 ) ,
grabberConfig [ " priority " ] . toInt ( 890 ) ) ;
_v4l2Grabber - > set3D ( parse3DMode ( grabberConfig [ " mode " ] . toString ( " 2D " ) . toStdString ( ) ) ) ;
_v4l2Grabber - > setCropping (
grabberConfig [ " cropLeft " ] . toInt ( 0 ) ,
grabberConfig [ " cropRight " ] . toInt ( 0 ) ,
grabberConfig [ " cropTop " ] . toInt ( 0 ) ,
grabberConfig [ " cropBottom " ] . toInt ( 0 ) ) ;
Debug ( _log , " V4L2 grabber created " ) ;
QObject : : connect ( _v4l2Grabber , SIGNAL ( emitImage ( int ,
const Image < ColorRgb > & , const int ) ) , _protoServer ,
SLOT ( sendImageToProtoSlaves ( int ,
const Image < ColorRgb > & , const int ) ) ) ;
if ( grabberConfig [ " enable " ] . toBool ( true ) & & _v4l2Grabber - > start ( ) ) {
Info ( _log , " V4L2 grabber started " ) ;
}
2016-06-19 00:56:47 +02:00
# else
2016-08-11 07:13:11 +02:00
if ( grabberConfig [ " enable " ] . toBool ( true ) ) {
Error ( _log , " The v4l2 grabber can not be instantiated, because it has been left out from the build " ) ;
}
2014-02-21 22:30:34 +01:00
# endif
2016-08-11 07:13:11 +02:00
}
2016-06-17 01:25:40 +02:00
}