Added simple QT-based grabber.

Moved ImageToLedsMap from include to libsrc.
Moved instantiation of objects to Hyperion (no JSON required outside this class).
This commit is contained in:
T. van der Zwan
2013-08-13 11:10:45 +02:00
parent 491d6ff608
commit 39b98386dd
32 changed files with 1065 additions and 508 deletions

View File

@@ -10,18 +10,22 @@ target_link_libraries(bob2hyperion
hyperion
hyperion-utils)
add_subdirectory(hyperion)
add_subdirectory(utils)
# Find the libPNG
find_package(PNG REQUIRED QUIET)
# Add additional includes dirs
include_directories(${PNG_INCLUDE_DIR})
if (PNG_FOUND)
# Add additional includes dirs
include_directories(${PNG_INCLUDE_DIR})
add_library(bob2hyperion-png SHARED
hyperion-png.cpp)
add_library(bob2hyperion-png SHARED
hyperion-png.cpp)
target_link_libraries(bob2hyperion-png
hyperion-png)
target_link_libraries(bob2hyperion-png
hyperion-png)
add_subdirectory(hyperionpng)
endif(PNG_FOUND)
add_subdirectory(hyperion)
add_subdirectory(hyperionpng)
add_subdirectory(utils)

View File

@@ -51,7 +51,7 @@ void boblight_destroy(void* hyperion_ptr)
Hyperion* raspiLight = rasp_cast(hyperion_ptr);
// Switch all leds to black (off)
raspiLight->setColor(RgbColor::BLACK);
// raspiLight->setColor(RgbColor::BLACK);
delete raspiLight;
@@ -64,20 +64,20 @@ void boblight_setscanrange(void* hyperion_ptr, int width, int height)
syslog(LOG_INFO, "Configuring scan range [%dx%d]", width, height);
Hyperion* raspiLight = rasp_cast(hyperion_ptr);
raspiLight->setInputSize(width, height);
// raspiLight->setInputSize(width, height);
}
void boblight_addpixelxy(void* hyperion_ptr, int x, int y, int* rgb)
{
Hyperion* raspiLight = rasp_cast(hyperion_ptr);
const RgbColor color = {uint8_t(rgb[0]), uint8_t(rgb[1]), uint8_t(rgb[2])};
raspiLight->image().setPixel(x, y, color);
// raspiLight->image().setPixel(x, y, color);
}
int boblight_sendrgb(void* hyperion_ptr, int sync, int* outputused)
{
Hyperion* raspiLight = rasp_cast(hyperion_ptr);
raspiLight->commit();
// raspiLight->commit();
return 1;
}

View File

@@ -1,22 +1,52 @@
# Find the BCM-package (VC control)
find_package(BCM REQUIRED)
include_directories(${BCM_INCLUDE_DIRS})
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/hyperion)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/hyperion)
add_library(hyperion
SET(Hyperion_HEADERS
${CURRENT_HEADER_DIR}/Hyperion.h
${CURRENT_HEADER_DIR}/LedDevice.h
${CURRENT_HEADER_DIR}/LedString.h
${CURRENT_HEADER_DIR}/ImageToLedsMap.h
${CURRENT_HEADER_DIR}/ImageProcessor.h
${CURRENT_HEADER_DIR}/ImageProcessorFactory.h
${CURRENT_HEADER_DIR}/PriorityMuxer.h
${CURRENT_HEADER_DIR}/DispmanxWrapper.h
${CURRENT_SOURCE_DIR}/DispmanxFrameGrabber.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
${CURRENT_SOURCE_DIR}/ImageToLedsMap.h
${CURRENT_SOURCE_DIR}/ColorTransform.h
)
SET(Hyperion_SOURCES
${CURRENT_SOURCE_DIR}/LedString.cpp
${CURRENT_SOURCE_DIR}/Hyperion.cpp
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
${CURRENT_SOURCE_DIR}/ColorTransform.h
${CURRENT_SOURCE_DIR}/ColorTransform.cpp
${CURRENT_SOURCE_DIR}/ImageProcessor.cpp
${CURRENT_SOURCE_DIR}/ImageProcessorFactory.cpp
${CURRENT_SOURCE_DIR}/PriorityMuxer.cpp
${CURRENT_SOURCE_DIR}/DispmanxWrapper.cpp
${CURRENT_SOURCE_DIR}/DispmanxFrameGrabber.cpp
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
${CURRENT_SOURCE_DIR}/ColorTransform.cpp
)
QT4_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_HEADERS})
add_library(hyperion
${Hyperion_HEADERS}
${Hyperion_HEADERS_MOC}
${Hyperion_SOURCES}
)
target_link_libraries(hyperion
hyperion-utils)
hyperion-utils
${QT_LIBRARIES}
${BCM_LIBRARIES})

View File

@@ -1,23 +1,26 @@
// STL includes
#include <cmath>
#include "ColorTransform.h"
using namespace hyperion;
ColorTransform::ColorTransform() :
_threshold(0),
_gamma(1.0),
_blacklevel(0.0),
_whitelevel(1.0)
_threshold(0),
_gamma(1.0),
_blacklevel(0.0),
_whitelevel(1.0)
{
initializeMapping();
initializeMapping();
}
ColorTransform::ColorTransform(double threshold, double gamma, double blacklevel, double whitelevel) :
_threshold(threshold),
_gamma(gamma),
_blacklevel(blacklevel),
_whitelevel(whitelevel)
_threshold(threshold),
_gamma(gamma),
_blacklevel(blacklevel),
_whitelevel(whitelevel)
{
initializeMapping();
initializeMapping();
}
ColorTransform::~ColorTransform()
@@ -26,77 +29,77 @@ ColorTransform::~ColorTransform()
double ColorTransform::getThreshold() const
{
return _threshold;
return _threshold;
}
void ColorTransform::setThreshold(double threshold)
{
_threshold = threshold;
initializeMapping();
_threshold = threshold;
initializeMapping();
}
double ColorTransform::getGamma() const
{
return _gamma;
return _gamma;
}
void ColorTransform::setGamma(double gamma)
{
_gamma = gamma;
initializeMapping();
_gamma = gamma;
initializeMapping();
}
double ColorTransform::getBlacklevel() const
{
return _blacklevel;
return _blacklevel;
}
void ColorTransform::setBlacklevel(double blacklevel)
{
_blacklevel = blacklevel;
initializeMapping();
_blacklevel = blacklevel;
initializeMapping();
}
double ColorTransform::getWhitelevel() const
{
return _whitelevel;
return _whitelevel;
}
void ColorTransform::setWhitelevel(double whitelevel)
{
_whitelevel = whitelevel;
initializeMapping();
_whitelevel = whitelevel;
initializeMapping();
}
void ColorTransform::initializeMapping()
{
// initialize the mapping as a linear array
for (int i = 0; i < 256; ++i)
{
double output = i / 255.0;
// initialize the mapping as a linear array
for (int i = 0; i < 256; ++i)
{
double output = i / 255.0;
// apply linear transform
if (output < _threshold)
{
output = 0.0;
}
// apply linear transform
if (output < _threshold)
{
output = 0.0;
}
// apply gamma correction
output = std::pow(output, _gamma);
// apply gamma correction
output = std::pow(output, _gamma);
// apply blacklevel and whitelevel
output = _blacklevel + (_whitelevel - _blacklevel) * output;
// apply blacklevel and whitelevel
output = _blacklevel + (_whitelevel - _blacklevel) * output;
// calc mapping
int mappingValue = output * 255;
if (mappingValue < 0)
{
mappingValue = 0;
}
else if (mappingValue > 255)
{
mappingValue = 255;
}
_mapping[i] = mappingValue;
}
// calc mapping
int mappingValue = output * 255;
if (mappingValue < 0)
{
mappingValue = 0;
}
else if (mappingValue > 255)
{
mappingValue = 255;
}
_mapping[i] = mappingValue;
}
}

View File

@@ -1,6 +1,10 @@
#pragma once
#include "stdint.h"
// STL includes
#include <cstdint>
namespace hyperion
{
/// Transform for a single color byte value
///
@@ -14,36 +18,38 @@
class ColorTransform
{
public:
ColorTransform();
ColorTransform(double threshold, double gamma, double whitelevel, double blacklevel);
~ColorTransform();
ColorTransform();
ColorTransform(double threshold, double gamma, double blacklevel, double whitelevel);
~ColorTransform();
double getThreshold() const;
void setThreshold(double threshold);
double getThreshold() const;
void setThreshold(double threshold);
double getGamma() const;
void setGamma(double gamma);
double getGamma() const;
void setGamma(double gamma);
double getBlacklevel() const;
void setBlacklevel(double blacklevel);
double getBlacklevel() const;
void setBlacklevel(double blacklevel);
double getWhitelevel() const;
void setWhitelevel(double whitelevel);
double getWhitelevel() const;
void setWhitelevel(double whitelevel);
/// get the transformed value for the given byte value
uint8_t transform(uint8_t input) const
{
return _mapping[input];
}
/// get the transformed value for the given byte value
uint8_t transform(uint8_t input) const
{
return _mapping[input];
}
private:
void initializeMapping();
void initializeMapping();
private:
double _threshold;
double _gamma;
double _blacklevel;
double _whitelevel;
double _threshold;
double _gamma;
double _blacklevel;
double _whitelevel;
uint8_t _mapping[256];
uint8_t _mapping[256];
};
} // end namespace hyperion

View File

@@ -0,0 +1,54 @@
#include "DispmanxFrameGrabber.h"
DispmanxFrameGrabber::DispmanxFrameGrabber(const unsigned width, const unsigned height) :
_display(0),
_resource(0),
_width(width),
_height(height)
{
// Initiase BCM
bcm_host_init();
// Open the connection to the displaydisplay
_display = vc_dispmanx_display_open(0);
int ret = vc_dispmanx_display_get_info(_display, &_info);
assert(ret == 0);
// Create the resources for capturing image
_resource = vc_dispmanx_resource_create(
VC_IMAGE_RGB888,
width,
height,
&_vc_image_ptr);
assert(_resource);
// Define the capture rectangle with the same size
vc_dispmanx_rect_set(&_rectangle, 0, 0, width, height);
_pitch = width * 3;
}
DispmanxFrameGrabber::~DispmanxFrameGrabber()
{
// Clean up resources
vc_dispmanx_resource_delete(_resource);
// Close the displaye
vc_dispmanx_display_close(_display);
// De-init BCM
bcm_host_deinit();
}
void DispmanxFrameGrabber::grabFrame(RgbImage& image)
{
// Sanity check of the given image size
assert(image.width() == _width && image.height() == _height);
void* image_ptr = image.memptr();
// Create the snapshot
vc_dispmanx_snapshot(_display, _resource, VC_IMAGE_ROT0);
// Read the snapshot into the memory (incl down-scaling)
vc_dispmanx_resource_read_data(_resource, &_rectangle, image_ptr, _pitch);
}

View File

@@ -0,0 +1,35 @@
#pragma once
// BCM includes
#include <bcm_host.h>
// STL includes
#include <cstdint>
// Utils includes
#include <utils/RgbImage.h>
///
/// The DispmanxFrameGrabber grabs
///
class DispmanxFrameGrabber
{
public:
DispmanxFrameGrabber(const unsigned width, const unsigned height);
~DispmanxFrameGrabber();
void grabFrame(RgbImage& image);
private:
DISPMANX_DISPLAY_HANDLE_T _display;
DISPMANX_MODEINFO_T _info;
DISPMANX_RESOURCE_HANDLE_T _resource;
uint32_t _vc_image_ptr;
VC_RECT_T _rectangle;
unsigned _width;
unsigned _height;
uint32_t _pitch;
};

View File

@@ -0,0 +1,46 @@
// QT includes
#include <QDebug>
#include <QDateTime>
// Hyperion includes
#include <hyperion/DispmanxWrapper.h>
#include <hyperion/ImageProcessorFactory.h>
// Local-Hyperion includes
#include "DispmanxFrameGrabber.h"
DispmanxWrapper::DispmanxWrapper() :
_timer(),
_processor(ImageProcessorFactory::getInstance().newImageProcessor()),
_frameGrabber(new DispmanxFrameGrabber(64, 64))
{
_timer.setInterval(100);
_timer.setSingleShot(false);
QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(action()));
}
DispmanxWrapper::~DispmanxWrapper()
{
delete _frameGrabber;
delete _processor;
}
void DispmanxWrapper::start()
{
_timer.start();
}
void DispmanxWrapper::action()
{
qDebug() << "[" << QDateTime::currentDateTimeUtc() << "] Grabbing frame";
RgbImage image(64, 64);
_frameGrabber->grabFrame(image);
//_processor->
}
void DispmanxWrapper::stop()
{
_timer.stop();
}

View File

@@ -10,6 +10,9 @@
#include <hyperion/LedDevice.h>
#include "LedDeviceWs2801.h"
#include "ColorTransform.h"
using namespace hyperion;
LedDevice* constructDevice(const Json::Value& deviceConfig)
{
@@ -34,9 +37,41 @@ LedDevice* constructDevice(const Json::Value& deviceConfig)
return device;
}
ColorTransform* createColorTransform(const Json::Value& colorConfig)
{
const double threshold = colorConfig["threshold"].asDouble();
const double gamma = colorConfig["gamma"].asDouble();
const double blacklevel = colorConfig["blacklevel"].asDouble();
const double whitelevel = colorConfig["whitelevel"].asDouble();
ColorTransform* transform = new ColorTransform(threshold, gamma, blacklevel, whitelevel);
return transform;
}
LedString createLedString(const Json::Value& ledsConfig)
{
LedString ledString;
for (const Json::Value& ledConfig : ledsConfig)
{
Led led;
led.index = ledConfig["index"].asInt();
const Json::Value& hscanConfig = ledConfig["hscan"];
const Json::Value& vscanConfig = ledConfig["vscan"];
led.minX_frac = std::max(0.0, std::min(100.0, hscanConfig["minimum"].asDouble()))/100.0;
led.maxX_frac = std::max(0.0, std::min(100.0, hscanConfig["maximum"].asDouble()))/100.0;
led.minY_frac = 1.0 - std::max(0.0, std::min(100.0, vscanConfig["maximum"].asDouble()))/100.0;
led.maxY_frac = 1.0 - std::max(0.0, std::min(100.0, vscanConfig["minimum"].asDouble()))/100.0;
ledString.leds().push_back(led);
}
return ledString;
}
Hyperion::Hyperion(const Json::Value &jsonConfig) :
mLedString(LedString::construct(jsonConfig["leds"], jsonConfig["color"])),
mImage(nullptr),
mLedString(createLedString(jsonConfig["leds"])),
mRedTransform( createColorTransform(jsonConfig["color"]["red"])),
mGreenTransform(createColorTransform(jsonConfig["color"]["green"])),
mBlueTransform( createColorTransform(jsonConfig["color"]["blue"])),
mDevice(constructDevice(jsonConfig["device"]))
{
// empty
@@ -45,58 +80,29 @@ Hyperion::Hyperion(const Json::Value &jsonConfig) :
Hyperion::~Hyperion()
{
// Delete the existing image (or delete nullptr)
delete mImage;
// Delete the Led-String
delete mDevice;
// Delete the color-transform
delete mBlueTransform;
delete mGreenTransform;
delete mRedTransform;
}
void Hyperion::setInputSize(const unsigned width, const unsigned height)
void Hyperion::setValue(int priority, std::vector<RgbColor>& ledColors)
{
// Delete the existing image (or delete nullptr)
delete mImage;
// Create the new image with the mapping to the leds
mImage = new RgbImage(width, height);
mLedsMap.createMapping(*mImage, mLedString.leds());
}
void Hyperion::commit()
{
// Derive the color per led
std::vector<RgbColor> ledColors = mLedsMap.getMeanLedColor();
// const std::vector<RgbColor> ledColors = mLedsMap.getMedianLedColor();
// Write the Led colors to the led-string
mDevice->write(ledColors);
}
void Hyperion::operator() (const RgbImage& inputImage)
{
// Copy the input-image into the buffer
mImage->copy(inputImage);
// Derive the color per led
std::vector<RgbColor> ledColors = mLedsMap.getMeanLedColor();
// std::vector<RgbColor> ledColors = mLedsMap.getMedianLedColor();
applyTransform(ledColors);
// Write the Led colors to the led-string
mDevice->write(ledColors);
}
void Hyperion::setColor(const RgbColor& color)
{
mDevice->write(std::vector<RgbColor>(mLedString.leds().size(), color));
}
void Hyperion::applyTransform(std::vector<RgbColor>& colors) const
{
for (RgbColor& color : colors)
// Apply the transform to each led and color-channel
for (RgbColor& color : ledColors)
{
color.red = (color.red < mLedString.red.blacklevel)? 0 : mLedString.red.adjust + mLedString.red.gamma * color.red;
color.green = (color.green < mLedString.green.blacklevel)? 0 : mLedString.green.adjust + mLedString.green.gamma * color.green;
color.blue = (color.blue < mLedString.blue.blacklevel)? 0 : mLedString.blue.adjust + mLedString.blue.gamma * color.blue;
color.red = mRedTransform->transform(color.red);
color.green = mGreenTransform->transform(color.green);
color.blue = mBlueTransform->transform(color.blue);
}
mMuxer.setInput(priority, ledColors);
if (priority == mMuxer.getCurrentPriority())
{
mDevice->write(ledColors);
}
}

View File

@@ -0,0 +1,65 @@
#include <hyperion/ImageProcessor.h>
#include "ImageToLedsMap.h"
#include "ColorTransform.h"
using namespace hyperion;
ImageProcessor::ImageProcessor(const LedString& ledString) :
mLedString(ledString),
mBuffer(nullptr),
mImageToLeds(nullptr)
{
// empty
}
ImageProcessor::~ImageProcessor()
{
delete mImageToLeds;
delete mBuffer;
}
std::vector<RgbColor> ImageProcessor::process(const RgbImage& image)
{
// Ensure that the buffer-image is the proper size
setSize(image.width(), image.height());
// Copy the data of the given image into the mapped-image
mBuffer->copy(image);
// Create a result vector and call the 'in place' functionl
std::vector<RgbColor> colors(mLedString.leds().size(), RgbColor::BLACK);
inplace_process(colors);
// return the computed colors
return colors;
}
void ImageProcessor::setSize(const unsigned width, const unsigned height)
{
// Check if the existing buffer-image is already the correct dimensions
if (mBuffer && mBuffer->width() == width && mBuffer->height() == height)
{
return;
}
// Clean up the old buffer and mapping
delete mImageToLeds;
delete mBuffer;
// Construct a new buffer and mapping
mBuffer = new RgbImage(width, height);
mImageToLeds = new ImageToLedsMap(*mBuffer, mLedString.leds());
}
RgbImage& ImageProcessor::image()
{
return *mBuffer;
}
void ImageProcessor::inplace_process(std::vector<RgbColor>& ledColors)
{
// Determine the mean-colors of each led (using the existing mapping)
mImageToLeds->getMeanLedColor(ledColors);
}

View File

@@ -0,0 +1,21 @@
// Hyperion includes
#include <hyperion/ImageProcessorFactory.h>
#include <hyperion/ImageProcessor.h>
ImageProcessorFactory& ImageProcessorFactory::getInstance()
{
static ImageProcessorFactory instance;
// Return the singleton instance
return instance;
}
void ImageProcessorFactory::init(const LedString& ledString)
{
_ledString = ledString;
}
ImageProcessor* ImageProcessorFactory::newImageProcessor() const
{
return new ImageProcessor(_ledString);
}

View File

@@ -3,14 +3,11 @@
#include <algorithm>
// hyperion includes
#include <hyperion/ImageToLedsMap.h>
#include "ImageToLedsMap.h"
ImageToLedsMap::ImageToLedsMap()
{
// empty
}
using namespace hyperion;
void ImageToLedsMap::createMapping(const RgbImage& image, const std::vector<Led>& leds)
ImageToLedsMap::ImageToLedsMap(const RgbImage& image, const std::vector<Led>& leds)
{
mColorsMap.resize(leds.size(), std::vector<const RgbColor*>());
@@ -46,6 +43,19 @@ std::vector<RgbColor> ImageToLedsMap::getMeanLedColor()
return colors;
}
void ImageToLedsMap::getMeanLedColor(std::vector<RgbColor>& ledColors)
{
// Sanity check for the number of leds
assert(mColorsMap.size() == ledColors.size());
auto led = ledColors.begin();
for (auto ledColors = mColorsMap.begin(); ledColors != mColorsMap.end(); ++ledColors, ++led)
{
const RgbColor color = findMeanColor(*ledColors);
*led = color;
}
}
RgbColor ImageToLedsMap::findMeanColor(const std::vector<const RgbColor*>& colors)
{
uint_fast16_t cummRed = 0;
@@ -64,27 +74,3 @@ RgbColor ImageToLedsMap::findMeanColor(const std::vector<const RgbColor*>& color
return {avgRed, avgGreen, avgBlue};
}
std::vector<RgbColor> ImageToLedsMap::getMedianLedColor()
{
std::vector<RgbColor> ledColors;
for (std::vector<const RgbColor*>& colors : mColorsMap)
{
const RgbColor color = findMedianColor(colors);
ledColors.push_back(color);
}
return ledColors;
}
RgbColor ImageToLedsMap::findMedianColor(std::vector<const RgbColor*>& colors)
{
std::sort(colors.begin(), colors.end(), [](const RgbColor* lhs, const RgbColor* rhs){ return lhs->red < rhs->red; });
const uint8_t red = colors.at(colors.size()/2)->red;
std::sort(colors.begin(), colors.end(), [](const RgbColor* lhs, const RgbColor* rhs){ return lhs->green < rhs->green; });
const uint8_t green = colors.at(colors.size()/2)->green;
std::sort(colors.begin(), colors.end(), [](const RgbColor* lhs, const RgbColor* rhs){ return lhs->blue < rhs->blue; });
const uint8_t blue = colors.at(colors.size()/2)->blue;
return {red, green, blue};
}

View File

@@ -0,0 +1,57 @@
#pragma once
// hyperion-utils includes
#include <utils/RgbImage.h>
// hyperion includes
#include <hyperion/LedString.h>
namespace hyperion
{
class ImageToLedsMap
{
public:
/**
* Constructs an mapping from the colors in the image to each led based on the border
* definition given in the list of leds. The map holds pointers to the given image and its
* lifetime should never exceed that of the given image
*
* @param[in] image The RGB image
* @param[in] leds The list with led specifications
*/
ImageToLedsMap(const RgbImage& image, const std::vector<Led>& leds);
/**
* Determines the mean-color for each led using the mapping the image given
* at construction.
*
* @return ledColors The vector containing the output
*/
std::vector<RgbColor> getMeanLedColor();
/**
* Determines the mean-color for each led using the mapping the image given
* at construction.
*
* @param[out] ledColors The vector containing the output
*/
void getMeanLedColor(std::vector<RgbColor>& ledColors);
private:
std::vector<std::vector<const RgbColor*> > mColorsMap;
/**
* Finds the 'mean color' of the given list. This is the mean over each color-channel (red,
* green, blue)
*
* @param colors The list with colors
*
* @return The mean of the given list of colors (or black when empty)
*/
RgbColor findMeanColor(const std::vector<const RgbColor*>& colors);
};
} // end namespace hyperion

View File

@@ -9,41 +9,6 @@
// hyperion includes
#include <hyperion/LedString.h>
LedString LedString::construct(const Json::Value& ledsConfig, const Json::Value& colorConfig)
{
LedString ledString;
const Json::Value& redConfig = colorConfig["red"];
const Json::Value& greenConfig = colorConfig["greem"];
const Json::Value& blueConfig = colorConfig["blue"];
ledString.red.gamma = redConfig["gamma"].asDouble();
ledString.red.adjust = redConfig["adjust"].asDouble();
ledString.red.blacklevel = redConfig["blacklevel"].asDouble();
ledString.green.gamma = greenConfig["gamma"].asDouble();
ledString.green.adjust = colorConfig["adjust"].asDouble();
ledString.green.blacklevel = colorConfig["blacklevel"].asDouble();
ledString.blue.gamma = blueConfig["gamma"].asDouble();
ledString.blue.adjust = blueConfig["adjust"].asDouble();
ledString.blue.blacklevel = blueConfig["blacklevel"].asDouble();
for (const Json::Value& ledConfig : ledsConfig)
{
Led led;
led.index = ledConfig["index"].asInt();
const Json::Value& hscanConfig = ledConfig["hscan"];
const Json::Value& vscanConfig = ledConfig["vscan"];
led.minX_frac = std::max(0.0, std::min(100.0, hscanConfig["minimum"].asDouble()))/100.0;
led.maxX_frac = std::max(0.0, std::min(100.0, hscanConfig["maximum"].asDouble()))/100.0;
led.minY_frac = 1.0 - std::max(0.0, std::min(100.0, vscanConfig["maximum"].asDouble()))/100.0;
led.maxY_frac = 1.0 - std::max(0.0, std::min(100.0, vscanConfig["minimum"].asDouble()))/100.0;
ledString.mLeds.push_back(led);
}
return ledString;
}
LedString::LedString()
{
@@ -54,6 +19,11 @@ LedString::~LedString()
{
}
std::vector<Led>& LedString::leds()
{
return mLeds;
}
const std::vector<Led>& LedString::leds() const
{
return mLeds;

View File

@@ -0,0 +1,94 @@
// STL includes
#include <algorithm>
#include <stdexcept>
// Hyperion includes
#include <hyperion/PriorityMuxer.h>
PriorityMuxer::PriorityMuxer() :
mCurrentPriority(MAX_PRIORITY)
{
// empty
}
PriorityMuxer::~PriorityMuxer()
{
// empty
}
int PriorityMuxer::getCurrentPriority() const
{
return mCurrentPriority;
}
QList<int> PriorityMuxer::getPriorities() const
{
return mActiveInputs.keys();
}
bool PriorityMuxer::hasPriority(const int priority) const
{
return mActiveInputs.contains(priority);
}
const PriorityMuxer::InputInfo& PriorityMuxer::getInputInfo(const int priority) const
{
auto elemIt = mActiveInputs.find(priority);
if (elemIt == mActiveInputs.end())
{
throw std::runtime_error("no such priority");
}
return elemIt.value();
}
void PriorityMuxer::setInput(const int priority, const std::vector<RgbColor>& ledColors, const int64_t timeoutTime_ms)
{
InputInfo& input = mActiveInputs[priority];
input.priority = priority;
input.timeoutTime_ms = timeoutTime_ms;
input.ledColors = ledColors;
mCurrentPriority = std::min(mCurrentPriority, priority);
}
void PriorityMuxer::clearInput(const int priority)
{
mActiveInputs.remove(priority);
if (mCurrentPriority == priority)
{
if (mActiveInputs.empty())
{
mCurrentPriority = MAX_PRIORITY;
}
else
{
QList<int> keys = mActiveInputs.keys();
mCurrentPriority = *std::min_element(keys.begin(), keys.end());
}
}
}
void PriorityMuxer::clearAll()
{
mActiveInputs.clear();
mCurrentPriority = MAX_PRIORITY;
}
void PriorityMuxer::setCurrentTime(const int64_t& now)
{
mCurrentPriority = MAX_PRIORITY;
for (auto infoIt = mActiveInputs.begin(); infoIt != mActiveInputs.end();)
{
if (infoIt->timeoutTime_ms != -1 && infoIt->timeoutTime_ms <= now)
{
infoIt = mActiveInputs.erase(infoIt);
}
else
{
mCurrentPriority = std::min(mCurrentPriority, infoIt->priority);
++infoIt;
}
}
}