Merged branch master into master

This commit is contained in:
brindosch 2016-07-06 21:58:19 +02:00
commit 0feb1d7b58
62 changed files with 2211 additions and 1459 deletions

View File

@ -1,7 +1,16 @@
notifications:
email: false
language: cpp
sudo: required
dist: trusty
matrix:
include:
- os: linux
dist: trusty
sudo: required
# - os: osx
# osx_image: xcode7.3
before_install:
- sudo apt-get -qq update
- sudo apt-get install -qq -y qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev
script: mkdir build && cd build && cmake -DPLATFORM=x86 -DCMAKE_BUILD_TYPE=Release .. && make -j 2
- chmod +x ./.travis/travis_install.sh
- ./.travis/travis_install.sh
script:
- chmod +x ./.travis/travis_build.sh
- ./.travis/travis_build.sh

11
.travis/travis_build.sh Normal file
View File

@ -0,0 +1,11 @@
#!/bin/bash
# compile hyperion on osx
if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
cmake . -DCMAKE_PREFIX_PATH=/usr/local/Cellar/qt5/5.6.1-1
mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_TESTS=ON -Wno-dev .. && make -j$(nproc) package
fi
# compile hyperion on linux
if [[ $TRAVIS_OS_NAME == 'linux' ]]; then
mkdir build && cd build && cmake -DPLATFORM=x86 -DCMAKE_BUILD_TYPE=Release -DENABLE_AMLOGIC=ON -DENABLE_TESTS=ON -DENABLE_SPIDEV=ON -Wno-dev .. && make -j$(nproc) package
fi

16
.travis/travis_install.sh Normal file
View File

@ -0,0 +1,16 @@
#!/bin/bash
# install osx deps for hyperion compile
if [[ $TRAVIS_OS_NAME == 'osx' ]]; then
echo "Install OSX deps"
brew update
brew install qt5
brew install libusb
brew install cmake
fi
# install linux deps for hyperion compile
if [[ $TRAVIS_OS_NAME == 'linux' ]]; then
echo "Install linux deps"
sudo apt-get -qq update ; sudo apt-get install -qq -y qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev
fi

View File

@ -8,6 +8,10 @@ IF ( POLICY CMP0026 )
CMAKE_POLICY( SET CMP0026 OLD )
ENDIF()
IF ( POLICY CMP0043 )
CMAKE_POLICY( SET CMP0043 OLD )
ENDIF()
SET ( HYPERION_VERSION_STABLE OFF )
SET ( HYPERION_VERSION_MAJOR 2 )
SET ( HYPERION_VERSION_MINOR 0 )
@ -21,11 +25,12 @@ SET ( DEFAULT_X11 OFF )
SET ( DEFAULT_SPIDEV OFF )
SET ( DEFAULT_WS2812BPWM OFF )
SET ( DEFAULT_WS281XPWM OFF )
SET ( DEFAULT_ZEROCONF ON )
SET ( DEFAULT_V4L2 ON )
SET ( DEFAULT_USE_SHARED_AVAHI_LIBS OFF )
if (APPLE)
SET ( DEFAULT_OSX ON )
SET ( DEFAULT_OSX ON )
SET ( DEFAULT_V4l2 OFF )
else ()
if ( "${PLATFORM}" STREQUAL "rpi" )
SET ( DEFAULT_DISPMANX ON )
@ -48,8 +53,6 @@ else ()
endif ()
# set the build options
SET(ENABLE_ZEROCONF ON )
option(ENABLE_AMLOGIC "Enable the AMLOGIC video grabber" ${DEFAULT_AMLOGIC} )
message(STATUS "ENABLE_AMLOGIC = " ${ENABLE_AMLOGIC})
@ -68,7 +71,7 @@ message(STATUS "ENABLE_SPIDEV = " ${ENABLE_SPIDEV})
option(ENABLE_TINKERFORGE "Enable the TINKERFORGE device" ON)
message(STATUS "ENABLE_TINKERFORGE = " ${ENABLE_TINKERFORGE})
option(ENABLE_V4L2 "Enable the V4L2 grabber" ON)
option(ENABLE_V4L2 "Enable the V4L2 grabber" ${DEFAULT_V4L2})
message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2})
option(ENABLE_WS2812BPWM "Enable the WS2812b-PWM device" ${DEFAULT_WS2812BPWM} )

View File

@ -27,9 +27,6 @@
// Define to enable the osx grabber
#cmakedefine ENABLE_OSX
// Define to enable the bonjour/zeroconf publishing
#cmakedefine ENABLE_ZEROCONF
// Define to enable profiler for development purpose
#cmakedefine ENABLE_PROFILER

View File

@ -0,0 +1,12 @@
[Unit]
Description=Hyperion ambient light systemd service for OpenELEC/LibreELEC/RasPlex
After=graphical.target
[Service]
ExecStart=/bin/sh -c "exec sh /storage/hyperion/bin/hyperiond.sh /storage/.config/hyperion/hyperion.config.json"
TimeoutStopSec=2
Restart=always
RestartSec=2
[Install]
WantedBy=default.target

View File

@ -1,15 +1,15 @@
[Unit]
Description=Hyperion Systemd service
Description=Hyperion ambient light systemd service
[Service]
Type=simple
User=root
Group=root
UMask=007
User=hyperion
Group=hyperion
ExecStart=/usr/bin/hyperiond /etc/hyperion/hyperion.config.json
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
TimeoutStopSec=10
TimeoutStopSec=2
Restart=always
RestartSec=2
[Install]
WantedBy=multi-user.target

View File

@ -20,7 +20,7 @@ install_file()
echo "--- hyperion ambilight postinstall ---"
echo "- install configuration template"
mkdir -p /etc/hyperion
install_file /usr/share/hyperion/config/hyperion.config.json.example /etc/hyperion/hyperion.config.json
install_file /usr/share/hyperion/config/hyperion.config.json.default /etc/hyperion/hyperion.config.json
HYPERION_RUNNING=false

View File

@ -4,6 +4,12 @@
{
/// set log level: silent warn verbose debug
"logger" :
{
"level" : "warn"
},
/// Device configuration contains the following fields:
/// * 'name' : The user friendly name of the device (only used for display purposes)
/// * 'type' : The type of the device or leds (known types for now are

View File

@ -1,4 +1,9 @@
{
"logger" :
{
"level" : "warn"
},
"device" :
{
"name" : "DefaultHyperionConfig",

File diff suppressed because it is too large Load Diff

View File

@ -9,6 +9,7 @@
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <utils/Logger.h>
class BoblightClientConnection;
@ -32,6 +33,24 @@ public:
/// @return the port number on which this TCP listens for incoming connections
///
uint16_t getPort() const;
/// @return true if server is active (bind to a port)
///
bool active() { return _isActive; };
public slots:
///
/// bind server to network
///
void start();
///
/// close server
///
void stop();
signals:
void statusChanged(bool isActive);
private slots:
///
@ -57,4 +76,12 @@ private:
/// hyperion priority
const int _priority;
/// Logger instance
Logger * _log;
/// state of connection
bool _isActive;
uint16_t _port;
};

4
include/grabber/AmlogicGrabber.h Normal file → Executable file
View File

@ -2,7 +2,7 @@
// STL includes
#include <cstdint>
#include <utils/Logger.h>
// Utils includes
#include <utils/Image.h>
#include <utils/ColorBgr.h>
@ -55,4 +55,6 @@ private:
/** The snapshot/capture device of the amlogic video chip */
int _amlogicCaptureDev;
Logger * _log;
};

4
include/grabber/X11Grabber.h Normal file → Executable file
View File

@ -3,7 +3,7 @@
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/ImageResampler.h>
#include <utils/Logger.h>
// X11 includes
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
@ -64,4 +64,6 @@ private:
void setupResources();
int updateScreenDimensions();
Logger * _log;
};

View File

@ -4,7 +4,7 @@
#include <string>
// Utils includes
#include <utils/RgbChannelCorrection.h>
#include <utils/RgbChannelAdjustment.h>
class ColorCorrection
{
@ -14,5 +14,5 @@ public:
std::string _id;
/// The RGB correction
RgbChannelCorrection _rgbCorrection;
RgbChannelAdjustment _rgbCorrection;
};

View File

@ -9,6 +9,8 @@
// hyperion-utils includes
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/Logger.h>
// Hyperion includes
#include <hyperion/LedString.h>
@ -33,7 +35,6 @@ class RgbChannelCorrection;
class RgbChannelAdjustment;
class MultiColorTransform;
class MultiColorCorrection;
class MultiColorTemperature;
class MultiColorAdjustment;
///
/// The main class of Hyperion. This gives other 'users' access to the attached LedDevice through
@ -138,12 +139,6 @@ public slots:
///
const std::vector<std::string> & getTransformIds() const;
///
/// Returns the list with unique correction identifiers
/// @return The list with correction identifiers
///
const std::vector<std::string> & getCorrectionIds() const;
///
/// Returns the list with unique correction identifiers
/// @return The list with correction identifiers
@ -162,12 +157,6 @@ public slots:
///
ColorTransform * getTransform(const std::string& id);
///
/// Returns the ColorCorrection with the given identifier
/// @return The correction with the given identifier (or nullptr if the identifier does not exist)
///
ColorCorrection * getCorrection(const std::string& id);
///
/// Returns the ColorCorrection with the given identifier
/// @return The correction with the given identifier (or nullptr if the identifier does not exist)
@ -238,7 +227,6 @@ public:
static LedString createLedString(const Json::Value & ledsConfig, const ColorOrder deviceOrder);
static MultiColorTransform * createLedColorsTransform(const unsigned ledCnt, const Json::Value & colorTransformConfig);
static MultiColorCorrection * createLedColorsCorrection(const unsigned ledCnt, const Json::Value & colorCorrectionConfig);
static MultiColorCorrection * createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorTemperatureConfig);
static MultiColorAdjustment * createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorAdjustmentConfig);
static ColorTransform * createColorTransform(const Json::Value & transformConfig);
@ -247,7 +235,7 @@ public:
static HsvTransform * createHsvTransform(const Json::Value & hsvConfig);
static HslTransform * createHslTransform(const Json::Value & hslConfig);
static RgbChannelTransform * createRgbChannelTransform(const Json::Value& colorConfig);
static RgbChannelCorrection * createRgbChannelCorrection(const Json::Value& colorConfig);
static RgbChannelAdjustment * createRgbChannelCorrection(const Json::Value& colorConfig);
static RgbChannelAdjustment * createRgbChannelAdjustment(const Json::Value& colorConfig, const RgbChannel color);
static LedDevice * createColorSmoothing(const Json::Value & smoothingConfig, LedDevice * ledDevice);
@ -287,9 +275,6 @@ private:
/// The transformation from raw colors to led colors
MultiColorTransform * _raw2ledTransform;
/// The correction from raw colors to led colors
MultiColorCorrection * _raw2ledCorrection;
/// The temperature from raw colors to led colors
MultiColorCorrection * _raw2ledTemperature;
@ -313,4 +298,13 @@ private:
/// The timer for handling priority channel timeouts
QTimer _timer;
/// buffer for leds
std::vector<ColorRgb> _ledBuffer;
/// Logger instance
Logger * _log;
/// count of hardware leds
unsigned _hwLedCount;
};

View File

@ -27,12 +27,14 @@ class Logger
public:
enum LogLevel { UNSET=0,DEBUG=1, INFO=2,WARNING=3,ERROR=4,OFF=5 };
static Logger* getInstance(std::string name="", LogLevel minLevel=Logger::INFO);
static void deleteInstance(std::string name="");
static void setLogLevel(LogLevel level,std::string name="");
static Logger* getInstance(std::string name="", LogLevel minLevel=Logger::INFO);
static void deleteInstance(std::string name="");
static void setLogLevel(LogLevel level,std::string name="");
static LogLevel getLogLevel(std::string name="");
void Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...);
void setMinLevel(LogLevel level) { _minLevel = level; };
void Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...);
void setMinLevel(LogLevel level) { _minLevel = level; };
LogLevel getMinLevel() { return _minLevel; };
protected:
Logger( std::string name="", LogLevel minLevel=INFO);

View File

@ -1,9 +1,10 @@
#include "utils/Logger.h"
#include <string>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <map>
#include <utils/Logger.h>
#include <HyperionConfig.h>
#ifndef ENABLE_PROFILER
#error "Profiler is not for productive code, enable it via cmake or remove header include"

View File

@ -15,29 +15,34 @@ public:
/// @param adjustR
/// @param adjustG
/// @param adjustB
RgbChannelAdjustment(int adjustR, int adjustG, int adjustB);
RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB);
/// Destructor
~RgbChannelAdjustment();
/// setAdjustment RGB
/// @param adjustR
/// @param adjustG
/// @param adjustB
void setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB);
/// @return The current adjustR value
uint8_t getadjustmentR() const;
uint8_t getAdjustmentR() const;
/// @param threshold New adjustR value
void setadjustmentR(uint8_t adjustR);
void setAdjustmentR(uint8_t adjustR);
/// @return The current adjustG value
uint8_t getadjustmentG() const;
uint8_t getAdjustmentG() const;
/// @param gamma New adjustG value
void setadjustmentG(uint8_t adjustG);
void setAdjustmentG(uint8_t adjustG);
/// @return The current adjustB value
uint8_t getadjustmentB() const;
uint8_t getAdjustmentB() const;
/// @param blacklevel New adjustB value
void setadjustmentB(uint8_t adjustB);
void setAdjustmentB(uint8_t adjustB);
/// Transform the given array value
/// @param input The input color bytes
@ -48,19 +53,15 @@ public:
private:
/// color channels
enum ColorChannel { RED=0,GREEN=1, BLUE=2 };
/// (re)-initilize the color mapping
void initializeMapping();
private:
/// The adjustment of R channel
int _adjustR;
/// The adjustment of G channel
int _adjustG;
/// The adjustment of B channel
int _adjustB;
/// The adjustment of RGB channel
uint8_t _adjust[3];
/// The mapping from input color to output color
int _mappingR[256];
int _mappingG[256];
int _mappingB[256];
uint8_t _mapping[3][256];
};

View File

@ -1,66 +0,0 @@
#pragma once
// STL includes
#include <cstdint>
/// Correction for a single color byte value
/// All configuration values are unsigned int and assume the color value to be between 0 and 255
class RgbChannelCorrection
{
public:
/// Default constructor
RgbChannelCorrection();
/// Constructor
/// @param correctionR
/// @param correctionG
/// @param correctionB
RgbChannelCorrection(int correctionR, int correctionG, int correctionB);
/// Destructor
~RgbChannelCorrection();
/// @return The current correctionR value
uint8_t getcorrectionR() const;
/// @param threshold New correctionR value
void setcorrectionR(uint8_t correctionR);
/// @return The current correctionG value
uint8_t getcorrectionG() const;
/// @param gamma New correctionG value
void setcorrectionG(uint8_t correctionG);
/// @return The current correctionB value
uint8_t getcorrectionB() const;
/// @param blacklevel New correctionB value
void setcorrectionB(uint8_t correctionB);
/// Transform the given array value
/// @param input The input color bytes
/// @return The corrected byte value
uint8_t correctionR(uint8_t inputR) const;
uint8_t correctionG(uint8_t inputG) const;
uint8_t correctionB(uint8_t inputB) const;
private:
/// (re)-initilize the color mapping
void initializeMapping();
private:
/// The correction of R channel
int _correctionR;
/// The correction of G channel
int _correctionG;
/// The correction of B channel
int _correctionB;
/// The mapping from input color to output color
int _mappingR[256];
int _mappingG[256];
int _mappingB[256];
};

View File

@ -28,6 +28,13 @@ public:
/// Destructor
~RgbChannelTransform();
/// setAdjustment RGB
/// @param threshold The minimum threshold
/// @param gamma The gamma of the gamma-curve correction
/// @param blacklevel The minimum value for the RGB-Channel
/// @param whitelevel The maximum value for the RGB-Channel
void setTransform(double threshold, double gamma, double blacklevel, double whitelevel);
/// @return The current threshold value
double getThreshold() const;

View File

@ -22,15 +22,16 @@
// project includes
#include "BoblightClientConnection.h"
BoblightClientConnection::BoblightClientConnection(QTcpSocket *socket, const int priority, Hyperion * hyperion) :
QObject(),
_locale(QLocale::C),
_socket(socket),
_imageProcessor(ImageProcessorFactory::getInstance().newImageProcessor()),
_hyperion(hyperion),
_receiveBuffer(),
_priority(priority),
_ledColors(hyperion->getLedCount(), ColorRgb::BLACK)
BoblightClientConnection::BoblightClientConnection(QTcpSocket *socket, const int priority, Hyperion * hyperion)
: QObject()
, _locale(QLocale::C)
, _socket(socket)
, _imageProcessor(ImageProcessorFactory::getInstance().newImageProcessor())
, _hyperion(hyperion)
, _receiveBuffer()
, _priority(priority)
, _ledColors(hyperion->getLedCount(), ColorRgb::BLACK)
, _log(Logger::getInstance("BOBLIGHT"))
{
// initalize the locale. Start with the default C-locale
_locale.setNumberOptions(QLocale::OmitGroupSeparator | QLocale::RejectGroupSeparator);
@ -70,7 +71,7 @@ void BoblightClientConnection::readData()
// drop messages if the buffer is too full
if (_receiveBuffer.size() > 100*1024)
{
std::cout << "BOBLIGHT INFO: server drops messages (buffer full)" << std::endl;
Debug(_log, "server drops messages (buffer full)");
_receiveBuffer.clear();
}
@ -208,7 +209,7 @@ void BoblightClientConnection::handleMessage(const QString & message)
}
}
std::cout << "BOBLIGHT INFO: unknown boblight message: " << message.toStdString() << std::endl;
Debug(_log, "unknown boblight message: %s", message.toStdString().c_str());
}
void BoblightClientConnection::sendMessage(const std::string & message)

View File

@ -10,6 +10,7 @@
// Hyperion includes
#include <hyperion/Hyperion.h>
#include <utils/Logger.h>
class ImageProcessor;
@ -100,4 +101,7 @@ private:
/// The latest led color data
std::vector<ColorRgb> _ledColors;
/// logger instance
Logger * _log;
};

View File

@ -5,29 +5,53 @@
#include <boblightserver/BoblightServer.h>
#include "BoblightClientConnection.h"
BoblightServer::BoblightServer(const int priority,uint16_t port) :
QObject(),
_hyperion(Hyperion::getInstance()),
_server(),
_openConnections(),
_priority(priority)
BoblightServer::BoblightServer(const int priority, uint16_t port)
: QObject()
, _hyperion(Hyperion::getInstance())
, _server()
, _openConnections()
, _priority(priority)
, _log(Logger::getInstance("BOBLIGHT"))
, _isActive(false)
, _port(port)
{
if (!_server.listen(QHostAddress::Any, port))
{
throw std::runtime_error("BOBLIGHT ERROR: server could not bind to port");
}
// Set trigger for incoming connections
connect(&_server, SIGNAL(newConnection()), this, SLOT(newConnection()));
}
BoblightServer::~BoblightServer()
{
stop();
}
void BoblightServer::start()
{
if ( active() )
return;
if (!_server.listen(QHostAddress::Any, _port))
{
throw std::runtime_error("BOBLIGHT ERROR: server could not bind to port");
}
Info(_log, "Boblight server started on port %d", _port);
_isActive = true;
emit statusChanged(_isActive);
}
void BoblightServer::stop()
{
if ( ! active() )
return;
foreach (BoblightClientConnection * connection, _openConnections) {
delete connection;
}
_isActive = false;
emit statusChanged(_isActive);
}
uint16_t BoblightServer::getPort() const
{
return _server.serverPort();
@ -39,7 +63,7 @@ void BoblightServer::newConnection()
if (socket != nullptr)
{
std::cout << "BOBLIGHT INFO: new connection" << std::endl;
Info(_log, "new connection");
BoblightClientConnection * connection = new BoblightClientConnection(socket, _priority, _hyperion);
_openConnections.insert(connection);
@ -50,7 +74,7 @@ void BoblightServer::newConnection()
void BoblightServer::closedConnection(BoblightClientConnection *connection)
{
std::cout << "BOBLIGHT INFO: connection closed" << std::endl;
Debug(_log, "connection closed");
_openConnections.remove(connection);
// schedule to delete the connection object

18
libsrc/grabber/amlogic/AmlogicGrabber.cpp Normal file → Executable file
View File

@ -3,7 +3,7 @@
#include <algorithm>
#include <cassert>
#include <iostream>
#include <utils/Logger.h>
// Linux includes
#include <errno.h>
#include <fcntl.h>
@ -30,7 +30,7 @@ AmlogicGrabber::AmlogicGrabber(const unsigned width, const unsigned height) :
_height(std::max(160u, height)),
_amlogicCaptureDev(-1)
{
std::cout << "AMLOGICGRABBER INFO: [" << __PRETTY_FUNCTION__ << "] constructed(" << _width << "x" << _height << ")" << std::endl;
Info(_log, "[%s] constructed(%s x %s)",__PRETTY_FUNCTION__,_width,_height);
}
AmlogicGrabber::~AmlogicGrabber()
@ -39,7 +39,7 @@ AmlogicGrabber::~AmlogicGrabber()
{
if (close(_amlogicCaptureDev) == -1)
{
std::cerr << "AMLOGICGRABBER ERROR: [" << __PRETTY_FUNCTION__ << "] Failed to close device (" << errno << ")" << std::endl;
Error(_log, "[%s] Failed to close device (%s)",__PRETTY_FUNCTION__,errno);
}
_amlogicCaptureDev = -1;
}
@ -69,7 +69,7 @@ bool AmlogicGrabber::isVideoPlaying()
int video_fd = open(videoDevice.c_str(), O_RDONLY);
if (video_fd < 0)
{
std::cerr << "AMLOGICGRABBER ERROR: Failed to open video device(" << videoDevice << "): " << strerror(errno) << std::endl;
Error(_log, "Failed to open video device(%s): %s",videoDevice.c_str(),strerror(errno));
return false;
}
@ -77,7 +77,7 @@ bool AmlogicGrabber::isVideoPlaying()
int videoDisabled;
if (ioctl(video_fd, AMSTREAM_IOC_GET_VIDEO_DISABLE, &videoDisabled) == -1)
{
std::cerr << "AMLOGICGRABBER ERROR: Failed to retrieve video state from device: " << strerror(errno) << std::endl;
Error(_log, "Failed to retrieve video state from device: %s",strerror(errno));
close(video_fd);
return false;
}
@ -111,7 +111,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
// If the device is still not open, there is something wrong
if (_amlogicCaptureDev == -1)
{
std::cerr << "AMLOGICGRABBER ERROR:[" << __PRETTY_FUNCTION__ << "] Failed to open the AMLOGIC device (" << errno << "): " << strerror(errno) << std::endl;
Error(_log,"[%s] Failed to open the AMLOGIC device ():",__PRETTY_FUNCTION__,errno,strerror(errno));
return -1;
}
}
@ -121,7 +121,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
ioctl(_amlogicCaptureDev, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, _height) == -1)
{
// Failed to configure frame width
std::cerr << "AMLOGICGRABBER ERROR: [" << __PRETTY_FUNCTION__ << "] Failed to configure capture size (" << errno << "): " << strerror(errno) << std::endl;
Error(_log,"[%s] Failed to configure capture size (%s)",__PRETTY_FUNCTION__,errno,strerror(errno));
close(_amlogicCaptureDev);
_amlogicCaptureDev = -1;
return -1;
@ -134,7 +134,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
const ssize_t bytesRead = pread(_amlogicCaptureDev, image_ptr, bytesToRead, 0);
if (bytesRead == -1)
{
std::cerr << "AMLOGICGRABBER ERROR: [" << __PRETTY_FUNCTION__ << "] Read of device failed (erno=" << errno << "): " << strerror(errno) << std::endl;
Error(_log,"[%s] Read of device failed (erno=%s): %s",__PRETTY_FUNCTION__,errno,strerror(errno));
close(_amlogicCaptureDev);
_amlogicCaptureDev = -1;
return -1;
@ -142,7 +142,7 @@ int AmlogicGrabber::grabFrame(Image<ColorBgr> & image)
else if (bytesToRead != bytesRead)
{
// Read of snapshot failed
std::cerr << "AMLOGICGRABBER ERROR: [" << __PRETTY_FUNCTION__ << "] Capture failed to grab entire image [bytesToRead(" << bytesToRead << ") != bytesRead(" << bytesRead << ")]" << std::endl;
Error(_log,"[%s] Capture failed to grab entire image [bytesToRead(%s) != bytesRead(%s)]",__PRETTY_FUNCTION__,bytesToRead,bytesRead);
close(_amlogicCaptureDev);
_amlogicCaptureDev = -1;
return -1;

14
libsrc/grabber/x11/X11Grabber.cpp Normal file → Executable file
View File

@ -1,6 +1,7 @@
// STL includes
#include <iostream>
#include <cstdint>
#include <utils/Logger.h>
// X11Grabber includes
#include <grabber/X11Grabber.h>
@ -22,7 +23,8 @@ X11Grabber::X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropT
_screenHeight(0),
_croppedWidth(0),
_croppedHeight(0),
_image(0,0)
_image(0,0),
_log(Logger::getInstance("X11GRABBER"))
{
_imageResampler.setHorizontalPixelDecimation(horizontalPixelDecimation);
_imageResampler.setVerticalPixelDecimation(verticalPixelDecimation);
@ -94,11 +96,11 @@ bool X11Grabber::Setup()
_x11Display = XOpenDisplay(NULL);
if (_x11Display == nullptr)
{
std::cerr << "X11GRABBER ERROR: Unable to open display";
Error(_log, "Unable to open display");
if (getenv("DISPLAY")) {
std::cerr << " " << std::string(getenv("DISPLAY")) << std::endl;
Error(_log, "%s",getenv("DISPLAY"));
} else {
std::cerr << ". DISPLAY environment variable not set" << std::endl;
Error(_log, "DISPLAY environment variable not set");
}
return false;
}
@ -151,7 +153,7 @@ Image<ColorRgb> & X11Grabber::grab()
if (_xImage == nullptr)
{
std::cerr << "X11GRABBER ERROR: Grab failed" << std::endl;
Error(_log, "Grab Failed!");
return _image;
}
@ -165,7 +167,7 @@ int X11Grabber::updateScreenDimensions()
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
if (status == 0)
{
std::cerr << "X11GRABBER ERROR: Failed to obtain window attributes" << std::endl;
Error(_log, "Failed to obtain window attributes");
return -1;
}

View File

@ -2,6 +2,7 @@
// STL includes
#include <cassert>
#include <exception>
#include <sstream>
// QT includes
#include <QDateTime>
@ -53,41 +54,29 @@ Hyperion* Hyperion::getInstance()
ColorOrder Hyperion::createColorOrder(const Json::Value &deviceConfig)
{
// deprecated: force BGR when the deprecated flag is present and set to true
if (deviceConfig.get("bgr-output", false).asBool())
{
return ORDER_BGR;
}
std::string order = deviceConfig.get("colorOrder", "rgb").asString();
if (order == "rgb")
{
return ORDER_RGB;
}
else if (order == "bgr")
if (order == "bgr")
{
return ORDER_BGR;
}
else if (order == "rbg")
if (order == "rbg")
{
return ORDER_RBG;
}
else if (order == "brg")
if (order == "brg")
{
return ORDER_BRG;
}
else if (order == "gbr")
if (order == "gbr")
{
return ORDER_GBR;
}
else if (order == "grb")
if (order == "grb")
{
return ORDER_GRB;
}
else
{
std::cout << "HYPERION ERROR: Unknown color order defined (" << order << "). Using RGB." << std::endl;
}
WarningIf( order != "rgb", Logger::getInstance("Core"), "Unknown color order defined (%s). Using RGB.", order.c_str());
return ORDER_RGB;
}
@ -127,7 +116,7 @@ ColorCorrection * Hyperion::createColorCorrection(const Json::Value & correction
{
const std::string id = correctionConfig.get("id", "default").asString();
RgbChannelCorrection * rgbCorrection = createRgbChannelCorrection(correctionConfig["correctionValues"]);
RgbChannelAdjustment * rgbCorrection = createRgbChannelCorrection(correctionConfig["correctionValues"]);
ColorCorrection * correction = new ColorCorrection();
correction->_id = id;
@ -167,6 +156,7 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt,
{
// Create the result, the transforms are added to this
MultiColorTransform * transform = new MultiColorTransform(ledCnt);
Logger * log = Logger::getInstance("Core");
const Json::Value transformConfig = colorConfig.get("transform", Json::nullValue);
if (transformConfig.isNull())
@ -197,18 +187,17 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt,
{
// Special case for indices '*' => all leds
transform->setTransformForLed(colorTransform->_id, 0, ledCnt-1);
std::cout << "HYPERION INFO: ColorTransform '" << colorTransform->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl;
Info(log, "ColorTransform '%s' => [0; %d]", colorTransform->_id.c_str(), ledCnt-1);
continue;
}
if (!overallExp.exactMatch(ledIndicesStr))
{
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl;
Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
continue;
}
std::cout << "HYPERION INFO: ColorTransform '" << colorTransform->_id << "' => [";
std::stringstream ss;
const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0)
@ -231,92 +220,20 @@ MultiColorTransform * Hyperion::createLedColorsTransform(const unsigned ledCnt,
std::cout << index;
}
}
std::cout << "]" << std::endl;
Info(log, "ColorTransform '%s' => [%s]", colorTransform->_id.c_str(), ss.str().c_str());
}
}
return transform;
}
MultiColorCorrection * Hyperion::createLedColorsCorrection(const unsigned ledCnt, const Json::Value & colorConfig)
{
// Create the result, the corrections are added to this
MultiColorCorrection * correction = new MultiColorCorrection(ledCnt);
const Json::Value correctionConfig = colorConfig.get("correction", Json::nullValue);
if (correctionConfig.isNull())
{
// Old style color correction config (just one for all leds)
ColorCorrection * colorCorrection = createColorCorrection(colorConfig);
correction->addCorrection(colorCorrection);
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
}
else if (!correctionConfig.isArray())
{
ColorCorrection * colorCorrection = createColorCorrection(correctionConfig);
correction->addCorrection(colorCorrection);
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
}
else
{
const QRegExp overallExp("([0-9]+(\\-[0-9]+)?)(,[ ]*([0-9]+(\\-[0-9]+)?))*");
for (Json::UInt i = 0; i < correctionConfig.size(); ++i)
{
const Json::Value & config = correctionConfig[i];
ColorCorrection * colorCorrection = createColorCorrection(config);
correction->addCorrection(colorCorrection);
const QString ledIndicesStr = QString(config.get("leds", "").asCString()).trimmed();
if (ledIndicesStr.compare("*") == 0)
{
// Special case for indices '*' => all leds
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl;
continue;
}
if (!overallExp.exactMatch(ledIndicesStr))
{
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl;
continue;
}
std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [";
const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0)
{
std::cout << ", ";
}
if (ledIndexList[i].contains("-"))
{
QStringList ledIndices = ledIndexList[i].split("-");
int startInd = ledIndices[0].toInt();
int endInd = ledIndices[1].toInt();
correction->setCorrectionForLed(colorCorrection->_id, startInd, endInd);
std::cout << startInd << "-" << endInd;
}
else
{
int index = ledIndexList[i].toInt();
correction->setCorrectionForLed(colorCorrection->_id, index, index);
std::cout << index;
}
}
std::cout << "]" << std::endl;
}
}
return correction;
}
MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCnt, const Json::Value & colorConfig)
{
// Create the result, the corrections are added to this
MultiColorCorrection * correction = new MultiColorCorrection(ledCnt);
Logger * log = Logger::getInstance("Core");
const Json::Value correctionConfig = colorConfig.get("temperature", Json::nullValue);
const std::string jsonKey = colorConfig.isMember("temperature") ? "temperature" : "correction";
const Json::Value correctionConfig = colorConfig.get(jsonKey, Json::nullValue);
if (correctionConfig.isNull())
{
// Old style color correction config (just one for all leds)
@ -345,23 +262,22 @@ MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCn
{
// Special case for indices '*' => all leds
correction->setCorrectionForLed(colorCorrection->_id, 0, ledCnt-1);
std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl;
Info(log, "ColorTemperature '%s' => [0; %d]", colorCorrection->_id.c_str(), ledCnt-1);
continue;
}
if (!overallExp.exactMatch(ledIndicesStr))
{
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl;
Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
continue;
}
std::cout << "HYPERION INFO: ColorCorrection '" << colorCorrection->_id << "' => [";
std::stringstream ss;
const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0)
{
std::cout << ", ";
ss << ", ";
}
if (ledIndexList[i].contains("-"))
{
@ -370,25 +286,27 @@ MultiColorCorrection * Hyperion::createLedColorsTemperature(const unsigned ledCn
int endInd = ledIndices[1].toInt();
correction->setCorrectionForLed(colorCorrection->_id, startInd, endInd);
std::cout << startInd << "-" << endInd;
ss << startInd << "-" << endInd;
}
else
{
int index = ledIndexList[i].toInt();
correction->setCorrectionForLed(colorCorrection->_id, index, index);
std::cout << index;
ss << index;
}
}
std::cout << "]" << std::endl;
Info(log, "ColorTemperature '%s' => [%s]", colorCorrection->_id.c_str(), ss.str().c_str());
}
}
return correction;
}
MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt, const Json::Value & colorConfig)
{
// Create the result, the transforms are added to this
MultiColorAdjustment * adjustment = new MultiColorAdjustment(ledCnt);
Logger * log = Logger::getInstance("Core");
const Json::Value adjustmentConfig = colorConfig.get("channelAdjustment", Json::nullValue);
if (adjustmentConfig.isNull())
@ -419,23 +337,22 @@ MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt
{
// Special case for indices '*' => all leds
adjustment->setAdjustmentForLed(colorAdjustment->_id, 0, ledCnt-1);
std::cout << "HYPERION INFO: ColorAdjustment '" << colorAdjustment->_id << "' => [0; "<< ledCnt-1 << "]" << std::endl;
Info(log, "ColorAdjustment '%s' => [0; %d]", colorAdjustment->_id.c_str(), ledCnt-1);
continue;
}
if (!overallExp.exactMatch(ledIndicesStr))
{
std::cerr << "HYPERION ERROR: Given led indices " << i << " not correct format: " << ledIndicesStr.toStdString() << std::endl;
Error(log, "Given led indices %d not correct format: %s", i, ledIndicesStr.toStdString().c_str());
continue;
}
std::cout << "HYPERION INFO: ColorAdjustment '" << colorAdjustment->_id << "' => [";
std::stringstream ss;
const QStringList ledIndexList = ledIndicesStr.split(",");
for (int i=0; i<ledIndexList.size(); ++i) {
if (i > 0)
{
std::cout << ", ";
ss << ", ";
}
if (ledIndexList[i].contains("-"))
{
@ -444,16 +361,16 @@ MultiColorAdjustment * Hyperion::createLedColorsAdjustment(const unsigned ledCnt
int endInd = ledIndices[1].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, startInd, endInd);
std::cout << startInd << "-" << endInd;
ss << startInd << "-" << endInd;
}
else
{
int index = ledIndexList[i].toInt();
adjustment->setAdjustmentForLed(colorAdjustment->_id, index, index);
std::cout << index;
ss << index;
}
}
std::cout << "]" << std::endl;
Info(log, "ColorAdjustment '%s' => [%s]", colorAdjustment->_id.c_str(), ss.str().c_str());
}
}
return adjustment;
@ -487,13 +404,13 @@ RgbChannelTransform* Hyperion::createRgbChannelTransform(const Json::Value& colo
return transform;
}
RgbChannelCorrection* Hyperion::createRgbChannelCorrection(const Json::Value& colorConfig)
RgbChannelAdjustment* Hyperion::createRgbChannelCorrection(const Json::Value& colorConfig)
{
const int varR = colorConfig.get("red", 255).asInt();
const int varG = colorConfig.get("green", 255).asInt();
const int varB = colorConfig.get("blue", 255).asInt();
RgbChannelCorrection* correction = new RgbChannelCorrection(varR, varG, varB);
RgbChannelAdjustment* correction = new RgbChannelAdjustment(varR, varG, varB);
return correction;
}
@ -611,7 +528,7 @@ MessageForwarder * Hyperion::createMessageForwarder(const Json::Value & forwarde
{
for (const Json::Value& addr : forwarderConfig["json"])
{
std::cout << "HYPERION INFO: Json forward to " << addr.asString() << std::endl;
Info(Logger::getInstance("Core"), "Json forward to %s", addr.asString().c_str());
forwarder->addJsonSlave(addr.asString());
}
}
@ -620,7 +537,7 @@ MessageForwarder * Hyperion::createMessageForwarder(const Json::Value & forwarde
{
for (const Json::Value& addr : forwarderConfig["proto"])
{
std::cout << "HYPERION INFO: Proto forward to " << addr.asString() << std::endl;
Info(Logger::getInstance("Core"), "Proto forward to %s", addr.asString().c_str());
forwarder->addProtoSlave(addr.asString());
}
}
@ -638,7 +555,6 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
_ledString(createLedString(jsonConfig["leds"], createColorOrder(jsonConfig["device"]))),
_muxer(_ledString.leds().size()),
_raw2ledTransform(createLedColorsTransform(_ledString.leds().size(), jsonConfig["color"])),
_raw2ledCorrection(createLedColorsCorrection(_ledString.leds().size(), jsonConfig["color"])),
_raw2ledTemperature(createLedColorsTemperature(_ledString.leds().size(), jsonConfig["color"])),
_raw2ledAdjustment(createLedColorsAdjustment(_ledString.leds().size(), jsonConfig["color"])),
_device(LedDeviceFactory::construct(jsonConfig["device"])),
@ -646,16 +562,14 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
_messageForwarder(createMessageForwarder(jsonConfig["forwarder"])),
_jsonConfig(jsonConfig),
_configFile(configFile),
_timer()
_timer(),
_log(Logger::getInstance("Core")),
_hwLedCount(_ledString.leds().size())
{
if (!_raw2ledAdjustment->verifyAdjustments())
{
throw std::runtime_error("HYPERION ERROR: Color adjustment incorrectly set");
}
if (!_raw2ledCorrection->verifyCorrections())
{
throw std::runtime_error("HYPERION ERROR: Color correction incorrectly set");
}
if (!_raw2ledTemperature->verifyCorrections())
{
throw std::runtime_error("HYPERION ERROR: Color temperature incorrectly set");
@ -679,6 +593,11 @@ Hyperion::Hyperion(const Json::Value &jsonConfig, const std::string configFile)
// create the effect engine
_effectEngine = new EffectEngine(this, jsonConfig["effects"]);
unsigned int hwLedCount = jsonConfig["device"].get("ledCount",getLedCount()).asUInt();
_hwLedCount = std::max(hwLedCount, getLedCount());
Debug(_log,"configured leds: %d hw leds: %d", getLedCount(), _hwLedCount);
WarningIf(hwLedCount < getLedCount(), _log, "more leds configured than available. check 'ledCount' in 'device' section");
// initialize the leds
update();
@ -691,25 +610,12 @@ Hyperion::~Hyperion()
clearall();
_device->switchOff();
// delete the effect engine
// delete components on exit of hyperion core
delete _effectEngine;
// Delete the Led-String
delete _device;
// delete the color transform
delete _raw2ledTransform;
// delete the color correction
delete _raw2ledCorrection;
// delete the color temperature correction
delete _raw2ledTemperature;
// delete the color adjustment
delete _raw2ledAdjustment;
// delete the message forwarder
delete _messageForwarder;
}
@ -756,11 +662,6 @@ const std::vector<std::string> & Hyperion::getTransformIds() const
return _raw2ledTransform->getTransformIds();
}
const std::vector<std::string> & Hyperion::getCorrectionIds() const
{
return _raw2ledCorrection->getCorrectionIds();
}
const std::vector<std::string> & Hyperion::getTemperatureIds() const
{
return _raw2ledTemperature->getCorrectionIds();
@ -776,11 +677,6 @@ ColorTransform * Hyperion::getTransform(const std::string& id)
return _raw2ledTransform->getTransform(id);
}
ColorCorrection * Hyperion::getCorrection(const std::string& id)
{
return _raw2ledCorrection->getCorrection(id);
}
ColorCorrection * Hyperion::getTemperature(const std::string& id)
{
return _raw2ledTemperature->getCorrection(id);
@ -884,15 +780,20 @@ void Hyperion::update()
int priority = _muxer.getCurrentPriority();
const PriorityMuxer::InputInfo & priorityInfo = _muxer.getInputInfo(priority);
// copy ledcolors to local buffer
_ledBuffer.reserve(_hwLedCount);
_ledBuffer = priorityInfo.ledColors;
// Apply the correction and the transform to each led and color-channel
// Avoid applying correction, the same task is performed by adjustment
// std::vector<ColorRgb> correctedColors = _raw2ledCorrection->applyCorrection(priorityInfo.ledColors);
std::vector<ColorRgb> transformColors =_raw2ledTransform->applyTransform(priorityInfo.ledColors);
std::vector<ColorRgb> adjustedColors = _raw2ledAdjustment->applyAdjustment(transformColors);
std::vector<ColorRgb> ledColors = _raw2ledTemperature->applyCorrection(adjustedColors);
_raw2ledTransform->applyTransform(_ledBuffer);
_raw2ledAdjustment->applyAdjustment(_ledBuffer);
_raw2ledTemperature->applyCorrection(_ledBuffer);
const std::vector<Led>& leds = _ledString.leds();
int i = 0;
for (ColorRgb& color : ledColors)
for (ColorRgb& color : _ledBuffer)
{
const ColorOrder ledColorOrder = leds.at(i).colorOrder;
// correct the color byte order
@ -926,8 +827,13 @@ void Hyperion::update()
i++;
}
if ( _hwLedCount > _ledBuffer.size() )
{
_ledBuffer.resize(_hwLedCount, ColorRgb::BLACK);
}
// Write the data to the device
_device->write(ledColors);
_device->write(_ledBuffer);
// Start the timeout-timer
if (priorityInfo.timeoutTime_ms == -1)

View File

@ -3,10 +3,11 @@
#include <cassert>
// Hyperion includes
#include <utils/Logger.h>
#include "MultiColorAdjustment.h"
MultiColorAdjustment::MultiColorAdjustment(const unsigned ledCnt) :
_ledAdjustments(ledCnt, nullptr)
MultiColorAdjustment::MultiColorAdjustment(const unsigned ledCnt)
: _ledAdjustments(ledCnt, nullptr)
{
}
@ -40,16 +41,15 @@ void MultiColorAdjustment::setAdjustmentForLed(const std::string& id, const unsi
bool MultiColorAdjustment::verifyAdjustments() const
{
bool allLedsSet = true;
for (unsigned iLed=0; iLed<_ledAdjustments.size(); ++iLed)
{
if (_ledAdjustments[iLed] == nullptr)
{
std::cerr << "HYPERION (C.adjustment) ERROR: No adjustment set for " << iLed << std::endl;
allLedsSet = false;
Warning(Logger::getInstance("ColorAdjust"), "No adjustment set for %d", iLed);
return false;
}
}
return allLedsSet;
return true;
}
const std::vector<std::string> & MultiColorAdjustment::getAdjustmentIds()
@ -72,12 +72,9 @@ ColorAdjustment* MultiColorAdjustment::getAdjustment(const std::string& id)
return nullptr;
}
std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<ColorRgb>& rawColors)
void MultiColorAdjustment::applyAdjustment(std::vector<ColorRgb>& ledColors)
{
// Create a copy, as we will do the rest of the adjustment in place
std::vector<ColorRgb> ledColors(rawColors);
const size_t itCnt = std::min(_ledAdjustments.size(), rawColors.size());
const size_t itCnt = std::min(_ledAdjustments.size(), ledColors.size());
for (size_t i=0; i<itCnt; ++i)
{
ColorAdjustment* adjustment = _ledAdjustments[i];
@ -101,11 +98,11 @@ std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<Co
int BB = adjustment->_rgbBlueAdjustment.adjustmentB(color.blue);
int ledR = RR + GR + BR;
int maxR = (int)adjustment->_rgbRedAdjustment.getadjustmentR();
int maxR = (int)adjustment->_rgbRedAdjustment.getAdjustmentR();
int ledG = RG + GG + BG;
int maxG = (int)adjustment->_rgbGreenAdjustment.getadjustmentG();
int maxG = (int)adjustment->_rgbGreenAdjustment.getAdjustmentG();
int ledB = RB + GB + BB;
int maxB = (int)adjustment->_rgbBlueAdjustment.getadjustmentB();
int maxB = (int)adjustment->_rgbBlueAdjustment.getAdjustmentB();
if (ledR > maxR)
color.red = (uint8_t)maxR;
@ -122,5 +119,4 @@ std::vector<ColorRgb> MultiColorAdjustment::applyAdjustment(const std::vector<Co
else
color.blue = (uint8_t)ledB;
}
return ledColors;
}

View File

@ -48,11 +48,9 @@ public:
///
/// Performs the color adjustment from raw-color to led-color
///
/// @param rawColors The list with raw colors
/// @param ledColors The list with raw colors
///
/// @return The list with led-colors
///
std::vector<ColorRgb> applyAdjustment(const std::vector<ColorRgb>& rawColors);
void applyAdjustment(std::vector<ColorRgb>& ledColors);
private:
/// List with transform ids

View File

@ -3,6 +3,7 @@
#include <cassert>
// Hyperion includes
#include <utils/Logger.h>
#include "MultiColorCorrection.h"
MultiColorCorrection::MultiColorCorrection(const unsigned ledCnt) :
@ -40,16 +41,15 @@ void MultiColorCorrection::setCorrectionForLed(const std::string& id, const unsi
bool MultiColorCorrection::verifyCorrections() const
{
bool allLedsSet = true;
for (unsigned iLed=0; iLed<_ledCorrections.size(); ++iLed)
{
if (_ledCorrections[iLed] == nullptr)
{
std::cerr << "HYPERION (C.correction) ERROR: No correction set for " << iLed << std::endl;
allLedsSet = false;
Warning(Logger::getInstance("ColorCorrect"), "No adjustment set for %d", iLed);
return false;
}
}
return allLedsSet;
return true;
}
const std::vector<std::string> & MultiColorCorrection::getCorrectionIds()
@ -72,12 +72,9 @@ ColorCorrection* MultiColorCorrection::getCorrection(const std::string& id)
return nullptr;
}
std::vector<ColorRgb> MultiColorCorrection::applyCorrection(const std::vector<ColorRgb>& rawColors)
void MultiColorCorrection::applyCorrection(std::vector<ColorRgb>& ledColors)
{
// Create a copy, as we will do the rest of the correction in place
std::vector<ColorRgb> ledColors(rawColors);
const size_t itCnt = std::min(_ledCorrections.size(), rawColors.size());
const size_t itCnt = std::min(_ledCorrections.size(), ledColors.size());
for (size_t i=0; i<itCnt; ++i)
{
ColorCorrection * correction = _ledCorrections[i];
@ -88,9 +85,8 @@ std::vector<ColorRgb> MultiColorCorrection::applyCorrection(const std::vector<Co
}
ColorRgb& color = ledColors[i];
color.red = correction->_rgbCorrection.correctionR(color.red);
color.green = correction->_rgbCorrection.correctionG(color.green);
color.blue = correction->_rgbCorrection.correctionB(color.blue);
color.red = correction->_rgbCorrection.adjustmentR(color.red);
color.green = correction->_rgbCorrection.adjustmentG(color.green);
color.blue = correction->_rgbCorrection.adjustmentB(color.blue);
}
return ledColors;
}

View File

@ -48,11 +48,9 @@ public:
///
/// Performs the color transoformation from raw-color to led-color
///
/// @param rawColors The list with raw colors
/// @param ledColors The list with led colors
///
/// @return The list with led-colors
///
std::vector<ColorRgb> applyCorrection(const std::vector<ColorRgb>& rawColors);
void applyCorrection(std::vector<ColorRgb>& ledColors);
private:
/// List with Correction ids

View File

@ -3,6 +3,7 @@
#include <cassert>
// Hyperion includes
#include <utils/Logger.h>
#include "MultiColorTransform.h"
MultiColorTransform::MultiColorTransform(const unsigned ledCnt) :
@ -40,16 +41,15 @@ void MultiColorTransform::setTransformForLed(const std::string& id, const unsign
bool MultiColorTransform::verifyTransforms() const
{
bool allLedsSet = true;
for (unsigned iLed=0; iLed<_ledTransforms.size(); ++iLed)
{
if (_ledTransforms[iLed] == nullptr)
{
std::cerr << "HYPERION (C.transform) ERROR: No transform set for " << iLed << std::endl;
allLedsSet = false;
Warning(Logger::getInstance("ColorTransform"), "No adjustment set for %d", iLed);
return false;
}
}
return allLedsSet;
return true;
}
const std::vector<std::string> & MultiColorTransform::getTransformIds()
@ -72,12 +72,9 @@ ColorTransform* MultiColorTransform::getTransform(const std::string& id)
return nullptr;
}
std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<ColorRgb>& rawColors)
void MultiColorTransform::applyTransform(std::vector<ColorRgb>& ledColors)
{
// Create a copy, as we will do the rest of the transformation in place
std::vector<ColorRgb> ledColors(rawColors);
const size_t itCnt = std::min(_ledTransforms.size(), rawColors.size());
const size_t itCnt = std::min(_ledTransforms.size(), ledColors.size());
for (size_t i=0; i<itCnt; ++i)
{
ColorTransform* transform = _ledTransforms[i];
@ -94,5 +91,4 @@ std::vector<ColorRgb> MultiColorTransform::applyTransform(const std::vector<Colo
color.green = transform->_rgbGreenTransform.transform(color.green);
color.blue = transform->_rgbBlueTransform.transform(color.blue);
}
return ledColors;
}

View File

@ -48,11 +48,9 @@ public:
///
/// Performs the color transoformation from raw-color to led-color
///
/// @param rawColors The list with raw colors
/// @param ledColors The list with raw colors
///
/// @return The list with led-colors
///
std::vector<ColorRgb> applyTransform(const std::vector<ColorRgb>& rawColors);
void applyTransform(std::vector<ColorRgb>& ledColors);
private:
/// List with transform ids

View File

@ -251,8 +251,6 @@ void JsonClientConnection::handleMessage(const std::string &messageString)
handleClearallCommand(message);
else if (command == "transform")
handleTransformCommand(message);
else if (command == "correction")
handleCorrectionCommand(message);
else if (command == "temperature")
handleTemperatureCommand(message);
else if (command == "adjustment")
@ -398,26 +396,6 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &)
}
}
// collect correction information
Json::Value & correctionArray = info["correction"];
for (const std::string& correctionId : _hyperion->getCorrectionIds())
{
const ColorCorrection * colorCorrection = _hyperion->getCorrection(correctionId);
if (colorCorrection == nullptr)
{
std::cerr << "JSONCLIENT ERROR: Incorrect color correction id: " << correctionId << std::endl;
continue;
}
Json::Value & correction = correctionArray.append(Json::Value());
correction["id"] = correctionId;
Json::Value & corrValues = correction["correctionValues"];
corrValues.append(colorCorrection->_rgbCorrection.getcorrectionR());
corrValues.append(colorCorrection->_rgbCorrection.getcorrectionG());
corrValues.append(colorCorrection->_rgbCorrection.getcorrectionB());
}
// collect temperature correction information
Json::Value & temperatureArray = info["temperature"];
for (const std::string& tempId : _hyperion->getTemperatureIds())
@ -433,9 +411,9 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &)
temperature["id"] = tempId;
Json::Value & tempValues = temperature["correctionValues"];
tempValues.append(colorTemp->_rgbCorrection.getcorrectionR());
tempValues.append(colorTemp->_rgbCorrection.getcorrectionG());
tempValues.append(colorTemp->_rgbCorrection.getcorrectionB());
tempValues.append(colorTemp->_rgbCorrection.getAdjustmentR());
tempValues.append(colorTemp->_rgbCorrection.getAdjustmentG());
tempValues.append(colorTemp->_rgbCorrection.getAdjustmentB());
}
@ -492,17 +470,17 @@ void JsonClientConnection::handleServerInfoCommand(const Json::Value &)
adjustment["id"] = adjustmentId;
Json::Value & redAdjust = adjustment["redAdjust"];
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentR());
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentG());
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getadjustmentB());
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentR());
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentG());
redAdjust.append(colorAdjustment->_rgbRedAdjustment.getAdjustmentB());
Json::Value & greenAdjust = adjustment["greenAdjust"];
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentR());
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentG());
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getadjustmentB());
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentR());
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentG());
greenAdjust.append(colorAdjustment->_rgbGreenAdjustment.getAdjustmentB());
Json::Value & blueAdjust = adjustment["blueAdjust"];
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentR());
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentG());
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getadjustmentB());
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentR());
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentG());
blueAdjust.append(colorAdjustment->_rgbBlueAdjustment.getAdjustmentB());
}
// collect effect info
@ -706,32 +684,7 @@ void JsonClientConnection::handleTransformCommand(const Json::Value &message)
sendSuccessReply();
}
void JsonClientConnection::handleCorrectionCommand(const Json::Value &message)
{
const Json::Value & correction = message["correction"];
const std::string correctionId = correction.get("id", _hyperion->getCorrectionIds().front()).asString();
ColorCorrection * colorCorrection = _hyperion->getCorrection(correctionId);
if (colorCorrection == nullptr)
{
//sendErrorReply(std::string("Incorrect correction identifier: ") + correctionId);
return;
}
if (correction.isMember("correctionValues"))
{
const Json::Value & values = correction["correctionValues"];
colorCorrection->_rgbCorrection.setcorrectionR(values[0u].asInt());
colorCorrection->_rgbCorrection.setcorrectionG(values[1u].asInt());
colorCorrection->_rgbCorrection.setcorrectionB(values[2u].asInt());
}
// commit the changes
_hyperion->correctionsUpdated();
sendSuccessReply();
}
void JsonClientConnection::handleTemperatureCommand(const Json::Value &message)
{
const Json::Value & temperature = message["temperature"];
@ -747,9 +700,9 @@ void JsonClientConnection::handleTemperatureCommand(const Json::Value &message)
if (temperature.isMember("correctionValues"))
{
const Json::Value & values = temperature["correctionValues"];
colorTemperature->_rgbCorrection.setcorrectionR(values[0u].asInt());
colorTemperature->_rgbCorrection.setcorrectionG(values[1u].asInt());
colorTemperature->_rgbCorrection.setcorrectionB(values[2u].asInt());
colorTemperature->_rgbCorrection.setAdjustmentR(values[0u].asInt());
colorTemperature->_rgbCorrection.setAdjustmentG(values[1u].asInt());
colorTemperature->_rgbCorrection.setAdjustmentB(values[2u].asInt());
}
// commit the changes
@ -773,25 +726,25 @@ void JsonClientConnection::handleAdjustmentCommand(const Json::Value &message)
if (adjustment.isMember("redAdjust"))
{
const Json::Value & values = adjustment["redAdjust"];
colorAdjustment->_rgbRedAdjustment.setadjustmentR(values[0u].asInt());
colorAdjustment->_rgbRedAdjustment.setadjustmentG(values[1u].asInt());
colorAdjustment->_rgbRedAdjustment.setadjustmentB(values[2u].asInt());
colorAdjustment->_rgbRedAdjustment.setAdjustmentR(values[0u].asInt());
colorAdjustment->_rgbRedAdjustment.setAdjustmentG(values[1u].asInt());
colorAdjustment->_rgbRedAdjustment.setAdjustmentB(values[2u].asInt());
}
if (adjustment.isMember("greenAdjust"))
{
const Json::Value & values = adjustment["greenAdjust"];
colorAdjustment->_rgbGreenAdjustment.setadjustmentR(values[0u].asInt());
colorAdjustment->_rgbGreenAdjustment.setadjustmentG(values[1u].asInt());
colorAdjustment->_rgbGreenAdjustment.setadjustmentB(values[2u].asInt());
colorAdjustment->_rgbGreenAdjustment.setAdjustmentR(values[0u].asInt());
colorAdjustment->_rgbGreenAdjustment.setAdjustmentG(values[1u].asInt());
colorAdjustment->_rgbGreenAdjustment.setAdjustmentB(values[2u].asInt());
}
if (adjustment.isMember("blueAdjust"))
{
const Json::Value & values = adjustment["blueAdjust"];
colorAdjustment->_rgbBlueAdjustment.setadjustmentR(values[0u].asInt());
colorAdjustment->_rgbBlueAdjustment.setadjustmentG(values[1u].asInt());
colorAdjustment->_rgbBlueAdjustment.setadjustmentB(values[2u].asInt());
colorAdjustment->_rgbBlueAdjustment.setAdjustmentR(values[0u].asInt());
colorAdjustment->_rgbBlueAdjustment.setAdjustmentG(values[1u].asInt());
colorAdjustment->_rgbBlueAdjustment.setAdjustmentB(values[2u].asInt());
}
// commit the changes
_hyperion->adjustmentsUpdated();

View File

@ -113,13 +113,6 @@ private:
///
void handleTransformCommand(const Json::Value & message);
///
/// Handle an incoming JSON Correction message
///
/// @param message the incoming message
///
void handleCorrectionCommand(const Json::Value & message);
///
/// Handle an incoming JSON Temperature message
///

View File

@ -79,6 +79,7 @@ if(ENABLE_SPIDEV)
${CURRENT_SOURCE_DIR}/LedDeviceP9813.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.h
${CURRENT_SOURCE_DIR}/LedDeviceSk6812SPI.h
${CURRENT_SOURCE_DIR}/LedDeviceAPA102.h
)
SET(Leddevice_SOURCES
@ -89,6 +90,7 @@ if(ENABLE_SPIDEV)
${CURRENT_SOURCE_DIR}/LedDeviceP9813.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.cpp
${CURRENT_SOURCE_DIR}/LedDeviceSk6812SPI.cpp
${CURRENT_SOURCE_DIR}/LedDeviceAPA102.cpp
)
endif()

View File

@ -12,20 +12,18 @@
// hyperion local includes
#include "LedDeviceAPA102.h"
LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate, const unsigned ledcount) :
LedSpiDevice(outputDevice, baudrate, 500000),
_ledBuffer(0)
LedDeviceAPA102::LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate)
: LedSpiDevice(outputDevice, baudrate, 500000)
, _ledBuffer(0)
{
_HW_ledcount = ledcount;
}
int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
{
_mLedCount = ledValues.size();
const unsigned int max_leds = std::max(_mLedCount, _HW_ledcount);
const unsigned int startFrameSize = 4;
const unsigned int endFrameSize = std::max<unsigned int>(((max_leds + 15) / 16), 4);
const unsigned int APAbufferSize = (max_leds * 4) + startFrameSize + endFrameSize;
const unsigned int endFrameSize = std::max<unsigned int>(((_mLedCount + 15) / 16), 4);
const unsigned int APAbufferSize = (_mLedCount * 4) + startFrameSize + endFrameSize;
if(_ledBuffer.size() != APAbufferSize){
_ledBuffer.resize(APAbufferSize, 0xFF);
@ -35,8 +33,7 @@ int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
_ledBuffer[3] = 0x00;
}
unsigned iLed=0;
for (iLed=0; iLed < _mLedCount; ++iLed) {
for (unsigned iLed=0; iLed < _mLedCount; ++iLed) {
const ColorRgb& rgb = ledValues[iLed];
_ledBuffer[4+iLed*4] = 0xFF;
_ledBuffer[4+iLed*4+1] = rgb.red;
@ -44,13 +41,6 @@ int LedDeviceAPA102::write(const std::vector<ColorRgb> &ledValues)
_ledBuffer[4+iLed*4+3] = rgb.blue;
}
for ( ; iLed < max_leds; ++iLed) {
_ledBuffer[4+iLed*4] = 0xFF;
_ledBuffer[4+iLed*4+1] = 0x00;
_ledBuffer[4+iLed*4+2] = 0x00;
_ledBuffer[4+iLed*4+3] = 0x00;
}
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
}

View File

@ -17,11 +17,10 @@ public:
///
/// Constructs the LedDevice for a string containing leds of the type APA102
///
/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
/// @param outputDevice The name of the output device (eg '/dev/spidev.0.0')
/// @param baudrate The used baudrate for writing to the output device
///
LedDeviceAPA102(const std::string& outputDevice,
const unsigned baudrate, const unsigned ledcount );
LedDeviceAPA102(const std::string& outputDevice, const unsigned baudrate );
///
@ -39,7 +38,6 @@ private:
/// The buffer containing the packed RGB values
std::vector<uint8_t> _ledBuffer;
unsigned int _HW_ledcount;
unsigned int _mLedCount;
};

View File

@ -17,6 +17,7 @@
#include "LedDeviceP9813.h"
#include "LedDeviceWs2801.h"
#include "LedDeviceWs2812SPI.h"
#include "LedDeviceSk6812SPI.h"
#include "LedDeviceAPA102.h"
#endif
@ -119,9 +120,8 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
{
const std::string output = deviceConfig["output"].asString();
const unsigned rate = deviceConfig["rate"].asInt();
const unsigned ledcount = deviceConfig.get("leds",0).asInt();
LedDeviceAPA102* deviceAPA102 = new LedDeviceAPA102(output, rate, ledcount);
LedDeviceAPA102* deviceAPA102 = new LedDeviceAPA102(output, rate);
deviceAPA102->open();
device = deviceAPA102;
@ -147,6 +147,16 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
device = deviceWs2812SPI;
}
else if (type == "sk6812spi")
{
const std::string output = deviceConfig["output"].asString();
const unsigned rate = deviceConfig.get("rate",2857143).asInt();
LedDeviceSk6812SPI* deviceSk6812SPI = new LedDeviceSk6812SPI(output, rate);
deviceSk6812SPI->open();
device = deviceSk6812SPI;
}
#endif
#ifdef ENABLE_TINKERFORGE
else if (type=="tinkerforge")
@ -215,7 +225,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
const Json::Value gpioMapping = deviceConfig.get("gpiomap", Json::nullValue);
if (assignment.length() > 0) {
std::cout << "ERROR: Sorry, the configuration syntax has changed in this version." << std::endl;
Error(log, "Piblaster: The piblaster configuration syntax has changed in this version.");
exit(EXIT_FAILURE);
}
if (! gpioMapping.isNull() ) {
@ -224,7 +234,7 @@ LedDevice * LedDeviceFactory::construct(const Json::Value & deviceConfig)
device = devicePiBlaster;
} else {
std::cout << "ERROR: no gpiomap defined." << std::endl;
Error(log, "Piblaster: no gpiomap defined.");
exit(EXIT_FAILURE);
}
}

View File

@ -0,0 +1,67 @@
// STL includes
#include <cstring>
#include <cstdio>
#include <iostream>
// Linux includes
#include <fcntl.h>
#include <sys/ioctl.h>
// hyperion local includes
#include "LedDeviceSk6812SPI.h"
LedDeviceSk6812SPI::LedDeviceSk6812SPI(const std::string& outputDevice, const unsigned baudrate) :
LedSpiDevice(outputDevice, baudrate, 0),
mLedCount(0),
bitpair_to_byte {
0b10001000,
0b10001100,
0b11001000,
0b11001100,
}
{
// empty
}
int LedDeviceSk6812SPI::write(const std::vector<ColorRgb> &ledValues)
{
mLedCount = ledValues.size();
// 4 colours, 4 spi bytes per colour + 3 frame end latch bytes
#define COLOURS_PER_LED 3
#define SPI_BYTES_PER_COLOUR 4
#define SPI_BYTES_PER_LED COLOURS_PER_LED * SPI_BYTES_PER_COLOUR
unsigned spi_size = mLedCount * SPI_BYTES_PER_LED + 3;
if(_spiBuffer.size() != spi_size){
_spiBuffer.resize(spi_size, 0x00);
}
unsigned spi_ptr = 0;
for (unsigned i=0; i< mLedCount; ++i) {
uint8_t white = 0;
uint32_t colorBits =
((unsigned int)ledValues[i].red << 24) |
((unsigned int)ledValues[i].green << 16) |
((unsigned int)ledValues[i].blue << 8) |
white;
for (int j=SPI_BYTES_PER_LED - 1; j>=0; j--) {
_spiBuffer[spi_ptr+j] = bitpair_to_byte[ colorBits & 0x3 ];
colorBits >>= 2;
}
spi_ptr += SPI_BYTES_PER_LED;
}
_spiBuffer[spi_ptr++] = 0;
_spiBuffer[spi_ptr++] = 0;
_spiBuffer[spi_ptr++] = 0;
return writeBytes(spi_size, _spiBuffer.data());
}
int LedDeviceSk6812SPI::switchOff()
{
return write(std::vector<ColorRgb>(mLedCount, ColorRgb{0,0,0}));
}

View File

@ -0,0 +1,43 @@
#pragma once
// STL includes
#include <string>
// hyperion incluse
#include "LedSpiDevice.h"
///
/// Implementation of the LedDevice interface for writing to Sk6801 led device.
///
class LedDeviceSk6812SPI : public LedSpiDevice
{
public:
///
/// Constructs the LedDevice for a string containing leds of the type Sk6812SPI
///
/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
/// @param baudrate The used baudrate for writing to the output device
///
LedDeviceSk6812SPI(const std::string& outputDevice,
const unsigned baudrate);
///
/// Writes the led color values to the led-device
///
/// @param ledValues The color-value per led
/// @return Zero on succes else negative
///
virtual int write(const std::vector<ColorRgb> &ledValues);
/// Switch the leds off
virtual int switchOff();
private:
/// the number of leds (needed when switching off)
size_t mLedCount;
std::vector<uint8_t> _spiBuffer;
uint8_t bitpair_to_byte[4];
};

View File

@ -22,8 +22,6 @@ int update_number;
int fragment_number;
LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, const unsigned protocol, const unsigned maxPacket)
//LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate) :
// _ofs(output.empty()?"/home/pi/LedDevice.out":output.c_str())
{
std::string hostname;
std::string port;
@ -33,7 +31,6 @@ LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, c
leds_per_pkt = 200;
}
//printf ("leds_per_pkt is %d\n", leds_per_pkt);
int got_colon=0;
for (unsigned int i=0; i<output.length(); i++) {
if (output[i] == ':') {
@ -44,7 +41,6 @@ LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, c
port+=output[i];
}
}
//std::cout << "output " << output << " hostname " << hostname << " port " << port <<std::endl;
assert(got_colon==1);
int rv;
@ -62,7 +58,8 @@ LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, c
for(p = servinfo; p != NULL; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype,
p->ai_protocol)) == -1) {
perror("talker: socket");
Error(_log,"talker: socket %s", strerror(errno));
// perror("talker: socket");
continue;
}
@ -98,7 +95,6 @@ int LedDeviceUdp::write(const std::vector<ColorRgb> & ledValues)
udpbuffer[i++] = color.green;
udpbuffer[i++] = color.blue;
}
//printf ("c.red %d sz c.red %d\n", color.red, sizeof(color.red));
}
sendto(sockfd, udpbuffer, i, 0, p->ai_addr, p->ai_addrlen);
}

View File

@ -11,13 +11,6 @@
// hyperion local includes
#include "LedDeviceUdpRaw.h"
LedDeviceUdpRaw::LedDeviceUdpRaw(const std::string& outputDevice, const unsigned baudrate) :
LedUdpDevice(outputDevice, baudrate, 500000),
mLedCount(0)
{
// empty
}
LedDeviceUdpRaw::LedDeviceUdpRaw(const std::string& outputDevice, const unsigned baudrate, const unsigned latchTime) :
LedUdpDevice(outputDevice, baudrate, latchTime),
mLedCount(0)

View File

@ -18,8 +18,6 @@ public:
/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
/// @param baudrate The used baudrate for writing to the output device
///
LedDeviceUdpRaw(const std::string& outputDevice,
const unsigned baudrate);
LedDeviceUdpRaw(const std::string& outputDevice,
const unsigned baudrate,

View File

@ -313,7 +313,6 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
unsigned int wireBit = 1; // Holds the current bit we will set in PWMWaveform, start with 1 and skip the other two for speed
// Copy PWM waveform to DMA's data buffer
//printf("Copying %d words to DMA data buffer\n", NUM_DATA_WORDS);
struct control_data_s *ctl = (struct control_data_s *)virtbase;
dma_cb_t *cbp = ctl->cb;
@ -335,10 +334,7 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
for(size_t i=0; i<mLedCount; i++)
{
// Create bits necessary to represent one color triplet (in GRB, not RGB, order)
//printf("RGB: %d, %d, %d\n", ledValues[i].red, ledValues[i].green, ledValues[i].blue);
colorBits = ((unsigned int)ledValues[i].red << 8) | ((unsigned int)ledValues[i].green << 16) | ledValues[i].blue;
//printBinary(colorBits, 24);
//printf(" (binary, GRB order)\n");
// Iterate through color bits to get wire bits
for(int j=23; j>=0; j--) {
@ -380,7 +376,6 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
#ifdef WS2812_ASM_OPTI
// calculate the bits manually since it is not needed with asm
//wireBit += mLedCount * 24 *3;
//printf(" %d\n", wireBit);
#endif
//remove one to undo optimization
wireBit --;
@ -390,9 +385,6 @@ int LedDeviceWS2812b::write(const std::vector<ColorRgb> &ledValues)
startbitPattern = (1 << (rest-1)); // set new bitpattern to start at the benigining of one bit (3 bit in wave form)
rest += 32; // add one int extra for pwm
// printBinary(startbitPattern, 32);
// printf(" startbit\n");
unsigned int oldwireBitValue = wireBit;
unsigned int oldbitPattern = startbitPattern;

View File

@ -11,13 +11,6 @@
// hyperion local includes
#include "LedDeviceWs2801.h"
LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, const unsigned baudrate) :
LedSpiDevice(outputDevice, baudrate, 500000),
mLedCount(0)
{
// empty
}
LedDeviceWs2801::LedDeviceWs2801(const std::string& outputDevice, const unsigned baudrate, const unsigned latchTime) :
LedSpiDevice(outputDevice, baudrate, latchTime),
mLedCount(0)

View File

@ -18,8 +18,6 @@ public:
/// @param outputDevice The name of the output device (eg '/etc/SpiDev.0.0')
/// @param baudrate The used baudrate for writing to the output device
///
LedDeviceWs2801(const std::string& outputDevice,
const unsigned baudrate);
LedDeviceWs2801(const std::string& outputDevice,
const unsigned baudrate,

View File

@ -21,10 +21,6 @@ public:
LedDeviceWs2812SPI(const std::string& outputDevice,
const unsigned baudrate);
LedDeviceWs2812SPI(const std::string& outputDevice,
const unsigned baudrate,
const unsigned latchTime);
///
/// Writes the led color values to the led-device
///

View File

@ -36,8 +36,6 @@ add_library(hyperion-utils
${CURRENT_SOURCE_DIR}/HslTransform.cpp
${CURRENT_HEADER_DIR}/RgbChannelTransform.h
${CURRENT_SOURCE_DIR}/RgbChannelTransform.cpp
${CURRENT_HEADER_DIR}/RgbChannelCorrection.h
${CURRENT_SOURCE_DIR}/RgbChannelCorrection.cpp
${CURRENT_HEADER_DIR}/RgbChannelAdjustment.h
${CURRENT_SOURCE_DIR}/RgbChannelAdjustment.cpp

3
libsrc/utils/ImageResampler.cpp Normal file → Executable file
View File

@ -1,4 +1,5 @@
#include "utils/ImageResampler.h"
#include <utils/Logger.h>
ImageResampler::ImageResampler() :
_horizontalDecimation(1),
@ -124,7 +125,7 @@ void ImageResampler::processImage(const uint8_t * data, int width, int height, i
}
break;
case PIXELFORMAT_NO_CHANGE:
std::cerr << "Invalid pixel format given" << std::endl;
Error(Logger::getInstance("ImageResampler"), "Invalid pixel format given");
break;
}
}

View File

@ -75,6 +75,16 @@ void Logger::setLogLevel(LogLevel level,std::string name)
}
}
Logger::LogLevel Logger::getLogLevel(std::string name)
{
if ( name.empty() )
{
return GLOBAL_MIN_LOG_LEVEL;
}
Logger* log = Logger::getInstance(name);
return log->getMinLevel();
}
Logger::Logger ( std::string name, LogLevel minLevel ):
_name(name),

View File

@ -1,107 +1,84 @@
// STL includes
#include <cmath>
#include <cstdint>
#include <algorithm>
// Utils includes
#include <utils/RgbChannelAdjustment.h>
RgbChannelAdjustment::RgbChannelAdjustment() :
_adjustR(255),
_adjustG(255),
_adjustB(255)
RgbChannelAdjustment::RgbChannelAdjustment()
{
initializeMapping();
setAdjustment(UINT8_MAX, UINT8_MAX, UINT8_MAX);
}
RgbChannelAdjustment::RgbChannelAdjustment(int adjustR, int adjustG, int adjustB) :
_adjustR(adjustR),
_adjustG(adjustG),
_adjustB(adjustB)
RgbChannelAdjustment::RgbChannelAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB)
{
initializeMapping();
setAdjustment(adjustR, adjustG, adjustB);
}
RgbChannelAdjustment::~RgbChannelAdjustment()
{
}
uint8_t RgbChannelAdjustment::getadjustmentR() const
void RgbChannelAdjustment::setAdjustment(uint8_t adjustR, uint8_t adjustG, uint8_t adjustB)
{
return _adjustR;
}
void RgbChannelAdjustment::setadjustmentR(uint8_t adjustR)
{
_adjustR = adjustR;
_adjust[RED] = adjustR;
_adjust[GREEN] = adjustG;
_adjust[BLUE] = adjustB;
initializeMapping();
}
uint8_t RgbChannelAdjustment::getadjustmentG() const
uint8_t RgbChannelAdjustment::getAdjustmentR() const
{
return _adjustG;
return _adjust[RED];
}
void RgbChannelAdjustment::setadjustmentG(uint8_t adjustG)
void RgbChannelAdjustment::setAdjustmentR(uint8_t adjustR)
{
_adjustG = adjustG;
initializeMapping();
setAdjustment(adjustR, _adjust[GREEN], _adjust[BLUE]);
}
uint8_t RgbChannelAdjustment::getadjustmentB() const
uint8_t RgbChannelAdjustment::getAdjustmentG() const
{
return _adjustB;
return _adjust[GREEN];
}
void RgbChannelAdjustment::setadjustmentB(uint8_t adjustB)
void RgbChannelAdjustment::setAdjustmentG(uint8_t adjustG)
{
_adjustB = adjustB;
initializeMapping();
setAdjustment(_adjust[RED], adjustG, _adjust[BLUE]);
}
uint8_t RgbChannelAdjustment::getAdjustmentB() const
{
return _adjust[BLUE];
}
void RgbChannelAdjustment::setAdjustmentB(uint8_t adjustB)
{
setAdjustment(_adjust[RED], _adjust[GREEN], adjustB);
}
uint8_t RgbChannelAdjustment::adjustmentR(uint8_t inputR) const
{
return _mappingR[inputR];
return _mapping[RED][inputR];
}
uint8_t RgbChannelAdjustment::adjustmentG(uint8_t inputG) const
{
return _mappingG[inputG];
return _mapping[GREEN][inputG];
}
uint8_t RgbChannelAdjustment::adjustmentB(uint8_t inputB) const
{
return _mappingB[inputB];
return _mapping[BLUE][inputB];
}
void RgbChannelAdjustment::initializeMapping()
{
// initialize the mapping
for (int i = 0; i < 256; ++i)
{
int outputR = (i * _adjustR) / 255;
if (outputR > 255)
// initialize linear mapping
for (unsigned channel=0; channel<3; channel++)
for (unsigned idx=0; idx<=UINT8_MAX; idx++)
{
outputR = 255;
_mapping[channel][idx] = std::min( ((idx * _adjust[channel]) / UINT8_MAX), (unsigned)UINT8_MAX);
}
_mappingR[i] = outputR;
}
for (int i = 0; i < 256; ++i)
{
int outputG = (i * _adjustG) / 255;
if (outputG > 255)
{
outputG = 255;
}
_mappingG[i] = outputG;
}
for (int i = 0; i < 256; ++i)
{
int outputB = (i * _adjustB) / 255;
if (outputB > 255)
{
outputB = 255;
}
_mappingB[i] = outputB;
}
}

View File

@ -1,120 +0,0 @@
// STL includes
#include <cmath>
// Utils includes
#include <utils/RgbChannelCorrection.h>
RgbChannelCorrection::RgbChannelCorrection() :
_correctionR(255),
_correctionG(255),
_correctionB(255)
{
initializeMapping();
}
RgbChannelCorrection::RgbChannelCorrection(int correctionR, int correctionG, int correctionB) :
_correctionR(correctionR),
_correctionG(correctionG),
_correctionB(correctionB)
{
initializeMapping();
}
RgbChannelCorrection::~RgbChannelCorrection()
{
}
uint8_t RgbChannelCorrection::getcorrectionR() const
{
return _correctionR;
}
void RgbChannelCorrection::setcorrectionR(uint8_t correctionR)
{
_correctionR = correctionR;
initializeMapping();
}
uint8_t RgbChannelCorrection::getcorrectionG() const
{
return _correctionG;
}
void RgbChannelCorrection::setcorrectionG(uint8_t correctionG)
{
_correctionG = correctionG;
initializeMapping();
}
uint8_t RgbChannelCorrection::getcorrectionB() const
{
return _correctionB;
}
void RgbChannelCorrection::setcorrectionB(uint8_t correctionB)
{
_correctionB = correctionB;
initializeMapping();
}
uint8_t RgbChannelCorrection::correctionR(uint8_t inputR) const
{
return _mappingR[inputR];
}
uint8_t RgbChannelCorrection::correctionG(uint8_t inputG) const
{
return _mappingG[inputG];
}
uint8_t RgbChannelCorrection::correctionB(uint8_t inputB) const
{
return _mappingB[inputB];
}
void RgbChannelCorrection::initializeMapping()
{
// initialize the mapping
for (int i = 0; i < 256; ++i)
{
int outputR = (i * _correctionR) / 255;
if (outputR < -255)
{
outputR = -255;
}
else if (outputR > 255)
{
outputR = 255;
}
_mappingR[i] = outputR;
}
for (int i = 0; i < 256; ++i)
{
int outputG = (i * _correctionG) / 255;
if (outputG < -255)
{
outputG = -255;
}
else if (outputG > 255)
{
outputG = 255;
}
_mappingG[i] = outputG;
}
for (int i = 0; i < 256; ++i)
{
int outputB = (i * _correctionB) / 255;
if (outputB < -255)
{
outputB = -255;
}
else if (outputB > 255)
{
outputB = 255;
}
_mappingB[i] = outputB;
}
}

View File

@ -4,28 +4,29 @@
// Utils includes
#include <utils/RgbChannelTransform.h>
RgbChannelTransform::RgbChannelTransform() :
_threshold(0),
_gamma(1.0),
_blacklevel(0.0),
_whitelevel(1.0)
RgbChannelTransform::RgbChannelTransform()
{
initializeMapping();
setTransform(0.0, 1.0, 0.0, 1.0);
}
RgbChannelTransform::RgbChannelTransform(double threshold, double gamma, double blacklevel, double whitelevel) :
_threshold(threshold),
_gamma(gamma),
_blacklevel(blacklevel),
_whitelevel(whitelevel)
RgbChannelTransform::RgbChannelTransform(double threshold, double gamma, double blacklevel, double whitelevel)
{
initializeMapping();
setTransform(threshold, gamma, blacklevel, whitelevel);
}
RgbChannelTransform::~RgbChannelTransform()
{
}
void RgbChannelTransform::setTransform(double threshold, double gamma, double blacklevel, double whitelevel)
{
_threshold = threshold;
_gamma = gamma;
_blacklevel = blacklevel;
_whitelevel = whitelevel;
initializeMapping();
}
double RgbChannelTransform::getThreshold() const
{
return _threshold;
@ -33,8 +34,7 @@ double RgbChannelTransform::getThreshold() const
void RgbChannelTransform::setThreshold(double threshold)
{
_threshold = threshold;
initializeMapping();
setTransform(threshold, _gamma, _blacklevel, _whitelevel);
}
double RgbChannelTransform::getGamma() const
@ -44,8 +44,7 @@ double RgbChannelTransform::getGamma() const
void RgbChannelTransform::setGamma(double gamma)
{
_gamma = gamma;
initializeMapping();
setTransform(_threshold, gamma, _blacklevel, _whitelevel);
}
double RgbChannelTransform::getBlacklevel() const
@ -55,8 +54,7 @@ double RgbChannelTransform::getBlacklevel() const
void RgbChannelTransform::setBlacklevel(double blacklevel)
{
_blacklevel = blacklevel;
initializeMapping();
setTransform(_threshold, _gamma, blacklevel, _whitelevel);
}
double RgbChannelTransform::getWhitelevel() const
@ -66,8 +64,7 @@ double RgbChannelTransform::getWhitelevel() const
void RgbChannelTransform::setWhitelevel(double whitelevel)
{
_whitelevel = whitelevel;
initializeMapping();
setTransform(_threshold, _gamma, _blacklevel, whitelevel);
}
void RgbChannelTransform::initializeMapping()

3
libsrc/utils/RgbToRgbw.cpp Normal file → Executable file
View File

@ -1,5 +1,6 @@
#include <utils/ColorRgb.h>
#include <utils/ColorRgbw.h>
#include <utils/Logger.h>
void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm) {
if (_whiteAlgorithm == "subtract_minimum") {
@ -18,7 +19,7 @@ void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm
output->white = 0;
}
else {
std::cout << "ERROR: unknown whiteAlgorithm " << _whiteAlgorithm << std::endl;
Error(Logger::getInstance("RGBtoRGBW"), "unknown whiteAlgorithm %s", _whiteAlgorithm.c_str());
}
}

View File

@ -175,7 +175,7 @@ int main(int argc, char * argv[])
if (argIdC.isSet()) corrId = argIdC.getValue();
if (argCorrection.isSet()) correction = argCorrection.getValue();
connection.setCorrection(
connection.setTemperature(
argIdC.isSet() ? &corrId : nullptr,
argCorrection.isSet() ? &correction : nullptr);
}

View File

@ -1,4 +1,5 @@
#include <unistd.h>
#include <cassert>
#include <QCoreApplication>
#include <QResource>
@ -42,6 +43,26 @@ HyperionDaemon::HyperionDaemon(std::string configFile, QObject *parent)
{
loadConfig(configFile);
_hyperion = Hyperion::initInstance(_config, configFile);
if (Logger::getLogLevel() == Logger::WARNING)
{
if (_config.isMember("logger"))
{
const Json::Value & logConfig = _config["logger"];
std::string level = logConfig.get("level", "warn").asString(); // silent warn verbose debug
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
{
WarningIf(_config.isMember("logger"), Logger::getInstance("LOGGER"), "Logger settings overriden by command line argument");
}
Info(_log, "Hyperion started and initialised");
}
@ -231,13 +252,15 @@ void HyperionDaemon::startNetworkServices()
if (_config.isMember("boblightServer"))
{
const Json::Value & boblightServerConfig = _config["boblightServer"];
_boblightServer = new BoblightServer(
boblightServerConfig.get("priority",900).asInt(),
boblightServerConfig["port"].asUInt()
);
Debug(_log, "Boblight server created");
if ( boblightServerConfig.get("enable", true).asBool() )
{
_boblightServer = new BoblightServer(
boblightServerConfig.get("priority",900).asInt(),
boblightServerConfig["port"].asUInt()
);
Info(_log, "Boblight server created and started on port %d", _boblightServer->getPort());
_boblightServer->start();
}
}
@ -252,11 +275,10 @@ void HyperionDaemon::startNetworkServices()
udpListenerConfig.get("port", 2801).asUInt(),
udpListenerConfig.get("shared", false).asBool()
);
Info(_log, "UDP listener created on port %d", _udpListener->getPort());
Debug(_log, "UDP listener created");
if ( udpListenerConfig.get("enable", true).asBool() )
{
Info(_log, "UDP listener started" );
_udpListener->start();
}
}

View File

@ -75,5 +75,5 @@ private:
FramebufferWrapper* _fbGrabber;
OsxWrapper* _osxGrabber;
WebConfig* _webConfig;
Hyperion* _hyperion;
Hyperion* _hyperion;
};

View File

@ -54,7 +54,7 @@ void setColor(char* colorStr)
unsigned ledCnt = 50;
std::vector<ColorRgb> buff(ledCnt, color);
LedDeviceWs2801 ledDevice("/dev/spidev0.0", 40000);
LedDeviceWs2801 ledDevice("/dev/spidev0.0", 40000, 500000);
ledDevice.open();
ledDevice.write(buff);
}
@ -68,7 +68,7 @@ void doCircle()
unsigned ledCnt = 50;
std::vector<ColorRgb> data(ledCnt, ColorRgb::BLACK);
LedDeviceWs2801 ledDevice("/dev/spidev0.0", 40000);
LedDeviceWs2801 ledDevice("/dev/spidev0.0", 40000, 500000);
ledDevice.open();
timespec loopTime;

View File

@ -5,7 +5,7 @@ include_directories(${BCM_INCLUDE_DIRS})
# Configure the use of QT4
#find_package(Qt4 COMPONENTS QtTest REQUIRED QUIET)
include(${QT_USE_FILE})
#include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
@ -16,4 +16,5 @@ add_executable(dispmanx2png
target_link_libraries(dispmanx2png
dispmanx-grabber
getoptPlusPlus
Qt5Gui
${QT_LIBRARIES})

View File

@ -4,7 +4,7 @@
#include <iomanip>
// QT includes
#include <QImage>
#include <QtGui/QImage>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
@ -35,7 +35,7 @@ int main(int argc, char** argv)
ParameterSet & parameters = optionParser.getParameters();
QString flagDescr = QString("Set the grab flags of the dispmanx frame grabber [default: 0x%1]").arg(grabFlags, 8, 16, QChar('0'));
StringParameter & argFlags = parameters.add<StringParameter> ('f', "flags", flagDescr.toAscii().constData());
StringParameter & argFlags = parameters.add<StringParameter> ('f', "flags", flagDescr.toLatin1().constData());
IntParameter & argCount = parameters.add<IntParameter> ('n', "count", "Number of images to capture (default infinite)");
argCount.setDefault(grabCount);
SwitchParameter<> & argList = parameters.add<SwitchParameter<> >('l', "list", "List the possible flags");

View File

@ -143,7 +143,7 @@ void setup_io()
);
if ((long)gpio_map < 0) {
printf("mmap error %d\n", (int)gpio_map);
printf("mmap error %d\n", (long)gpio_map);
exit (-1);
}
gpio = (volatile unsigned *)gpio_map;
@ -169,7 +169,7 @@ void setup_io()
printf("SPI mapped from 0x%p to 0x%p\n",SPI0_BASE,spi0_map);
if ((long)spi0_map < 0) {
printf("mmap error %d\n", (int)spi0_map);
printf("mmap error %d\n", (long)spi0_map);
exit (-1);
}
spi0 = (volatile unsigned *)spi0_map;