New XBMC checker functionality: 3D video detection (filename based) and screensaver detection

Former-commit-id: ea95e4ecde3ab9378bdf9c4c60950713947bd0ac
This commit is contained in:
johan 2013-12-21 14:32:30 +01:00
parent e1a60e6944
commit 78795b9fa8
12 changed files with 347 additions and 110 deletions

View File

@ -1 +1 @@
c358364291c2377c26ef2912042fae6d7fe50d08 42debced0ba50d4c1801b25ae3ce1a546ec7a94e

View File

@ -9,6 +9,7 @@
#include <utils/ColorRgb.h> #include <utils/ColorRgb.h>
#include <utils/ColorRgba.h> #include <utils/ColorRgba.h>
#include <utils/GrabbingMode.h> #include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
// Forward class declaration // Forward class declaration
class DispmanxFrameGrabber; class DispmanxFrameGrabber;
@ -61,6 +62,12 @@ public slots:
/// ///
void setGrabbingMode(const GrabbingMode mode); void setGrabbingMode(const GrabbingMode mode);
///
/// Set the video mode (2D/3D)
/// @param[in] mode The new video mode
///
void setVideoMode(const VideoMode videoMode);
private: private:
/// The update rate [Hz] /// The update rate [Hz]
const int _updateInterval_ms; const int _updateInterval_ms;

View File

@ -118,6 +118,22 @@ public:
return _pixels[toIndex(x,y)]; return _pixels[toIndex(x,y)];
} }
/// Resize the image
/// @param width The width of the image
/// @param height The height of the image
void resize(const unsigned width, const unsigned height)
{
if ((width*height) > (_endOfPixels-_pixels))
{
delete[] _pixels;
_pixels = new Pixel_T[width*height + 1];
_endOfPixels = _pixels + width*height;
}
_width = width;
_height = height;
}
/// ///
/// Copies another image into this image. The images should have exactly the same size. /// Copies another image into this image. The images should have exactly the same size.
/// ///
@ -165,9 +181,9 @@ private:
private: private:
/// The width of the image /// The width of the image
const unsigned _width; unsigned _width;
/// The height of the image /// The height of the image
const unsigned _height; unsigned _height;
/// The pixels of the image /// The pixels of the image
Pixel_T* _pixels; Pixel_T* _pixels;

11
include/utils/VideoMode.h Normal file
View File

@ -0,0 +1,11 @@
#pragma once
/**
* Enumeration of the possible modes in which video can be playing (2D, 3D)
*/
enum VideoMode
{
VIDEO_2D,
VIDEO_3DSBS,
VIDEO_3DTAB
};

View File

@ -16,6 +16,7 @@
// Utils includes // Utils includes
#include <utils/GrabbingMode.h> #include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
/// ///
/// This class will check if XBMC is playing something. When it does not, this class will send all black data to Hyperion. /// This class will check if XBMC is playing something. When it does not, this class will send all black data to Hyperion.
@ -33,13 +34,14 @@ public:
/// ///
/// @param address Network address of the XBMC instance /// @param address Network address of the XBMC instance
/// @param port Port number to use (XBMC default = 9090) /// @param port Port number to use (XBMC default = 9090)
/// @param interval The interval at which XBMC is polled
/// @param grabVideo Whether or not to grab when the XBMC video player is playing /// @param grabVideo Whether or not to grab when the XBMC video player is playing
/// @param grabPhoto Whether or not to grab when the XBMC photo player is playing /// @param grabPhoto Whether or not to grab when the XBMC photo player is playing
/// @param grabAudio Whether or not to grab when the XBMC audio player is playing /// @param grabAudio Whether or not to grab when the XBMC audio player is playing
/// @param grabMenu Whether or not to grab when nothing is playing (in XBMC menu) /// @param grabMenu Whether or not to grab when nothing is playing (in XBMC menu)
/// @param grabScreensaver Whether or not to grab when the XBMC screensaver is activated
/// @param enable3DDetection Wheter or not to enable the detection of 3D movies playing
/// ///
XBMCVideoChecker(const std::string & address, uint16_t port, uint64_t interval, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu); XBMCVideoChecker(const std::string & address, uint16_t port, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu, bool grabScreensaver, bool enable3DDetection);
/// ///
/// Start polling XBMC /// Start polling XBMC
@ -47,19 +49,34 @@ public:
void start(); void start();
signals: signals:
/// Signal emitted when the grabbing mode changes
void grabbingMode(GrabbingMode grabbingMode); void grabbingMode(GrabbingMode grabbingMode);
private slots: /// Signal emitted when a 3D movie is detected
/// void videoMode(VideoMode videoMode);
/// Send a request to XBMC
///
void sendRequest();
/// private slots:
/// Receive a reply from XBMC /// Receive a reply from XBMC
///
void receiveReply(); void receiveReply();
/// Called when connected to XBMC
void connected();
/// Called when disconnected from XBMC
void disconnected();
/// Called when a connection error was encountered
void connectionError(QAbstractSocket::SocketError error);
private:
/// Set the grabbing mode
void setGrabbingMode(GrabbingMode grabbingMode);
void setScreensaverMode(bool isOnScreensaver);
/// Set the video mode
void setVideoMode(VideoMode videoMode);
private: private:
/// The network address of the XBMC instance /// The network address of the XBMC instance
const QString _address; const QString _address;
@ -67,27 +84,42 @@ private:
/// The port number of XBMC /// The port number of XBMC
const uint16_t _port; const uint16_t _port;
/// The JSON-RPC request message /// The JSON-RPC message to check the active player
const QByteArray _request; const QString _activePlayerRequest;
/// The timer that schedules XBMC queries /// The JSON-RPC message to check the currently playing file
QTimer _timer; const QString _currentPlayingItemRequest;
/// The JSON-RPC message to check the screensaver
const QString _checkScreensaverRequest;
/// The QT TCP Socket with connection to XBMC /// The QT TCP Socket with connection to XBMC
QTcpSocket _socket; QTcpSocket _socket;
/// Flag indicating whether or not to grab when the XBMC video player is playing /// Flag indicating whether or not to grab when the XBMC video player is playing
bool _grabVideo; const bool _grabVideo;
/// Flag indicating whether or not to grab when the XBMC photo player is playing /// Flag indicating whether or not to grab when the XBMC photo player is playing
bool _grabPhoto; const bool _grabPhoto;
/// Flag indicating whether or not to grab when the XBMC audio player is playing /// Flag indicating whether or not to grab when the XBMC audio player is playing
bool _grabAudio; const bool _grabAudio;
/// Flag indicating whether or not to grab when XBMC is playing nothing (in menu) /// Flag indicating whether or not to grab when XBMC is playing nothing (in menu)
bool _grabMenu; const bool _grabMenu;
/// Previous emitted grab state /// Flag inidcating whether or not to grab when the XBMC screensaver is activated
GrabbingMode _previousMode; const bool _grabScreensaver;
/// Flag indicating wheter or not to enable the detection of 3D movies playing
const bool _enable3DDetection;
/// Flag indicating if XBMC is on screensaver
bool _previousScreensaverMode;
/// Previous emitted grab mode
GrabbingMode _previousGrabbingMode;
/// Previous emitted video mode
VideoMode _previousVideoMode;
}; };

View File

@ -61,10 +61,29 @@ void DispmanxFrameGrabber::setFlags(const int vc_flags)
_vc_flags = vc_flags; _vc_flags = vc_flags;
} }
void DispmanxFrameGrabber::setVideoMode(const VideoMode videoMode)
{
switch (videoMode) {
case VIDEO_3DSBS:
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width/2, _height);
break;
case VIDEO_3DTAB:
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width, _height/2);
break;
case VIDEO_2D:
default:
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width, _height);
break;
}
}
void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image) void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
{ {
// Sanity check of the given image size // resize the given image if needed
assert(image.width() == _width && image.height() == _height); if (image.width() != unsigned(_rectangle.width) || image.height() != unsigned(_rectangle.height))
{
image.resize(_rectangle.width, _rectangle.height);
}
// Open the connection to the display // Open the connection to the display
_vc_display = vc_dispmanx_display_open(0); _vc_display = vc_dispmanx_display_open(0);
@ -74,7 +93,7 @@ void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
// Read the snapshot into the memory // Read the snapshot into the memory
void* image_ptr = image.memptr(); void* image_ptr = image.memptr();
const unsigned destPitch = _width * sizeof(ColorRgba); const unsigned destPitch = _rectangle.width * sizeof(ColorRgba);
vc_dispmanx_resource_read_data(_vc_resource, &_rectangle, image_ptr, destPitch); vc_dispmanx_resource_read_data(_vc_resource, &_rectangle, image_ptr, destPitch);
// Close the displaye // Close the displaye

View File

@ -10,6 +10,7 @@
// Utils includes // Utils includes
#include <utils/Image.h> #include <utils/Image.h>
#include <utils/ColorRgba.h> #include <utils/ColorRgba.h>
#include <utils/VideoMode.h>
/// ///
/// The DispmanxFrameGrabber is used for creating snapshots of the display (screenshots) with a /// The DispmanxFrameGrabber is used for creating snapshots of the display (screenshots) with a
@ -34,6 +35,12 @@ public:
/// ///
void setFlags(const int vc_flags); void setFlags(const int vc_flags);
///
/// Set the video mode (2D/3D)
/// @param[in] mode The new video mode
///
void setVideoMode(const VideoMode videoMode);
/// ///
/// Captures a single snapshot of the display and writes the data to the given image. The /// Captures a single snapshot of the display and writes the data to the given image. The
/// provided image should have the same dimensions as the configured values (_width and /// provided image should have the same dimensions as the configured values (_width and
@ -58,8 +65,7 @@ private:
int _vc_flags; int _vc_flags;
/// With of the captured snapshot [pixels] /// With of the captured snapshot [pixels]
unsigned _width; const unsigned _width;
/// Height of the captured snapshot [pixels] /// Height of the captured snapshot [pixels]
unsigned _height; const unsigned _height;
}; };

View File

@ -81,3 +81,8 @@ void DispmanxWrapper::setGrabbingMode(const GrabbingMode mode)
break; break;
} }
} }
void DispmanxWrapper::setVideoMode(const VideoMode mode)
{
_frameGrabber->setVideoMode(mode);
}

View File

@ -255,6 +255,14 @@
"grabMenu" : { "grabMenu" : {
"type" : "boolean", "type" : "boolean",
"required" : true "required" : true
},
"grabScreensaver" : {
"type" : "boolean",
"required" : false
},
"enable3DDetection" : {
"type" : "boolean",
"required" : false
} }
}, },
"additionalProperties" : false "additionalProperties" : false

View File

@ -1,52 +1,50 @@
// Qt includes // Qt includes
#include <QUrl> #include <QUrl>
#include <QRegExp>
#include <QStringRef>
#include <xbmcvideochecker/XBMCVideoChecker.h> #include <xbmcvideochecker/XBMCVideoChecker.h>
XBMCVideoChecker::XBMCVideoChecker(const std::string & address, uint16_t port, uint64_t interval_ms, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu) : // Request player example:
// {"id":666,"jsonrpc":"2.0","method":"Player.GetActivePlayers"}
// {"id":666,"jsonrpc":"2.0","result":[{"playerid":1,"type":"video"}]}
// Request playing item example:
// {"id":667,"jsonrpc":"2.0","method":"Player.GetItem","params":{"playerid":1,"properties":["file"]}}
// {"id":667,"jsonrpc":"2.0","result":{"item":{"file":"smb://xbmc:xbmc@192.168.53.12/video/Movies/Avatar (2009)/Avatar.mkv","label":"Avatar","type":"unknown"}}}
// Request if screensaver is on
// {"id":668,"jsonrpc":"2.0","method":"XBMC.GetInfoBooleans","params":{"booleans":["System.ScreenSaverActive"]}}
// {"id":668,"jsonrpc":"2.0","result":{"System.ScreenSaverActive":false}}
XBMCVideoChecker::XBMCVideoChecker(const std::string & address, uint16_t port, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu, bool grabScreensaver, bool enable3DDetection) :
QObject(), QObject(),
_address(QString::fromStdString(address)), _address(QString::fromStdString(address)),
_port(port), _port(port),
_request(R"({"jsonrpc":"2.0","method":"Player.GetActivePlayers","id":666})"), _activePlayerRequest(R"({"id":666,"jsonrpc":"2.0","method":"Player.GetActivePlayers"})"),
_timer(), _currentPlayingItemRequest(R"({"id":667,"jsonrpc":"2.0","method":"Player.GetItem","params":{"playerid":%1,"properties":["file"]}})"),
_checkScreensaverRequest(R"({"id":668,"jsonrpc":"2.0","method":"XBMC.GetInfoBooleans","params":{"booleans":["System.ScreenSaverActive"]}})"),
_socket(), _socket(),
_grabVideo(grabVideo), _grabVideo(grabVideo),
_grabPhoto(grabPhoto), _grabPhoto(grabPhoto),
_grabAudio(grabAudio), _grabAudio(grabAudio),
_grabMenu(grabMenu), _grabMenu(grabMenu),
_previousMode(GRABBINGMODE_INVALID) _grabScreensaver(grabScreensaver),
_enable3DDetection(enable3DDetection),
_previousScreensaverMode(false),
_previousGrabbingMode(GRABBINGMODE_INVALID),
_previousVideoMode(VIDEO_2D)
{ {
// setup timer
_timer.setSingleShot(false);
_timer.setInterval(interval_ms);
connect(&_timer, SIGNAL(timeout()), this, SLOT(sendRequest()));
// setup socket // setup socket
connect(&_socket, SIGNAL(readyRead()), this, SLOT(receiveReply())); connect(&_socket, SIGNAL(readyRead()), this, SLOT(receiveReply()));
connect(&_socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
connect(&_socket, SIGNAL(connected()), this, SLOT(connected()));
connect(&_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(connectionError(QAbstractSocket::SocketError)));
} }
void XBMCVideoChecker::start() void XBMCVideoChecker::start()
{ {
_timer.start(); disconnected();
}
void XBMCVideoChecker::sendRequest()
{
switch (_socket.state())
{
case QTcpSocket::UnconnectedState:
// not connected. try to connect
std::cout << "Connecting to " << _address.toStdString() << ":" << _port << " to check XBMC player status" << std::endl;
_socket.connectToHost(_address, _port);
break;
case QTcpSocket::ConnectedState:
// write the request on the socket
_socket.write(_request);
break;
default:
// whatever. let's check again at the next timer tick
break;
}
} }
void XBMCVideoChecker::receiveReply() void XBMCVideoChecker::receiveReply()
@ -54,62 +52,195 @@ void XBMCVideoChecker::receiveReply()
// expect that the reply is received as a single message. Probably oke considering the size of the expected reply // expect that the reply is received as a single message. Probably oke considering the size of the expected reply
QString reply(_socket.readAll()); QString reply(_socket.readAll());
// check if the resply is a reply to one of my requests std::cout << "Message from XBMC: " << reply.toStdString() << std::endl;
if (!reply.contains("\"id\":666"))
if (reply.contains("\"method\":\"Player.OnPlay\""))
{ {
// probably not. Leave this mreply as is and don't act on it // send a request for the current player state
_socket.write(_activePlayerRequest.toUtf8());
return; return;
} }
else if (reply.contains("\"method\":\"Player.OnStop\""))
{
// the player has stopped
setGrabbingMode(_grabMenu ? GRABBINGMODE_MENU : GRABBINGMODE_OFF);
setVideoMode(VIDEO_2D);
}
else if (reply.contains("\"method\":\"GUI.OnScreensaverActivated\""))
{
setScreensaverMode(!_grabScreensaver);
}
else if (reply.contains("\"method\":\"GUI.OnScreensaverDeactivated\""))
{
setScreensaverMode(false);
}
else if (reply.contains("\"id\":666"))
{
// Result of Player.GetActivePlayers
GrabbingMode newMode = GRABBINGMODE_INVALID; // always start a new video in 2D mode
if (reply.contains("video")) emit videoMode(VIDEO_2D);
{
// video is playing
newMode = _grabVideo ? GRABBINGMODE_VIDEO : GRABBINGMODE_OFF;
}
else if (reply.contains("picture"))
{
// picture viewer is playing
newMode = _grabPhoto ? GRABBINGMODE_PHOTO : GRABBINGMODE_OFF;
}
else if (reply.contains("audio"))
{
// audio is playing
newMode = _grabAudio ? GRABBINGMODE_AUDIO : GRABBINGMODE_OFF;
}
else
{
// Nothing is playing.
newMode = _grabMenu ? GRABBINGMODE_MENU : GRABBINGMODE_OFF;
}
// emit new state if applicable if (reply.contains("video"))
if (newMode != _previousMode && newMode != GRABBINGMODE_INVALID)
{
switch (newMode)
{ {
case GRABBINGMODE_VIDEO: // video is playing
std::cout << "XBMC checker: switching to VIDEO mode" << std::endl; setGrabbingMode(_grabVideo ? GRABBINGMODE_VIDEO : GRABBINGMODE_OFF);
break;
case GRABBINGMODE_PHOTO:
std::cout << "XBMC checker: switching to PHOTO mode" << std::endl;
break;
case GRABBINGMODE_AUDIO:
std::cout << "XBMC checker: switching to AUDIO mode" << std::endl;
break;
case GRABBINGMODE_MENU:
std::cout << "XBMC checker: switching to MENU mode" << std::endl;
break;
case GRABBINGMODE_OFF:
std::cout << "XBMC checker: switching to OFF mode" << std::endl;
break;
case GRABBINGMODE_INVALID:
std::cout << "XBMC checker: switching to INVALID mode" << std::endl;
break;
}
emit grabbingMode(newMode); // we need to get the filename
_previousMode = newMode; // first retrieve the playerid
QString key = "\"playerid\":";
QRegExp regex(key + "(\\d+)");
int pos = regex.indexIn(reply);
if (pos > 0)
{
// now request info of the playing item
QStringRef idText(&reply, pos + key.length(), regex.matchedLength() - key.length());
_socket.write(_currentPlayingItemRequest.arg(idText.toString()).toUtf8());
}
}
else if (reply.contains("picture"))
{
// picture viewer is playing
setGrabbingMode(_grabPhoto ? GRABBINGMODE_PHOTO : GRABBINGMODE_OFF);
}
else if (reply.contains("audio"))
{
// audio is playing
setGrabbingMode(_grabAudio ? GRABBINGMODE_AUDIO : GRABBINGMODE_OFF);
}
else
{
// Nothing is playing.
setGrabbingMode(_grabMenu ? GRABBINGMODE_MENU : GRABBINGMODE_OFF);
}
}
else if (reply.contains("\"id\":667"))
{
// result of Player.GetItem
// TODO: what if the filename contains a '"'. In Json this should have been escaped
QRegExp regex("\"file\":\"((?!\").)*\"");
int pos = regex.indexIn(reply);
if (pos > 0)
{
QStringRef filename = QStringRef(&reply, pos+8, regex.matchedLength()-9);
if (filename.contains("3DSBS", Qt::CaseInsensitive) || filename.contains("HSBS", Qt::CaseInsensitive))
{
setVideoMode(VIDEO_3DSBS);
}
else if (filename.contains("3DTAB", Qt::CaseInsensitive) || filename.contains("HTAB", Qt::CaseInsensitive))
{
setVideoMode(VIDEO_3DTAB);
}
else
{
setVideoMode(VIDEO_2D);
}
}
}
else if (reply.contains("\"id\":668"))
{
// result of System.ScreenSaverActive
bool active = reply.contains("\"System.ScreenSaverActive\":true");
setScreensaverMode(!_grabScreensaver && active);
} }
} }
void XBMCVideoChecker::connected()
{
std::cout << "XBMC Connected" << std::endl;
// send a request for the current player state
_socket.write(_activePlayerRequest.toUtf8());
_socket.write(_checkScreensaverRequest.toUtf8());
}
void XBMCVideoChecker::disconnected()
{
std::cout << "XBMC Disconnected" << std::endl;
// try to connect
_socket.connectToHost(_address, _port);
}
void XBMCVideoChecker::connectionError(QAbstractSocket::SocketError)
{
std::cout << "XBMC Connection error" << std::endl;
// try to connect again in 1 second
QTimer::singleShot(1000, this, SLOT(disconnected()));
}
void XBMCVideoChecker::setGrabbingMode(GrabbingMode newGrabbingMode)
{
if (newGrabbingMode == _previousGrabbingMode)
{
// no change
return;
}
switch (newGrabbingMode)
{
case GRABBINGMODE_VIDEO:
std::cout << "XBMC checker: switching to VIDEO mode" << std::endl;
break;
case GRABBINGMODE_PHOTO:
std::cout << "XBMC checker: switching to PHOTO mode" << std::endl;
break;
case GRABBINGMODE_AUDIO:
std::cout << "XBMC checker: switching to AUDIO mode" << std::endl;
break;
case GRABBINGMODE_MENU:
std::cout << "XBMC checker: switching to MENU mode" << std::endl;
break;
case GRABBINGMODE_OFF:
std::cout << "XBMC checker: switching to OFF mode" << std::endl;
break;
case GRABBINGMODE_INVALID:
std::cout << "XBMC checker: switching to INVALID mode" << std::endl;
break;
}
// only emit the new state when we want to grab in screensaver mode or when the screensaver is deactivated
if (!_previousScreensaverMode)
{
emit grabbingMode(newGrabbingMode);
}
_previousGrabbingMode = newGrabbingMode;
}
void XBMCVideoChecker::setScreensaverMode(bool isOnScreensaver)
{
if (isOnScreensaver == _previousScreensaverMode)
{
// no change
return;
}
emit grabbingMode(isOnScreensaver ? GRABBINGMODE_OFF : _previousGrabbingMode);
_previousScreensaverMode = isOnScreensaver;
}
void XBMCVideoChecker::setVideoMode(VideoMode newVideoMode)
{
if (newVideoMode == _previousVideoMode)
{
// no change
return;
}
switch (newVideoMode)
{
case VIDEO_2D:
std::cout << "XBMC checker: switching to 2D mode" << std::endl;
break;
case VIDEO_3DSBS:
std::cout << "XBMC checker: switching to 3D SBS mode" << std::endl;
break;
case VIDEO_3DTAB:
std::cout << "XBMC checker: switching to 3D TAB mode" << std::endl;
break;
}
emit videoMode(newVideoMode);
_previousVideoMode = newVideoMode;
}

View File

@ -123,11 +123,12 @@ int main(int argc, char** argv)
xbmcVideoChecker = new XBMCVideoChecker( xbmcVideoChecker = new XBMCVideoChecker(
videoCheckerConfig["xbmcAddress"].asString(), videoCheckerConfig["xbmcAddress"].asString(),
videoCheckerConfig["xbmcTcpPort"].asUInt(), videoCheckerConfig["xbmcTcpPort"].asUInt(),
1000,
videoCheckerConfig["grabVideo"].asBool(), videoCheckerConfig["grabVideo"].asBool(),
videoCheckerConfig["grabPictures"].asBool(), videoCheckerConfig["grabPictures"].asBool(),
videoCheckerConfig["grabAudio"].asBool(), videoCheckerConfig["grabAudio"].asBool(),
videoCheckerConfig["grabMenu"].asBool()); videoCheckerConfig["grabMenu"].asBool(),
videoCheckerConfig.get("grabScreensaver", true).asBool(),
videoCheckerConfig.get("enable3DDetection", true).asBool());
xbmcVideoChecker->start(); xbmcVideoChecker->start();
std::cout << "XBMC video checker created and started" << std::endl; std::cout << "XBMC video checker created and started" << std::endl;
@ -148,6 +149,7 @@ int main(int argc, char** argv)
if (xbmcVideoChecker != nullptr) if (xbmcVideoChecker != nullptr)
{ {
QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), dispmanx, SLOT(setGrabbingMode(GrabbingMode))); QObject::connect(xbmcVideoChecker, SIGNAL(grabbingMode(GrabbingMode)), dispmanx, SLOT(setGrabbingMode(GrabbingMode)));
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), dispmanx, SLOT(setVideoMode(VideoMode)));
} }
dispmanx->start(); dispmanx->start();

View File

@ -12,8 +12,8 @@ public:
// empty // empty
} }
int write(const std::vector<ColorRgb> &ledValues) {} int write(const std::vector<ColorRgb> &ledValues) { return 0; }
int switchOff() {}; int switchOff() { return 0; }
void writeTestSequence() void writeTestSequence()
{ {