Qcommandlineparser (#199)

* Replaced getoptplusplus with QCommandLineParser. Fixes #39

* enabling C++11 if possible

* enabling C++11 if possible

* fixed gcc compilation issues

* fixed linux builds and improved os x build

* trying to fix dispmanx

* trying to fix dispmanx

* simplified travis build script

* fixed argumentparser default values

* rewrote validator system and made sure default arguments are processed correctly

* rewrote validator system and made sure default arguments are processed correctly

* fixed bool vs. regular options

* oops... removing debug code

* reverted screenshot api change
This commit is contained in:
Rick van Hattem
2016-08-28 15:10:43 +02:00
committed by redPanther
parent c13f2e20ec
commit 61db9f43b8
74 changed files with 1490 additions and 3911 deletions

View File

@@ -30,7 +30,7 @@ add_executable(${PROJECT_NAME}
)
target_link_libraries(${PROJECT_NAME}
getoptPlusPlus
commandline
blackborder
hyperion-utils
protoserver

View File

@@ -4,20 +4,16 @@
#include <QCoreApplication>
#include <QImage>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
#include <protoserver/ProtoConnectionWrapper.h>
#include "AmlogicWrapper.h"
#include "HyperionConfig.h"
#include <utils/Logger.h>
#include <commandline/Parser.h>
using namespace vlofgren;
using namespace commandline;
// save the image as screenshot
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
void saveScreenshot(QString filename, const Image<ColorRgb> & image)
{
// store as PNG
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
@@ -35,50 +31,30 @@ int main(int argc, char ** argv)
try
{
// create the option parser and initialize all parameters
OptionsParser optionParser("AmLogic capture application for Hyperion");
ParameterSet & parameters = optionParser.getParameters();
// create the option parser and initialize all parser
Parser parser("AmLogic capture application for Hyperion");
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Capture frame rate [default: 10]");
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Width of the captured image [default: 128]");
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "Height of the captured image [default: 128]");
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
// set defaults
argFps.setDefault(10);
argWidth.setDefault(160);
argHeight.setDefault(160);
argAddress.setDefault("127.0.0.1:19445");
argPriority.setDefault(800);
IntOption & argFps = parser.add<IntOption> ('f', "framerate", "Capture frame rate [default: %1]", "10");
IntOption & argWidth = parser.add<IntOption> (0x0, "width", "Width of the captured image [default: %1]", "160", 160, 4096);
IntOption & argHeight = parser.add<IntOption> (0x0, "height", "Height of the captured image [default: %1]", "160", 160, 4096);
BooleanOption & argScreenshot = parser.add<BooleanOption> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
Option & argAddress = parser.add<Option> ('a', "address", "Set the address of the hyperion server [default: %1]", "127.0.0.1:19445");
IntOption & argPriority = parser.add<IntOption> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: %1]", "800");
BooleanOption & argSkipReply = parser.add<BooleanOption> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
BooleanOption & argHelp = parser.add<BooleanOption> ('h', "help", "Show this help message and exit");
// parse all options
optionParser.parse(argc, const_cast<const char **>(argv));
parser.process(app);
// check if we need to display the usage. exit if we do.
if (argHelp.isSet())
if (parser.isSet(argHelp))
{
optionParser.usage();
return 0;
parser.showHelp(0);
}
int width = argWidth.getValue();
int height = argHeight.getValue();
if (width < 160 || height < 160)
{
Warning(Logger::getInstance("AMLOGIC"), "Minimum width and height is 160");
AmlogicWrapper amlWrapper(argWidth.getInt(parser), argHeight.getInt(parser), 1000 / argFps.getInt(parser));
width = std::max(160, width);
height = std::max(160, height);
}
int grabInterval = 1000 / argFps.getValue();
AmlogicWrapper amlWrapper(argWidth.getValue(),argHeight.getValue(),grabInterval);
if (argScreenshot.isSet())
if (parser.isSet(argScreenshot))
{
// Capture a single screenshot and finish
const Image<ColorRgb> & screenshot = amlWrapper.getScreenshot();
@@ -87,7 +63,7 @@ int main(int argc, char ** argv)
else
{
// Create the Proto-connection with hyperiond
ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
ProtoConnectionWrapper protoWrapper(argAddress.value(parser), argPriority.getInt(parser), 1000, parser.isSet(argSkipReply));
// Connect the screen capturing to the proto processing
QObject::connect(&amlWrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));

View File

@@ -31,7 +31,7 @@ add_executable( ${PROJECT_NAME}
)
target_link_libraries( ${PROJECT_NAME}
getoptPlusPlus
commandline
blackborder
hyperion-utils
protoserver

View File

@@ -3,18 +3,16 @@
#include <QCoreApplication>
#include <QImage>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
#include <protoserver/ProtoConnectionWrapper.h>
#include "DispmanxWrapper.h"
#include "HyperionConfig.h"
#include <commandline/Parser.h>
using namespace vlofgren;
using namespace commandline;
// save the image as screenshot
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
void saveScreenshot(QString filename, const Image<ColorRgb> & image)
{
// store as PNG
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
@@ -33,71 +31,58 @@ int main(int argc, char ** argv)
try
{
// create the option parser and initialize all parameters
OptionsParser optionParser("Dispmanx capture application for Hyperion");
ParameterSet & parameters = optionParser.getParameters();
Parser parser("Dispmanx capture application for Hyperion");
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Capture frame rate [default: 10]");
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "The width of the grabbed frames [pixels]");
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "The height of the grabbed frames");
IntOption & argFps = parser.add<IntOption> ('f', "framerate", "Capture frame rate [default: %1]", "10");
IntOption & argWidth = parser.add<IntOption> (0x0, "width", "Width of the captured image [default: %1]", "64", 32, 4096);
IntOption & argHeight = parser.add<IntOption> (0x0, "height", "Height of the captured image [default: %1]", "64", 32, 4096);
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
BooleanOption & argScreenshot = parser.add<BooleanOption> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
Option & argAddress = parser.add<Option> ('a', "address", "Set the address of the hyperion server [default: %1]", "127.0.0.1:19445");
IntOption & argPriority = parser.add<IntOption> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: %1]", "800");
BooleanOption & argSkipReply = parser.add<BooleanOption> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
BooleanOption & argHelp = parser.add<BooleanOption> ('h', "help", "Show this help message and exit");
IntParameter & argCropLeft = parameters.add<IntParameter> (0x0, "crop-left", "pixels to remove on left after grabbing");
IntParameter & argCropRight = parameters.add<IntParameter> (0x0, "crop-right", "pixels to remove on right after grabbing");
IntParameter & argCropTop = parameters.add<IntParameter> (0x0, "crop-top", "pixels to remove on top after grabbing");
IntParameter & argCropBottom = parameters.add<IntParameter> (0x0, "crop-bottom", "pixels to remove on bottom after grabbing");
IntOption & argCropLeft = parser.add<IntOption> (0x0, "crop-left", "pixels to remove on left after grabbing");
IntOption & argCropRight = parser.add<IntOption> (0x0, "crop-right", "pixels to remove on right after grabbing");
IntOption & argCropTop = parser.add<IntOption> (0x0, "crop-top", "pixels to remove on top after grabbing");
IntOption & argCropBottom = parser.add<IntOption> (0x0, "crop-bottom", "pixels to remove on bottom after grabbing");
SwitchParameter<> & arg3DSBS = parameters.add<SwitchParameter<>> (0x0, "3DSBS", "Interpret the incoming video stream as 3D side-by-side");
SwitchParameter<> & arg3DTAB = parameters.add<SwitchParameter<>> (0x0, "3DTAB", "Interpret the incoming video stream as 3D top-and-bottom");
// set defaults
argFps.setDefault(10);
argWidth.setDefault(64);
argHeight.setDefault(64);
argAddress.setDefault("127.0.0.1:19445");
argPriority.setDefault(800);
argCropLeft.setDefault(0);
argCropRight.setDefault(0);
argCropTop.setDefault(0);
argCropBottom.setDefault(0);
BooleanOption & arg3DSBS = parser.add<BooleanOption> (0x0, "3DSBS", "Interpret the incoming video stream as 3D side-by-side");
BooleanOption & arg3DTAB = parser.add<BooleanOption> (0x0, "3DTAB", "Interpret the incoming video stream as 3D top-and-bottom");
// parse all options
optionParser.parse(argc, const_cast<const char **>(argv));
parser.process(app);
VideoMode videoMode = VIDEO_2D;
if (arg3DSBS.isSet())
if (parser.isSet(arg3DSBS))
{
videoMode = VIDEO_3DSBS;
}
else if (arg3DTAB.isSet())
else if (parser.isSet(arg3DTAB))
{
videoMode = VIDEO_3DTAB;
}
// check if we need to display the usage. exit if we do.
if (argHelp.isSet())
if (parser.isSet(argHelp))
{
optionParser.usage();
return 0;
parser.showHelp(1);
}
// Create the dispmanx grabbing stuff
int grabInterval = 1000 / argFps.getValue();
DispmanxWrapper dispmanxWrapper(argWidth.getValue(),argHeight.getValue(),
DispmanxWrapper dispmanxWrapper(
argWidth.getInt(parser),
argHeight.getInt(parser),
videoMode,
std::max(0, argCropLeft.getValue()),
std::max(0, argCropRight.getValue()),
std::max(0, argCropTop.getValue()),
std::max(0, argCropBottom.getValue()),
grabInterval);
argCropLeft.getInt(parser),
argCropRight.getInt(parser),
argCropTop.getInt(parser),
argCropBottom.getInt(parser),
1000 / argFps.getInt(parser));
if (argScreenshot.isSet())
if (parser.isSet(argScreenshot))
{
// Capture a single screenshot and finish
const Image<ColorRgb> & screenshot = dispmanxWrapper.getScreenshot();
@@ -106,7 +91,7 @@ int main(int argc, char ** argv)
else
{
// Create the Proto-connection with hyperiond
ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
ProtoConnectionWrapper protoWrapper(argAddress.value(parser), argPriority.getInt(parser), 1000, parser.isSet(argSkipReply));
// Connect the screen capturing to the proto processing
QObject::connect(&dispmanxWrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));

View File

@@ -30,7 +30,7 @@ add_executable( ${PROJECT_NAME}
)
target_link_libraries( ${PROJECT_NAME}
getoptPlusPlus
commandline
blackborder
hyperion-utils
protoserver

View File

@@ -4,16 +4,14 @@
#include <QCoreApplication>
#include <QImage>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
#include <protoserver/ProtoConnectionWrapper.h>
#include "FramebufferWrapper.h"
#include <commandline/Parser.h>
using namespace vlofgren;
using namespace commandline;
// save the image as screenshot
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
void saveScreenshot(QString filename, const Image<ColorRgb> & image)
{
// store as PNG
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
@@ -27,50 +25,30 @@ int main(int argc, char ** argv)
try
{
// create the option parser and initialize all parameters
OptionsParser optionParser("FrameBuffer capture application for Hyperion");
ParameterSet & parameters = optionParser.getParameters();
Parser parser("FrameBuffer capture application for Hyperion");
StringParameter & argDevice = parameters.add<StringParameter> ('d', "device", "Set the video device [default: /dev/video0]");
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Capture frame rate [default: 10]");
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Width of the captured image [default: 128]");
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "Height of the captured image [default: 128]");
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
// set defaults
argFps.setDefault(10);
argWidth.setDefault(160);
argHeight.setDefault(160);
argAddress.setDefault("127.0.0.1:19445");
argPriority.setDefault(800);
argDevice.setDefault("/dev/video0");
Option & argDevice = parser.add<Option> ('d', "device", "Set the video device [default: %1]", "/dev/video0");
IntOption & argFps = parser.add<IntOption> ('f', "framerate", "Capture frame rate [default: %1]", "10");
IntOption & argWidth = parser.add<IntOption> (0x0, "width", "Width of the captured image [default: %1]", "160", 160, 4096);
IntOption & argHeight = parser.add<IntOption> (0x0, "height", "Height of the captured image [default: %1]", "160", 160, 4096);
BooleanOption & argScreenshot = parser.add<BooleanOption> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
Option & argAddress = parser.add<Option> ('a', "address", "Set the address of the hyperion server [default: %1]", "127.0.0.1:19445");
IntOption & argPriority = parser.add<IntOption> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: %1]", "800");
BooleanOption & argSkipReply = parser.add<BooleanOption> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
BooleanOption & argHelp = parser.add<BooleanOption> ('h', "help", "Show this help message and exit");
// parse all options
optionParser.parse(argc, const_cast<const char **>(argv));
parser.process(app);
// check if we need to display the usage. exit if we do.
if (argHelp.isSet())
if (parser.isSet(argHelp))
{
optionParser.usage();
return 0;
parser.showHelp(0);
}
int width = argWidth.getValue();
int height = argHeight.getValue();
if (width < 160 || height < 160)
{
Warning(Logger::getInstance("FRAMEBUFFER"), "Minimum width and height is 160");
width = std::max(160, width);
height = std::max(160, height);
}
int grabInterval = 1000 / argFps.getValue();
FramebufferWrapper fbWrapper(argDevice.getValue(), argWidth.getValue(), argHeight.getValue(), grabInterval);
FramebufferWrapper fbWrapper(argDevice.getStdString(parser), argWidth.getInt(parser), argHeight.getInt(parser), 1000 / argFps.getInt(parser));
if (argScreenshot.isSet())
if (parser.isSet(argScreenshot))
{
// Capture a single screenshot and finish
const Image<ColorRgb> & screenshot = fbWrapper.getScreenshot();
@@ -79,7 +57,7 @@ int main(int argc, char ** argv)
else
{
// Create the Proto-connection with hyperiond
ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
ProtoConnectionWrapper protoWrapper(argAddress.value(parser), argPriority.getInt(parser), 1000, parser.isSet(argSkipReply));
// Connect the screen capturing to the proto processing
QObject::connect(&fbWrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));

View File

@@ -30,7 +30,7 @@ add_executable( ${PROJECT_NAME}
)
target_link_libraries( ${PROJECT_NAME}
getoptPlusPlus
commandline
blackborder
hyperion-utils
protoserver

View File

@@ -4,16 +4,14 @@
#include <QCoreApplication>
#include <QImage>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
#include <protoserver/ProtoConnectionWrapper.h>
#include "OsxWrapper.h"
#include <commandline/Parser.h>
using namespace vlofgren;
using namespace commandline;
// save the image as screenshot
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
void saveScreenshot(QString filename, const Image<ColorRgb> & image)
{
// store as PNG
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
@@ -27,69 +25,53 @@ int main(int argc, char ** argv)
try
{
// create the option parser and initialize all parameters
OptionsParser optionParser("OSX capture application for Hyperion");
ParameterSet & parameters = optionParser.getParameters();
Parser parser("OSX capture application for Hyperion");
IntParameter & argDisplay = parameters.add<IntParameter> ('d', "display", "Set the display to capture [default: 0]");
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Capture frame rate [default: 10]");
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Width of the captured image [default: 128]");
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "Height of the captured image [default: 128]");
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
Option & argDisplay = parser.add<Option> ('d', "display", "Set the display to capture [default: %1]");
IntOption & argFps = parser.add<IntOption> ('f', "framerate", "Capture frame rate [default: %1]", "10", 1, 600);
IntOption & argWidth = parser.add<IntOption> (0x0, "width", "Width of the captured image [default: %1]", "160", 160, 4096);
IntOption & argHeight = parser.add<IntOption> (0x0, "height", "Height of the captured image [default: %1]", "160", 160, 4096);
BooleanOption & argScreenshot = parser.add<BooleanOption> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
Option & argAddress = parser.add<Option> ('a', "address", "Set the address of the hyperion server [default: %1]", "127.0.0.1:19445");
IntOption & argPriority = parser.add<IntOption> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: %1]", "800");
BooleanOption & argSkipReply = parser.add<BooleanOption> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
BooleanOption & argHelp = parser.add<BooleanOption> ('h', "help", "Show this help message and exit");
// set defaults
argFps.setDefault(10);
argWidth.setDefault(160);
argHeight.setDefault(160);
argAddress.setDefault("127.0.0.1:19445");
argPriority.setDefault(800);
argDisplay.setDefault(0);
// parse all options
optionParser.parse(argc, const_cast<const char **>(argv));
// parse all arguments
parser.process(app);
// check if we need to display the usage. exit if we do.
if (argHelp.isSet())
if (parser.isSet(argHelp))
{
optionParser.usage();
return 0;
parser.showHelp(0);
}
int width = argWidth.getValue();
int height = argHeight.getValue();
if (width < 160 || height < 160)
{
Warning(Logger::getInstance("OSXGRABBER"), "Minimum width and height is 160");
width = std::max(160, width);
height = std::max(160, height);
}
int grabInterval = 1000 / argFps.getValue();
OsxWrapper osxWrapper(argDisplay.getValue(), argWidth.getValue(), argHeight.getValue(), grabInterval);
OsxWrapper osxWrapper
(parser.isSet(argDisplay), argWidth.getInt(parser), argHeight.getInt(parser), 1000 / argFps.getInt(parser));
if (argScreenshot.isSet())
{
// Capture a single screenshot and finish
const Image<ColorRgb> & screenshot = osxWrapper.getScreenshot();
saveScreenshot("screenshot.png", screenshot);
}
else
{
// Create the Proto-connection with hyperiond
ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
if (parser.isSet(argScreenshot)) {
// Capture a single screenshot and finish
const Image<ColorRgb> &screenshot = osxWrapper.getScreenshot();
saveScreenshot("screenshot.png", screenshot);
}
else {
// Create the Proto-connection with hyperiond
ProtoConnectionWrapper protoWrapper
(argAddress.value(parser), argPriority.getInt(parser), 1000, parser.isSet(argSkipReply));
// Connect the screen capturing to the proto processing
QObject::connect(&osxWrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));
// Connect the screen capturing to the proto processing
QObject::connect(&osxWrapper,
SIGNAL(sig_screenshot(
const Image<ColorRgb> &)),
&protoWrapper,
SLOT(receiveImage(Image<ColorRgb>)));
// Start the capturing
osxWrapper.start();
// Start the capturing
osxWrapper.start();
// Start the application
app.exec();
}
// Start the application
app.exec();
}
}
catch (const std::runtime_error & e)
{

View File

@@ -15,9 +15,7 @@ ENDIF()
include_directories(${QT_INCLUDES})
set(hyperion-remote_HEADERS
CustomParameter.h
JsonConnection.h
ColorTransformValues.h)
JsonConnection.h)
set(hyperion-remote_SOURCES
hyperion-remote.cpp
@@ -28,8 +26,8 @@ add_executable(${PROJECT_NAME}
${hyperion-remote_SOURCES})
target_link_libraries(${PROJECT_NAME}
commandline
jsoncpp
getoptPlusPlus
${QT_LIBRARIES})
qt5_use_modules(${PROJECT_NAME} Gui Core Network)

View File

@@ -1,12 +0,0 @@
#pragma once
/// Simple structure to contain the values of a color transformation
struct ColorAdjustmentValues
{
/// The value for the red color-channel
int valueRed;
/// The value for the green color-channel
int valueGreen;
/// The value for the blue color-channel
int valueBlue;
};

View File

@@ -1,12 +0,0 @@
#pragma once
/// Simple structure to contain the values of a color transformation
struct ColorCorrectionValues
{
/// The value for the red color-channel
int valueRed;
/// The value for the green color-channel
int valueGreen;
/// The value for the blue color-channel
int valueBlue;
};

View File

@@ -1,12 +0,0 @@
#pragma once
/// Simple structure to contain the values of a color transformation
struct ColorTransformValues
{
/// The value for the red color-channel
double valueRed;
/// The value for the green color-channel
double valueGreen;
/// The value for the blue color-channel
double valueBlue;
};

View File

@@ -1,197 +0,0 @@
#pragma once
// STL includes
#include <algorithm>
// Qt includes
#include <QColor>
#include <QImage>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
// hyperion-remote includes
#include "ColorTransformValues.h"
#include "ColorCorrectionValues.h"
#include "ColorAdjustmentValues.h"
/// Data parameter for a color
typedef vlofgren::PODParameter<std::vector<QColor>> ColorParameter;
/// Data parameter for an image
typedef vlofgren::PODParameter<QImage> ImageParameter;
/// Data parameter for color transform values (list of three values)
typedef vlofgren::PODParameter<ColorTransformValues> TransformParameter;
/// Data parameter for color correction values (list of three values)
typedef vlofgren::PODParameter<ColorCorrectionValues> CorrectionParameter;
/// Data parameter for color correction values (list of three values)
typedef vlofgren::PODParameter<ColorAdjustmentValues> AdjustmentParameter;
namespace vlofgren {
///
/// Translates a string (as passed on the commandline) to a vector of colors
///
/// @param[in] s The string (as passed on the commandline)
///
/// @return The translated colors
///
/// @throws Parameter::ParameterRejected If the string did not result in a color
///
template<>
std::vector<QColor> ColorParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
{
// Check if we can create the color by name
QColor color(s.c_str());
if (color.isValid())
{
return std::vector<QColor>{color};
}
// check if we can create the color by hex RRGGBB value
if (s.length() >= 6u && (s.length()%6u) == 0u && std::count_if(s.begin(), s.end(), isxdigit) == int(s.length()))
{
bool ok = true;
std::vector<QColor> colors;
for (size_t j = 0; j < s.length()/6; ++j)
{
int rgb[3];
for (int i = 0; i < 3 && ok; ++i)
{
QString colorComponent(s.substr(6*j+2*i, 2).c_str());
rgb[i] = colorComponent.toInt(&ok, 16);
}
if (ok)
{
color.setRgb(rgb[0], rgb[1], rgb[2]);
colors.push_back(color);
}
else
{
break;
}
}
// check if all components parsed succesfully
if (ok)
{
return colors;
}
}
std::stringstream errorMessage;
errorMessage << "Invalid color. A color is specified by a six lettered RRGGBB hex value or one of the following names:";
foreach (const QString & colorname, QColor::colorNames()) {
errorMessage << "\n " << colorname.toStdString();
}
throw Parameter::ParameterRejected(errorMessage.str());
return std::vector<QColor>{color};
}
template<>
QImage ImageParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
{
QImage image(s.c_str());
if (image.isNull())
{
std::stringstream errorMessage;
errorMessage << "File " << s << " could not be opened as an image";
throw Parameter::ParameterRejected(errorMessage.str());
}
return image;
}
template<>
ColorTransformValues TransformParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
{
ColorTransformValues transform;
// s should be split in 3 parts
// seperators are either a ',' or a space
QStringList components = QString(s.c_str()).split(" ", QString::SkipEmptyParts);
if (components.size() == 3)
{
bool ok1, ok2, ok3;
transform.valueRed = components[0].toDouble(&ok1);
transform.valueGreen = components[1].toDouble(&ok2);
transform.valueBlue = components[2].toDouble(&ok3);
if (ok1 && ok2 && ok3)
{
return transform;
}
}
std::stringstream errorMessage;
errorMessage << "Argument " << s << " can not be parsed to 3 double values";
throw Parameter::ParameterRejected(errorMessage.str());
return transform;
}
template<>
ColorCorrectionValues CorrectionParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
{
ColorCorrectionValues correction;
// s should be split in 3 parts
// seperators are either a ',' or a space
QStringList components = QString(s.c_str()).split(" ", QString::SkipEmptyParts);
if (components.size() == 3)
{
bool ok1, ok2, ok3;
correction.valueRed = components[0].toInt(&ok1);
correction.valueGreen = components[1].toInt(&ok2);
correction.valueBlue = components[2].toInt(&ok3);
if (ok1 && ok2 && ok3)
{
return correction;
}
}
std::stringstream errorMessage;
errorMessage << "Argument " << s << " can not be parsed to 3 integer values";
throw Parameter::ParameterRejected(errorMessage.str());
return correction;
}
template<>
ColorAdjustmentValues AdjustmentParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
{
ColorAdjustmentValues adjustment;
// s should be split in 3 parts
// seperators are either a ',' or a space
QStringList components = QString(s.c_str()).split(" ", QString::SkipEmptyParts);
if (components.size() == 3)
{
bool ok1, ok2, ok3;
adjustment.valueRed = components[0].toInt(&ok1);
adjustment.valueGreen = components[1].toInt(&ok2);
adjustment.valueBlue = components[2].toInt(&ok3);
if (ok1 && ok2 && ok3)
{
return adjustment;
}
}
std::stringstream errorMessage;
errorMessage << "Argument " << s << " can not be parsed to 3 integer values";
throw Parameter::ParameterRejected(errorMessage.str());
return adjustment;
}
}

View File

@@ -8,11 +8,10 @@
// hyperion-remote includes
#include "JsonConnection.h"
JsonConnection::JsonConnection(const std::string & a, bool printJson)
JsonConnection::JsonConnection(const QString & address, bool printJson)
: _printJson(printJson)
, _socket()
{
QString address(a.c_str());
QStringList parts = address.split(":");
if (parts.size() != 2)
{
@@ -32,7 +31,7 @@ JsonConnection::JsonConnection(const std::string & a, bool printJson)
throw std::runtime_error("Unable to connect to host");
}
std::cout << "Connected to " << a << std::endl;
qDebug() << "Connected to:" << address;
}
JsonConnection::~JsonConnection()
@@ -67,7 +66,7 @@ void JsonConnection::setColor(std::vector<QColor> colors, int priority, int dura
parseReply(reply);
}
void JsonConnection::setImage(QImage image, int priority, int duration)
void JsonConnection::setImage(QImage &image, int priority, int duration)
{
std::cout << "Set image has size: " << image.width() << "x" << image.height() << std::endl;
@@ -93,7 +92,7 @@ void JsonConnection::setImage(QImage image, int priority, int duration)
command["priority"] = priority;
command["imagewidth"] = image.width();
command["imageheight"] = image.height();
command["imagedata"] = std::string(base64Image.data(), base64Image.size());
command["imagedata"] = base64Image.data();
if (duration > 0)
{
command["duration"] = duration;
@@ -106,20 +105,20 @@ void JsonConnection::setImage(QImage image, int priority, int duration)
parseReply(reply);
}
void JsonConnection::setEffect(const std::string &effectName, const std::string & effectArgs, int priority, int duration)
void JsonConnection::setEffect(const QString &effectName, const QString & effectArgs, int priority, int duration)
{
std::cout << "Start effect " << effectName << std::endl;
qDebug() << "Start effect " << effectName;
// create command
Json::Value command;
command["command"] = "effect";
command["priority"] = priority;
Json::Value & effect = command["effect"];
effect["name"] = effectName;
effect["name"] = effectName.toStdString();
if (effectArgs.size() > 0)
{
Json::Reader reader;
if (!reader.parse(effectArgs, effect["args"], false))
if (!reader.parse(effectArgs.toStdString(), effect["args"], false))
{
throw std::runtime_error("Error in effect arguments: " + reader.getFormattedErrorMessages());
}
@@ -193,16 +192,15 @@ void JsonConnection::clearAll()
parseReply(reply);
}
void JsonConnection::setComponentState(const std::string& component, const bool state)
void JsonConnection::setComponentState(const QString & component, const bool state)
{
state ? std::cout << "Enable Component " : std::cout << "Disable Component ";
std::cout << component << std::endl;
qDebug() << (state ? "Enable" : "Disable") << "Component" << component;
// create command
Json::Value command;
command["command"] = "componentstate";
Json::Value & parameter = command["componentstate"];
parameter["component"] = component;
parameter["component"] = component.toStdString();
parameter["state"] = state;
// send command message
@@ -268,7 +266,7 @@ QString JsonConnection::getConfig(std::string type)
return QString();
}
void JsonConnection::setConfig(const std::string &jsonString, bool create, bool overwrite)
void JsonConnection::setConfig(const QString &jsonString, bool create, bool overwrite)
{
// create command
Json::Value command;
@@ -281,7 +279,7 @@ void JsonConnection::setConfig(const std::string &jsonString, bool create, bool
if (jsonString.size() > 0)
{
Json::Reader reader;
if (!reader.parse(jsonString, config, false))
if (!reader.parse(jsonString.toStdString(), config, false))
{
throw std::runtime_error("Error in configset arguments: " + reader.getFormattedErrorMessages());
}
@@ -294,7 +292,16 @@ void JsonConnection::setConfig(const std::string &jsonString, bool create, bool
parseReply(reply);
}
void JsonConnection::setTransform(std::string * transformId, double * saturation, double * value, double * saturationL, double * luminance, double * luminanceMin, ColorTransformValues *threshold, ColorTransformValues *gamma, ColorTransformValues *blacklevel, ColorTransformValues *whitelevel)
void JsonConnection::setTransform(const QString &transformId,
double *saturation,
double *value,
double *saturationL,
double *luminance,
double *luminanceMin,
QColor threshold,
QColor gamma,
QColor blacklevel,
QColor whitelevel)
{
std::cout << "Set color transforms" << std::endl;
@@ -303,9 +310,9 @@ void JsonConnection::setTransform(std::string * transformId, double * saturation
command["command"] = "transform";
Json::Value & transform = command["transform"];
if (transformId != nullptr)
if (!transformId.isNull())
{
transform["id"] = *transformId;
transform["id"] = transformId.toStdString();
}
if (saturation != nullptr)
@@ -333,36 +340,36 @@ void JsonConnection::setTransform(std::string * transformId, double * saturation
transform["luminanceMinimum"] = *luminanceMin;
}
if (threshold != nullptr)
if (threshold.isValid())
{
Json::Value & v = transform["threshold"];
v.append(threshold->valueRed);
v.append(threshold->valueGreen);
v.append(threshold->valueBlue);
v.append(threshold.red());
v.append(threshold.green());
v.append(threshold.blue());
}
if (gamma != nullptr)
if (gamma.isValid())
{
Json::Value & v = transform["gamma"];
v.append(gamma->valueRed);
v.append(gamma->valueGreen);
v.append(gamma->valueBlue);
v.append(gamma.red());
v.append(gamma.green());
v.append(gamma.blue());
}
if (blacklevel != nullptr)
if (blacklevel.isValid())
{
Json::Value & v = transform["blacklevel"];
v.append(blacklevel->valueRed);
v.append(blacklevel->valueGreen);
v.append(blacklevel->valueBlue);
v.append(blacklevel.red());
v.append(blacklevel.green());
v.append(blacklevel.blue());
}
if (whitelevel != nullptr)
if (whitelevel.isValid())
{
Json::Value & v = transform["whitelevel"];
v.append(whitelevel->valueRed);
v.append(whitelevel->valueGreen);
v.append(whitelevel->valueBlue);
v.append(whitelevel.red());
v.append(whitelevel.green());
v.append(whitelevel.blue());
}
// send command message
@@ -372,7 +379,7 @@ void JsonConnection::setTransform(std::string * transformId, double * saturation
parseReply(reply);
}
void JsonConnection::setCorrection(std::string * correctionId, ColorCorrectionValues *correction)
void JsonConnection::setCorrection(QString &correctionId, const QColor & correction)
{
std::cout << "Set color corrections" << std::endl;
@@ -381,17 +388,17 @@ void JsonConnection::setCorrection(std::string * correctionId, ColorCorrectionVa
command["command"] = "correction";
Json::Value & correct = command["correction"];
if (correctionId != nullptr)
if (!correctionId.isNull())
{
correct["id"] = *correctionId;
correct["id"] = correctionId.toStdString();
}
if (correction != nullptr)
if (correction.isValid())
{
Json::Value & v = correct["correctionValues"];
v.append(correction->valueRed);
v.append(correction->valueGreen);
v.append(correction->valueBlue);
v.append(correction.red());
v.append(correction.green());
v.append(correction.blue());
}
// send command message
@@ -401,7 +408,7 @@ void JsonConnection::setCorrection(std::string * correctionId, ColorCorrectionVa
parseReply(reply);
}
void JsonConnection::setTemperature(std::string * temperatureId, ColorCorrectionValues *temperature)
void JsonConnection::setTemperature(const QString &temperatureId, const QColor & temperature)
{
std::cout << "Set color temperature corrections" << std::endl;
@@ -410,17 +417,17 @@ void JsonConnection::setTemperature(std::string * temperatureId, ColorCorrection
command["command"] = "temperature";
Json::Value & temp = command["temperature"];
if (temperatureId != nullptr)
if (!temperatureId.isNull())
{
temp["id"] = *temperatureId;
temp["id"] = temperatureId.toStdString();
}
if (temperature != nullptr)
if (temperature.isValid())
{
Json::Value & v = temp["correctionValues"];
v.append(temperature->valueRed);
v.append(temperature->valueGreen);
v.append(temperature->valueBlue);
v.append(temperature.red());
v.append(temperature.green());
v.append(temperature.blue());
}
// send command message
@@ -430,7 +437,10 @@ void JsonConnection::setTemperature(std::string * temperatureId, ColorCorrection
parseReply(reply);
}
void JsonConnection::setAdjustment(std::string * adjustmentId, ColorAdjustmentValues * redAdjustment, ColorAdjustmentValues * greenAdjustment, ColorAdjustmentValues * blueAdjustment)
void JsonConnection::setAdjustment(const QString &adjustmentId,
const QColor & redAdjustment,
const QColor & greenAdjustment,
const QColor & blueAdjustment)
{
std::cout << "Set color adjustments" << std::endl;
@@ -439,33 +449,33 @@ void JsonConnection::setAdjustment(std::string * adjustmentId, ColorAdjustmentVa
command["command"] = "adjustment";
Json::Value & adjust = command["adjustment"];
if (adjustmentId != nullptr)
if (!adjustmentId.isNull())
{
adjust["id"] = *adjustmentId;
adjust["id"] = adjustmentId.toStdString();
}
if (redAdjustment != nullptr)
if (redAdjustment.isValid())
{
Json::Value & v = adjust["redAdjust"];
v.append(redAdjustment->valueRed);
v.append(redAdjustment->valueGreen);
v.append(redAdjustment->valueBlue);
v.append(redAdjustment.red());
v.append(redAdjustment.green());
v.append(redAdjustment.blue());
}
if (greenAdjustment != nullptr)
if (greenAdjustment.isValid())
{
Json::Value & v = adjust["greenAdjust"];
v.append(greenAdjustment->valueRed);
v.append(greenAdjustment->valueGreen);
v.append(greenAdjustment->valueBlue);
v.append(greenAdjustment.red());
v.append(greenAdjustment.green());
v.append(greenAdjustment.blue());
}
if (blueAdjustment != nullptr)
if (blueAdjustment.isValid())
{
Json::Value & v = adjust["blueAdjust"];
v.append(blueAdjustment->valueRed);
v.append(blueAdjustment->valueGreen);
v.append(blueAdjustment->valueBlue);
v.append(blueAdjustment.red());
v.append(blueAdjustment.green());
v.append(blueAdjustment.blue());
}
// send command message

View File

@@ -13,9 +13,6 @@
#include <json/json.h>
// hyperion-remote includes
#include "ColorTransformValues.h"
#include "ColorCorrectionValues.h"
#include "ColorAdjustmentValues.h"
///
/// Connection class to setup an connection to the hyperion server and execute commands
@@ -29,7 +26,7 @@ public:
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
/// @param printJson Boolean indicating if the sent and received json is written to stdout
///
JsonConnection(const std::string & address, bool printJson);
JsonConnection(const QString & address, bool printJson);
///
/// Destructor
@@ -52,7 +49,7 @@ public:
/// @param priority The priority
/// @param duration The duration in milliseconds
///
void setImage(QImage image, int priority, int duration);
void setImage(QImage &image, int priority, int duration);
///
/// Start the given effect
@@ -62,7 +59,7 @@ public:
/// @param priority The priority
/// @param duration The duration in milliseconds
///
void setEffect(const std::string & effectName, const std::string &effectArgs, int priority, int duration);
void setEffect(const QString & effectName, const QString &effectArgs, int priority, int duration);
///
/// Retrieve a list of all occupied priority channels
@@ -89,7 +86,7 @@ public:
/// @param component The component [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]
/// @param state The state of the component [true | false]
///
void setComponentState(const std::string & component, const bool state);
void setComponentState(const QString & component, const bool state);
///
/// Set current active priority channel and deactivate auto source switching
@@ -114,7 +111,7 @@ public:
/// @param jsonString The JSON String(s) to write
/// @param create Specifies whether the nonexistent json string to be created
///
void setConfig(const std::string & jsonString, bool create, bool overwrite);
void setConfig(const QString &jsonString, bool create, bool overwrite);
///
/// Set the color transform of the leds
@@ -133,16 +130,16 @@ public:
/// @param whitelevel The whitelevel
///
void setTransform(
std::string * transformId,
double * saturation,
double * value,
double * saturationL,
double * luminance,
double * luminanceMin,
ColorTransformValues * threshold,
ColorTransformValues * gamma,
ColorTransformValues * blacklevel,
ColorTransformValues * whitelevel);
const QString &transformId,
double *saturation,
double *value,
double *saturationL,
double *luminance,
double *luminanceMin,
QColor threshold,
QColor gamma,
QColor blacklevel,
QColor whitelevel);
///
/// Set the color correction of the leds
@@ -152,8 +149,8 @@ public:
/// @param correctionId The identifier of the correction to set
/// @param correction The correction values
void setCorrection(
std::string * correctionId,
ColorCorrectionValues * correction);
QString &correctionId,
const QColor & correction);
///
/// Set the color temperature of the leds
@@ -163,8 +160,8 @@ public:
/// @param temperatureId The identifier of the correction to set
/// @param temperature The temperature correction values
void setTemperature(
std::string * temperatureId,
ColorCorrectionValues * temperature);
const QString & temperatureId,
const QColor & temperature);
///
/// Set the color adjustment of the leds
@@ -176,10 +173,10 @@ public:
/// @param greenAdjustment The green channel adjustment values
/// @param blueAdjustment The blue channel adjustment values
void setAdjustment(
std::string * adjustmentId,
ColorAdjustmentValues * redAdjustment,
ColorAdjustmentValues * greenAdjustment,
ColorAdjustmentValues * blueAdjustment);
const QString & adjustmentId,
const QColor & redAdjustment,
const QColor & greenAdjustment,
const QColor & blueAdjustment);
private:
///

View File

@@ -7,17 +7,13 @@
#include <QCoreApplication>
#include <QLocale>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
// hyperion-remote include
#include "CustomParameter.h"
#include "JsonConnection.h"
#include "HyperionConfig.h"
#include <commandline/Parser.h>
using namespace vlofgren;
using namespace commandline;
/// Count the number of true values in a list of booleans
int count(std::initializer_list<bool> values)
@@ -30,6 +26,17 @@ int count(std::initializer_list<bool> values)
return count;
}
void showHelp(Option & option){
QString shortOption;
QString longOption = QString("-%1").arg(option.names().last());
if(option.names().size() == 2){
shortOption = QString("-%1").arg(option.names().first());
}
qWarning() << qPrintable(QString("\t%1\t%2\t%3").arg(shortOption, longOption, option.description()));
}
int main(int argc, char * argv[])
{
std::cout
@@ -45,256 +52,201 @@ int main(int argc, char * argv[])
try
{
// some default settings
QString defaultServerAddress = "localhost:19444";
int defaultPriority = 100;
// create the option parser and initialize all parameters
OptionsParser optionParser("Simple application to send a command to hyperion using the Json interface");
ParameterSet & parameters = optionParser.getParameters();
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address" , QString("Set the address of the hyperion server [default: %1]").arg(defaultServerAddress).toLatin1().constData());
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority" , QString("Use to the provided priority channel (the lower the number, the higher the priority) [default: %1]").arg(defaultPriority).toLatin1().constData());
IntParameter & argDuration = parameters.add<IntParameter> ('d', "duration" , "Specify how long the leds should be switched on in millseconds [default: infinity]");
ColorParameter & argColor = parameters.add<ColorParameter> ('c', "color" , "Set all leds to a constant color (either RRGGBB hex value or a color name. The color may be repeated multiple time like: RRGGBBRRGGBB)");
ImageParameter & argImage = parameters.add<ImageParameter> ('i', "image" , "Set the leds to the colors according to the given image file");
StringParameter & argEffect = parameters.add<StringParameter> ('e', "effect" , "Enable the effect with the given name");
StringParameter & argEffectArgs = parameters.add<StringParameter> (0x0, "effectArgs", "Arguments to use in combination with the specified effect. Should be a Json object string.");
SwitchParameter<> & argServerInfo = parameters.add<SwitchParameter<> >('l', "list" , "List server info and active effects with priority and duration");
SwitchParameter<> & argClear = parameters.add<SwitchParameter<> >('x', "clear" , "Clear data for the priority channel provided by the -p option");
SwitchParameter<> & argClearAll = parameters.add<SwitchParameter<> >(0x0, "clearall" , "Clear data for all active priority channels");
StringParameter & argEnableComponent = parameters.add<StringParameter> ('E', "enable" , "Enable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]");
StringParameter & argDisableComponent = parameters.add<StringParameter> ('D', "disable" , "Disable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]");
StringParameter & argId = parameters.add<StringParameter> ('q', "qualifier" , "Identifier(qualifier) of the transform to set");
DoubleParameter & argSaturation = parameters.add<DoubleParameter> ('s', "saturation", "!DEPRECATED! Will be removed soon! Set the HSV saturation gain of the leds");
DoubleParameter & argValue = parameters.add<DoubleParameter> ('v', "value" , "!DEPRECATED! Will be removed soon! Set the HSV value gain of the leds");
DoubleParameter & argSaturationL = parameters.add<DoubleParameter> ('u', "saturationL", "Set the HSL saturation gain of the leds");
DoubleParameter & argLuminance = parameters.add<DoubleParameter> ('m', "luminance" , "Set the HSL luminance gain of the leds");
DoubleParameter & argLuminanceMin= parameters.add<DoubleParameter> ('n', "luminanceMin" , "Set the HSL luminance minimum of the leds (backlight)");
TransformParameter & argGamma = parameters.add<TransformParameter>('g', "gamma" , "Set the gamma of the leds (requires 3 space seperated values)");
TransformParameter & argThreshold = parameters.add<TransformParameter>('t', "threshold" , "Set the threshold of the leds (requires 3 space seperated values between 0.0 and 1.0)");
TransformParameter & argBlacklevel = parameters.add<TransformParameter>('b', "blacklevel", "!DEPRECATED! Will be removed soon! Set the blacklevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
TransformParameter & argWhitelevel = parameters.add<TransformParameter>('w', "whitelevel", "!DEPRECATED! Will be removed soon! Set the whitelevel of the leds (requires 3 space seperated values which are normally between 0.0 and 1.0)");
SwitchParameter<> & argPrint = parameters.add<SwitchParameter<> >(0x0, "print" , "Print the json input and output messages on stdout");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<> >('h', "help" , "Show this help message and exit");
StringParameter & argIdC = parameters.add<StringParameter> ('y', "qualifier" , "!DEPRECATED! Will be removed soon! Identifier(qualifier) of the correction to set");
CorrectionParameter & argCorrection = parameters.add<CorrectionParameter>('Y', "correction" , "!DEPRECATED! Will be removed soon! Set the correction of the leds (requires 3 space seperated values between 0 and 255)");
StringParameter & argIdT = parameters.add<StringParameter> ('z', "qualifier" , "Identifier(qualifier) of the temperature correction to set");
CorrectionParameter & argTemperature= parameters.add<CorrectionParameter>('Z', "temperature" , "Set the temperature correction of the leds (requires 3 space seperated values between 0 and 255)");
StringParameter & argIdA = parameters.add<StringParameter> ('j', "qualifier" , "Identifier(qualifier) of the adjustment to set");
AdjustmentParameter & argRAdjust = parameters.add<AdjustmentParameter>('R', "redAdjustment" , "Set the adjustment of the red color (requires 3 space seperated values between 0 and 255)");
AdjustmentParameter & argGAdjust = parameters.add<AdjustmentParameter>('G', "greenAdjustment", "Set the adjustment of the green color (requires 3 space seperated values between 0 and 255)");
AdjustmentParameter & argBAdjust = parameters.add<AdjustmentParameter>('B', "blueAdjustment", "Set the adjustment of the blue color (requires 3 space seperated values between 0 and 255)");
IntParameter & argSource = parameters.add<IntParameter> (0x0, "sourceSelect" , "Set current active priority channel and deactivate auto source switching");
SwitchParameter<> & argSourceAuto = parameters.add<SwitchParameter<> >(0x0, "sourceAutoSelect", "Enables auto source, if disabled prio by manual selecting input source");
SwitchParameter<> & argSourceOff = parameters.add<SwitchParameter<> >(0x0, "sourceOff", "select no source, this results in leds activly set to black (=off)");
SwitchParameter<> & argConfigGet = parameters.add<SwitchParameter<> >(0x0, "configGet" , "Print the current loaded Hyperion configuration file");
SwitchParameter<> & argSchemaGet = parameters.add<SwitchParameter<> >(0x0, "schemaGet" , "Print the json schema for Hyperion configuration");
StringParameter & argConfigSet = parameters.add<StringParameter>('W', "configSet", "Write to the actual loaded configuration file. Should be a Json object string.");
SwitchParameter<> & argCreate = parameters.add<SwitchParameter<> >(0x0, "createkeys", "Create non exist Json Entry(s) in the actual loaded configuration file. Argument to use in combination with configSet.");
SwitchParameter<> & argOverwriteConfig = parameters.add<SwitchParameter<> >(0x0, "overwrite", "Overwrite the actual loaded configuration file with the Json object string from configSet. Argument to use in combination with configSet.");
Parser parser("Simple application to send a command to hyperion using the Json interface");
// set the default values
argAddress.setDefault(defaultServerAddress.toStdString());
argPriority.setDefault(defaultPriority);
argDuration.setDefault(-1);
argEffectArgs.setDefault("");
Option & argAddress = parser.add<Option> ('a', "address" , "Set the address of the hyperion server [default: %1]", "localhost:19444");
IntOption & argPriority = parser.add<IntOption> ('p', "priority" , "Use to the provided priority channel (the lower the number, the higher the priority) [default: %1]", "100");
IntOption & argDuration = parser.add<IntOption> ('d', "duration" , "Specify how long the leds should be switched on in milliseconds [default: infinity]");
ColorsOption & argColor = parser.add<ColorsOption> ('c', "color" , "Set all leds to a constant color (either RRGGBB hex getColors or a color name. The color may be repeated multiple time like: RRGGBBRRGGBB)");
ImageOption & argImage = parser.add<ImageOption> ('i', "image" , "Set the leds to the colors according to the given image file");
Option & argEffect = parser.add<Option> ('e', "effect" , "Enable the effect with the given name");
Option & argEffectArgs = parser.add<Option> (0x0, "effectArgs", "Arguments to use in combination with the specified effect. Should be a Json object string.", "");
BooleanOption & argServerInfo = parser.add<BooleanOption> ('l', "list" , "List server info and active effects with priority and duration");
BooleanOption & argClear = parser.add<BooleanOption> ('x', "clear" , "Clear data for the priority channel provided by the -p option");
BooleanOption & argClearAll = parser.add<BooleanOption> (0x0, "clearall" , "Clear data for all active priority channels");
Option & argEnableComponent = parser.add<Option> ('E', "enable" , "Enable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]");
Option & argDisableComponent = parser.add<Option> ('D', "disable" , "Disable the Component with the given name. Available Components are [SMOOTHING, BLACKBORDER, KODICHECKER, FORWARDER, UDPLISTENER, BOBLIGHT_SERVER, GRABBER]");
Option & argId = parser.add<Option> ('q', "qualifier" , "Identifier(qualifier) of the transform to set");
DoubleOption & argSaturation = parser.add<DoubleOption> ('s', "saturation", "!DEPRECATED! Will be removed soon! Set the HSV saturation gain of the leds");
DoubleOption & argValue = parser.add<DoubleOption> ('v', "getColors" , "!DEPRECATED! Will be removed soon! Set the HSV getColors gain of the leds");
DoubleOption & argSaturationL = parser.add<DoubleOption> ('u', "saturationL", "Set the HSL saturation gain of the leds");
DoubleOption & argLuminance = parser.add<DoubleOption> ('m', "luminance" , "Set the HSL luminance gain of the leds");
DoubleOption & argLuminanceMin= parser.add<DoubleOption> ('n', "luminanceMin" , "Set the HSL luminance minimum of the leds (backlight)");
ColorOption & argGamma = parser.add<ColorOption>('g', "gamma" , "Set the gamma of the leds (requires colors in hex format as RRGGBB)");
ColorOption & argThreshold = parser.add<ColorOption>('t', "threshold" , "Set the threshold of the leds (requires colors in hex format as RRGGBB)");
ColorOption & argBlacklevel = parser.add<ColorOption>('b', "blacklevel", "!DEPRECATED! Will be removed soon! Set the blacklevel of the leds (requires colors in hex format as RRGGBB which are normally between 0.0 and 1.0)");
ColorOption & argWhitelevel = parser.add<ColorOption>('w', "whitelevel", "!DEPRECATED! Will be removed soon! Set the whitelevel of the leds (requires colors in hex format as RRGGBB which are normally between 0.0 and 1.0)");
BooleanOption & argPrint = parser.add<BooleanOption>(0x0, "print" , "Print the json input and output messages on stdout");
BooleanOption & argHelp = parser.add<BooleanOption>('h', "help" , "Show this help message and exit");
Option & argIdC = parser.add<Option> ('y', "qualifier-c" , "!DEPRECATED! Will be removed soon! Identifier(qualifier) of the correction to set");
ColorOption & argCorrection = parser.add<ColorOption>('Y', "correction" , "!DEPRECATED! Will be removed soon! Set the correction of the leds (requires colors in hex format as RRGGBB)");
Option & argIdT = parser.add<Option> ('z', "qualifier-t" , "Identifier(qualifier) of the temperature correction to set");
ColorOption & argTemperature= parser.add<ColorOption>('Z', "temperature" , "Set the temperature correction of the leds (requires colors in hex format as RRGGBB)");
Option & argIdA = parser.add<Option> ('j', "qualifier-a" , "Identifier(qualifier) of the adjustment to set");
ColorOption & argRAdjust = parser.add<ColorOption>('R', "redAdjustment" , "Set the adjustment of the red color (requires colors in hex format as RRGGBB)");
ColorOption & argGAdjust = parser.add<ColorOption>('G', "greenAdjustment", "Set the adjustment of the green color (requires colors in hex format as RRGGBB)");
ColorOption & argBAdjust = parser.add<ColorOption>('B', "blueAdjustment", "Set the adjustment of the blue color (requires colors in hex format as RRGGBB)");
IntOption & argSource = parser.add<IntOption> (0x0, "sourceSelect" , "Set current active priority channel and deactivate auto source switching");
BooleanOption & argSourceAuto = parser.add<BooleanOption>(0x0, "sourceAutoSelect", "Enables auto source, if disabled prio by manual selecting input source");
BooleanOption & argSourceOff = parser.add<BooleanOption>(0x0, "sourceOff", "select no source, this results in leds activly set to black (=off)");
BooleanOption & argConfigGet = parser.add<BooleanOption>(0x0, "configGet" , "Print the current loaded Hyperion configuration file");
Option & argSchemaGet = parser.add<Option>(0x0, "schemaGet" , "Print the json schema for Hyperion configuration");
Option & argConfigSet = parser.add<Option>('W', "configSet", "Write to the actual loaded configuration file. Should be a Json object string.");
Option & argCreate = parser.add<Option>(0x0, "createkeys", "Create non exist Json Entry(s) in the actual loaded configuration file. Argument to use in combination with configSet.");
Option & argOverwriteConfig = parser.add<Option>(0x0, "overwrite", "Overwrite the actual loaded configuration file with the Json object string from configSet. Argument to use in combination with configSet.");
// parse all options
optionParser.parse(argc, const_cast<const char **>(argv));
// parse all _options
parser.process(app);
// check if we need to display the usage. exit if we do.
if (argHelp.isSet())
if (parser.isSet(argHelp))
{
optionParser.usage();
return 0;
parser.showHelp(0);
}
// check if at least one of the available color transforms is set
bool colorTransform = argSaturation.isSet() || argValue.isSet() || argSaturationL.isSet() || argLuminance.isSet() || argLuminanceMin.isSet() || argThreshold.isSet() || argGamma.isSet() || argBlacklevel.isSet() || argWhitelevel.isSet();
bool colorAdjust = argRAdjust.isSet() || argGAdjust.isSet() || argBAdjust.isSet();
bool colorModding = colorTransform || colorAdjust || argCorrection.isSet() || argTemperature.isSet();
bool colorTransform = parser.isSet(argSaturation) || parser.isSet(argValue) || parser.isSet(argSaturationL) || parser.isSet(argLuminance) || parser.isSet(argLuminanceMin) || parser.isSet(argThreshold) || parser.isSet(argGamma) || parser.isSet(argBlacklevel) || parser.isSet(argWhitelevel);
bool colorAdjust = parser.isSet(argRAdjust) || parser.isSet(argGAdjust) || parser.isSet(argBAdjust);
bool colorModding = colorTransform || colorAdjust || parser.isSet(argCorrection) || parser.isSet(argTemperature);
// check that exactly one command was given
int commandCount = count({
argColor.isSet(), argImage.isSet(), argEffect.isSet(), argServerInfo.isSet(), argClear.isSet(), argClearAll.isSet(), argEnableComponent.isSet(),
argDisableComponent.isSet(), colorModding, argSource.isSet(), argSourceAuto.isSet(), argSourceOff.isSet(), argSchemaGet.isSet(), argConfigGet.isSet(),
argConfigSet.isSet()
});
int commandCount = count({parser.isSet(argColor), parser.isSet(argImage), parser.isSet(argEffect), parser.isSet(argServerInfo), parser.isSet(argClear), parser.isSet(argClearAll), parser.isSet(argEnableComponent), parser.isSet(argDisableComponent), colorModding, parser.isSet(argSource), parser.isSet(argSourceAuto), parser.isSet(argSourceOff), parser.isSet(argConfigGet)});
if (commandCount != 1)
{
std::cerr << (commandCount == 0 ? "No command found." : "Multiple commands found.") << " Provide exactly one of the following options:" << std::endl;
std::cerr << " " << argColor.usageLine() << std::endl;
std::cerr << " " << argImage.usageLine() << std::endl;
std::cerr << " " << argEffect.usageLine() << std::endl;
std::cerr << " " << argServerInfo.usageLine() << std::endl;
std::cerr << " " << argClear.usageLine() << std::endl;
std::cerr << " " << argClearAll.usageLine() << std::endl;
std::cerr << " " << argEnableComponent.usageLine() << std::endl;
std::cerr << " " << argDisableComponent.usageLine() << std::endl;
std::cerr << " " << argSource.usageLine() << std::endl;
std::cerr << " " << argSourceAuto.usageLine() << std::endl;
std::cerr << " " << argConfigGet.usageLine() << std::endl;
std::cerr << " " << argSchemaGet.usageLine() << std::endl;
std::cerr << " " << argConfigSet.usageLine() << std::endl;
std::cerr << "or one or more of the available color modding operations:" << std::endl;
std::cerr << " " << argId.usageLine() << std::endl;
std::cerr << " " << argSaturation.usageLine() << std::endl;
std::cerr << " " << argValue.usageLine() << std::endl;
std::cerr << " " << argSaturationL.usageLine() << std::endl;
std::cerr << " " << argLuminance.usageLine() << std::endl;
std::cerr << " " << argLuminanceMin.usageLine() << std::endl;
std::cerr << " " << argThreshold.usageLine() << std::endl;
std::cerr << " " << argGamma.usageLine() << std::endl;
std::cerr << " " << argBlacklevel.usageLine() << std::endl;
std::cerr << " " << argWhitelevel.usageLine() << std::endl;
std::cerr << " " << argIdC.usageLine() << std::endl;
std::cerr << " " << argCorrection.usageLine() << std::endl;
std::cerr << " " << argIdT.usageLine() << std::endl;
std::cerr << " " << argTemperature.usageLine() << std::endl;
std::cerr << " " << argIdA.usageLine() << std::endl;
std::cerr << " " << argRAdjust.usageLine() << std::endl;
std::cerr << " " << argGAdjust.usageLine() << std::endl;
std::cerr << " " << argBAdjust.usageLine() << std::endl;
qWarning() << (commandCount == 0 ? "No command found." : "Multiple commands found.") << " Provide exactly one of the following options:";
showHelp(argColor);
showHelp(argImage);
showHelp(argEffect);
showHelp(argServerInfo);
showHelp(argClear);
showHelp(argClearAll);
showHelp(argEnableComponent);
showHelp(argDisableComponent);
showHelp(argSource);
showHelp(argSourceAuto);
showHelp(argConfigGet);
qWarning() << "or one or more of the available color modding operations:";
showHelp(argId);
showHelp(argSaturation);
showHelp(argValue);
showHelp(argSaturationL);
showHelp(argLuminance);
showHelp(argLuminanceMin);
showHelp(argThreshold);
showHelp(argGamma);
showHelp(argBlacklevel);
showHelp(argWhitelevel);
showHelp(argIdC);
showHelp(argCorrection);
showHelp(argIdT);
showHelp(argTemperature);
showHelp(argIdA);
showHelp(argRAdjust);
showHelp(argGAdjust);
showHelp(argBAdjust);
return 1;
}
// create the connection to the hyperion server
JsonConnection connection(argAddress.getValue(), argPrint.isSet());
JsonConnection connection(argAddress.value(parser), parser.isSet(argPrint));
// now execute the given command
if (argColor.isSet())
if (parser.isSet(argColor))
{
connection.setColor(argColor.getValue(), argPriority.getValue(), argDuration.getValue());
// TODO: make sure setColor accepts a QList<QColor>
connection.setColor(argColor.getColors(parser).toVector().toStdVector(), argPriority.getInt(parser), argDuration.getInt(parser));
}
else if (argImage.isSet())
else if (parser.isSet(argImage))
{
connection.setImage(argImage.getValue(), argPriority.getValue(), argDuration.getValue());
connection.setImage(argImage.getImage(parser), argPriority.getInt(parser), argDuration.getInt(parser));
}
else if (argEffect.isSet())
{
connection.setEffect(argEffect.getValue(), argEffectArgs.getValue(), argPriority.getValue(), argDuration.getValue());
}
else if (argServerInfo.isSet())
else if (parser.isSet(argEffect))
{
connection.setEffect(argEffect.value(parser), argEffectArgs.value(parser), argPriority.getInt(parser), argDuration.getInt(parser));
}
else if (parser.isSet(argServerInfo))
{
QString info = connection.getServerInfo();
std::cout << "Server info:\n" << info.toStdString() << std::endl;
}
else if (argClear.isSet())
else if (parser.isSet(argClear))
{
connection.clear(argPriority.getValue());
connection.clear(argPriority.getInt(parser));
}
else if (argClearAll.isSet())
else if (parser.isSet(argClearAll))
{
connection.clearAll();
}
else if (argEnableComponent.isSet())
else if (parser.isSet(argEnableComponent))
{
connection.setComponentState(argEnableComponent.getValue(), true);
connection.setComponentState(argEnableComponent.value(parser), true);
}
else if (argDisableComponent.isSet())
else if (parser.isSet(argDisableComponent))
{
connection.setComponentState(argDisableComponent.getValue(), false);
connection.setComponentState(argDisableComponent.value(parser), false);
}
else if (argSourceOff.isSet())
else if (parser.isSet(argSourceOff))
{
connection.setSource(std::numeric_limits<int>::max());
}
else if (argSource.isSet())
else if (parser.isSet(argSource))
{
connection.setSource(argSource.getValue());
connection.setSource(argSource.getInt(parser));
}
else if (argSourceAuto.isSet())
else if (parser.isSet(argSourceAuto))
{
connection.setSourceAutoSelect();
}
else if (argConfigGet.isSet())
else if (parser.isSet(argConfigGet))
{
QString info = connection.getConfig("config");
std::cout << "Configuration:\n" << info.toStdString() << std::endl;
}
else if (argSchemaGet.isSet())
else if (parser.isSet(argSchemaGet))
{
QString info = connection.getConfig("schema");
std::cout << "Configuration Schema\n" << info.toStdString() << std::endl;
}
else if (argConfigSet.isSet())
else if (parser.isSet(argConfigSet))
{
connection.setConfig(argConfigSet.getValue(), argCreate.isSet(), argOverwriteConfig.isSet());
connection.setConfig(argConfigSet.value(parser), parser.isSet(argCreate), parser.isSet(argOverwriteConfig));
}
else if (colorModding)
{
if (argCorrection.isSet())
if (parser.isSet(argCorrection))
{
std::string corrId;
ColorCorrectionValues correction;
if (argIdC.isSet()) corrId = argIdC.getValue();
if (argCorrection.isSet()) correction = argCorrection.getValue();
connection.setTemperature(
argIdC.isSet() ? &corrId : nullptr,
argCorrection.isSet() ? &correction : nullptr);
connection.setTemperature(argIdC.value(parser), argCorrection.getColor(parser));
}
if (argTemperature.isSet())
if (parser.isSet(argTemperature))
{
std::string tempId;
ColorCorrectionValues temperature;
if (argIdT.isSet()) tempId = argIdT.getValue();
if (argTemperature.isSet()) temperature = argTemperature.getValue();
connection.setTemperature(
argIdT.isSet() ? &tempId : nullptr,
argTemperature.isSet() ? &temperature : nullptr);
connection.setTemperature(argIdT.value(parser), argTemperature.getColor(parser));
}
if (colorAdjust)
{
std::string adjustId;
ColorAdjustmentValues redChannel, greenChannel, blueChannel;
if (argIdA.isSet()) adjustId = argIdA.getValue();
if (argRAdjust.isSet()) redChannel = argRAdjust.getValue();
if (argGAdjust.isSet()) greenChannel = argGAdjust.getValue();
if (argBAdjust.isSet()) blueChannel = argBAdjust.getValue();
connection.setAdjustment(
argIdA.isSet() ? &adjustId : nullptr,
argRAdjust.isSet() ? &redChannel : nullptr,
argGAdjust.isSet() ? &greenChannel : nullptr,
argBAdjust.isSet() ? &blueChannel : nullptr);
argIdA.value(parser),
argRAdjust.getColor(parser),
argGAdjust.getColor(parser),
argBAdjust.getColor(parser)
);
}
if (colorTransform)
{
std::string transId;
double saturation, value, saturationL, luminance, luminanceMin;
ColorTransformValues threshold, gamma, blacklevel, whitelevel;
if (argId.isSet()) transId = argId.getValue();
if (argSaturation.isSet()) saturation = argSaturation.getValue();
if (argValue.isSet()) value = argValue.getValue();
if (argSaturationL.isSet()) saturationL = argSaturationL.getValue();
if (argLuminance.isSet()) luminance = argLuminance.getValue();
if (argLuminanceMin.isSet()) luminanceMin = argLuminanceMin.getValue();
if (argThreshold.isSet()) threshold = argThreshold.getValue();
if (argGamma.isSet()) gamma = argGamma.getValue();
if (argBlacklevel.isSet()) blacklevel = argBlacklevel.getValue();
if (argWhitelevel.isSet()) whitelevel = argWhitelevel.getValue();
connection.setTransform(
argId.isSet() ? &transId : nullptr,
argSaturation.isSet() ? &saturation : nullptr,
argValue.isSet() ? &value : nullptr,
argSaturationL.isSet() ? &saturationL : nullptr,
argLuminance.isSet() ? &luminance : nullptr,
argLuminanceMin.isSet() ? &luminanceMin : nullptr,
argThreshold.isSet() ? &threshold : nullptr,
argGamma.isSet() ? &gamma : nullptr,
argBlacklevel.isSet() ? &blacklevel : nullptr,
argWhitelevel.isSet() ? &whitelevel : nullptr);
argId.value(parser),
argSaturation.getDoublePtr(parser),
argValue.getDoublePtr(parser),
argSaturationL.getDoublePtr(parser),
argLuminance.getDoublePtr(parser),
argLuminanceMin.getDoublePtr(parser),
argThreshold.getColor(parser),
argGamma.getColor(parser),
argBlacklevel.getColor(parser),
argWhitelevel.getColor(parser));
}
}
}

View File

@@ -15,8 +15,6 @@ set(Hyperion_V4L2_QT_HEADERS
)
set(Hyperion_V4L2_HEADERS
VideoStandardParameter.h
PixelFormatParameter.h
)
set(Hyperion_V4L2_SOURCES
@@ -35,7 +33,7 @@ add_executable(${PROJECT_NAME}
target_link_libraries(${PROJECT_NAME}
v4l2-grabber
getoptPlusPlus
commandline
blackborder
hyperion-utils
protoserver

View File

@@ -1,43 +0,0 @@
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
// grabber includes
#include <utils/PixelFormat.h>
using namespace vlofgren;
/// Data parameter for the pixel format
typedef vlofgren::PODParameter<PixelFormat> PixelFormatParameter;
namespace vlofgren {
/// Translates a string (as passed on the commandline) to a pixel format
///
/// @param[in] s The string (as passed on the commandline)
/// @return The pixel format
/// @throws Parameter::ParameterRejected If the string did not result in a pixel format
template<>
PixelFormat PixelFormatParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
{
QString input = QString::fromStdString(s).toLower();
if (input == "yuyv")
{
return PIXELFORMAT_YUYV;
}
else if (input == "uyvy")
{
return PIXELFORMAT_UYVY;
}
else if (input == "rgb32")
{
return PIXELFORMAT_RGB32;
}
else if (input == "no-change")
{
return PIXELFORMAT_NO_CHANGE;
}
throw Parameter::ParameterRejected("Invalid value for pixel format. Valid values are: YUYV, UYVY, RGB32, and NO-CHANGE");
return PIXELFORMAT_NO_CHANGE;
}
}

View File

@@ -5,7 +5,7 @@
// hyperion-v4l2 includes
#include "ScreenshotHandler.h"
ScreenshotHandler::ScreenshotHandler(const std::string & filename) :
ScreenshotHandler::ScreenshotHandler(const QString & filename) :
_filename(filename)
{
}
@@ -18,7 +18,7 @@ void ScreenshotHandler::receiveImage(const Image<ColorRgb> & image)
{
// store as PNG
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
pngImage.save(_filename.c_str());
pngImage.save(_filename);
// Quit the application after the first image
QCoreApplication::quit();

View File

@@ -11,7 +11,7 @@ class ScreenshotHandler : public QObject
Q_OBJECT
public:
ScreenshotHandler(const std::string & filename);
ScreenshotHandler(const QString & filename);
virtual ~ScreenshotHandler();
public slots:
@@ -20,5 +20,5 @@ public slots:
void receiveImage(const Image<ColorRgb> & image);
private:
const std::string _filename;
const QString _filename;
};

View File

@@ -1,39 +0,0 @@
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
// grabber includes
#include <grabber/VideoStandard.h>
using namespace vlofgren;
/// Data parameter for the video standard
typedef vlofgren::PODParameter<VideoStandard> VideoStandardParameter;
namespace vlofgren {
/// Translates a string (as passed on the commandline) to a color standard
///
/// @param[in] s The string (as passed on the commandline)
/// @return The color standard
/// @throws Parameter::ParameterRejected If the string did not result in a video standard
template<>
VideoStandard VideoStandardParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
{
QString input = QString::fromStdString(s).toLower();
if (input == "pal")
{
return VIDEOSTANDARD_PAL;
}
else if (input == "ntsc")
{
return VIDEOSTANDARD_NTSC;
}
else if (input == "no-change")
{
return VIDEOSTANDARD_NO_CHANGE;
}
throw Parameter::ParameterRejected("Invalid value for video standard. Valid values are: PAL, NTSC, and NO-CHANGE");
return VIDEOSTANDARD_NO_CHANGE;
}
}

View File

@@ -6,9 +6,6 @@
// QT includes
#include <QCoreApplication>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
// blackborder includes
#include <blackborder/BlackBorderProcessor.h>
@@ -20,20 +17,19 @@
#include "protoserver/ProtoConnectionWrapper.h"
// hyperion-v4l2 includes
#include "VideoStandardParameter.h"
#include "PixelFormatParameter.h"
#include "ScreenshotHandler.h"
#include "HyperionConfig.h"
#include <commandline/Parser.h>
using namespace vlofgren;
using namespace commandline;
// save the image as screenshot
void saveScreenshot(void *, const Image<ColorRgb> & image)
void saveScreenshot(QString filename, const Image<ColorRgb> & image)
{
// store as PNG
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
pngImage.save("screenshot.png");
pngImage.save(filename);
}
int main(int argc, char** argv)
@@ -55,104 +51,90 @@ int main(int argc, char** argv)
try
{
// create the option parser and initialize all parameters
OptionsParser optionParser("V4L capture application for Hyperion");
ParameterSet & parameters = optionParser.getParameters();
Parser parser("V4L capture application for Hyperion");
StringParameter & argDevice = parameters.add<StringParameter> ('d', "device", "The device to use [default: /dev/video0]");
VideoStandardParameter & argVideoStandard = parameters.add<VideoStandardParameter>('v', "video-standard", "The used video standard. Valid values are PAL or NTSC (optional)");
PixelFormatParameter & argPixelFormat = parameters.add<PixelFormatParameter> (0x0, "pixel-format", "The use pixel format. Valid values are YUYV, UYVY, and RGB32 (optional)");
IntParameter & argInput = parameters.add<IntParameter> (0x0, "input", "Input channel (optional)");
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Try to set the width of the video input (optional)");
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "Try to set the height of the video input (optional)");
IntParameter & argCropWidth = parameters.add<IntParameter> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: 0]");
IntParameter & argCropHeight = parameters.add<IntParameter> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: 0]");
IntParameter & argCropLeft = parameters.add<IntParameter> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
IntParameter & argCropRight = parameters.add<IntParameter> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
IntParameter & argCropTop = parameters.add<IntParameter> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
IntParameter & argCropBottom = parameters.add<IntParameter> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=1]");
IntParameter & argFrameDecimation = parameters.add<IntParameter> ('f', "frame-decimator", "Decimation factor for the video frames [default=1]");
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
DoubleParameter & argSignalThreshold = parameters.add<DoubleParameter> ('t', "signal-threshold", "The signal threshold for detecting the presence of a signal. Value should be between 0.0 and 1.0.");
DoubleParameter & argRedSignalThreshold = parameters.add<DoubleParameter> (0x0, "red-threshold", "The red signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
DoubleParameter & argGreenSignalThreshold = parameters.add<DoubleParameter> (0x0, "green-threshold", "The green signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
DoubleParameter & argBlueSignalThreshold = parameters.add<DoubleParameter> (0x0, "blue-threshold", "The blue signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
SwitchParameter<> & arg3DSBS = parameters.add<SwitchParameter<>> (0x0, "3DSBS", "Interpret the incoming video stream as 3D side-by-side");
SwitchParameter<> & arg3DTAB = parameters.add<SwitchParameter<>> (0x0, "3DTAB", "Interpret the incoming video stream as 3D top-and-bottom");
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
Option & argDevice = parser.add<Option> ('d', "device", "The device to use [default: %1]", "/dev/video0");
SwitchOption<VideoStandard> & argVideoStandard = parser.add<SwitchOption<VideoStandard>>('v', "video-standard", "The used video standard. Valid values are PAL, NTSC or no-change. [default: %1]", "no-change");
SwitchOption<PixelFormat> & argPixelFormat = parser.add<SwitchOption<PixelFormat>> (0x0, "pixel-format", "The use pixel format. Valid values are YUYV, UYVY, RGB32 or no-change. [default: %1]", "no-change");
IntOption & argInput = parser.add<IntOption> (0x0, "input", "Input channel (optional)", "-1");
IntOption & argWidth = parser.add<IntOption> (0x0, "width", "Try to set the width of the video input [default: %1]", "-1");
IntOption & argHeight = parser.add<IntOption> (0x0, "height", "Try to set the height of the video input [default: %1]", "-1");
IntOption & argCropWidth = parser.add<IntOption> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: %1]", "0");
IntOption & argCropHeight = parser.add<IntOption> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: %1]", "0");
IntOption & argCropLeft = parser.add<IntOption> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
IntOption & argCropRight = parser.add<IntOption> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
IntOption & argCropTop = parser.add<IntOption> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
IntOption & argCropBottom = parser.add<IntOption> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
IntOption & argSizeDecimation = parser.add<IntOption> ('s', "size-decimator", "Decimation factor for the output size [default=%1]", "1");
IntOption & argFrameDecimation = parser.add<IntOption> ('f', "frame-decimator", "Decimation factor for the video frames [default=%1]", "1");
BooleanOption & argScreenshot = parser.add<BooleanOption> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
DoubleOption & argSignalThreshold = parser.add<DoubleOption> ('t', "signal-threshold", "The signal threshold for detecting the presence of a signal. Value should be between 0.0 and 1.0.", QString(), 0.0, 1.0);
DoubleOption & argRedSignalThreshold = parser.add<DoubleOption> (0x0, "red-threshold", "The red signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
DoubleOption & argGreenSignalThreshold = parser.add<DoubleOption> (0x0, "green-threshold", "The green signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
DoubleOption & argBlueSignalThreshold = parser.add<DoubleOption> (0x0, "blue-threshold", "The blue signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
BooleanOption & arg3DSBS = parser.add<BooleanOption> (0x0, "3DSBS", "Interpret the incoming video stream as 3D side-by-side");
BooleanOption & arg3DTAB = parser.add<BooleanOption> (0x0, "3DTAB", "Interpret the incoming video stream as 3D top-and-bottom");
Option & argAddress = parser.add<Option> ('a', "address", "Set the address of the hyperion server [default: %1]", "127.0.0.1:19445");
IntOption & argPriority = parser.add<IntOption> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: %1]", "800");
BooleanOption & argSkipReply = parser.add<BooleanOption> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
BooleanOption & argHelp = parser.add<BooleanOption> ('h', "help", "Show this help message and exit");
// set defaults
argDevice.setDefault("/dev/video0");
argVideoStandard.setDefault(VIDEOSTANDARD_NO_CHANGE);
argPixelFormat.setDefault(PIXELFORMAT_NO_CHANGE);
argInput.setDefault(-1);
argWidth.setDefault(-1);
argHeight.setDefault(-1);
argCropWidth.setDefault(0);
argCropHeight.setDefault(0);
argSizeDecimation.setDefault(1);
argFrameDecimation.setDefault(1);
argAddress.setDefault("127.0.0.1:19445");
argPriority.setDefault(800);
argSignalThreshold.setDefault(-1);
argVideoStandard.addSwitch("pal", VIDEOSTANDARD_PAL);
argVideoStandard.addSwitch("ntsc", VIDEOSTANDARD_NTSC);
argVideoStandard.addSwitch("no-change", VIDEOSTANDARD_NO_CHANGE);
argPixelFormat.addSwitch("yuyv", PIXELFORMAT_YUYV);
argPixelFormat.addSwitch("uyvy", PIXELFORMAT_UYVY);
argPixelFormat.addSwitch("rgb32", PIXELFORMAT_RGB32);
argPixelFormat.addSwitch("no-change", PIXELFORMAT_NO_CHANGE);
// parse all options
optionParser.parse(argc, const_cast<const char **>(argv));
parser.process(app);
// check if we need to display the usage. exit if we do.
if (argHelp.isSet())
if (parser.isSet(argHelp))
{
optionParser.usage();
return 0;
parser.showHelp(0);
}
// cropping values if not defined
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());
// initialize the grabber
V4L2Grabber grabber(
argDevice.getValue(),
argInput.getValue(),
argVideoStandard.getValue(),
argPixelFormat.getValue(),
argWidth.getValue(),
argHeight.getValue(),
std::max(1, argFrameDecimation.getValue()),
std::max(1, argSizeDecimation.getValue()),
std::max(1, argSizeDecimation.getValue()));
argDevice.getStdString(parser),
argInput.getInt(parser),
argVideoStandard.switchValue(parser),
argPixelFormat.switchValue(parser),
argWidth.getInt(parser),
argHeight.getInt(parser),
std::max(1, argFrameDecimation.getInt(parser)),
std::max(1, argSizeDecimation.getInt(parser)),
std::max(1, argSizeDecimation.getInt(parser)));
// set signal detection
grabber.setSignalThreshold(
std::min(1.0, std::max(0.0, argRedSignalThreshold.isSet() ? argRedSignalThreshold.getValue() : argSignalThreshold.getValue())),
std::min(1.0, std::max(0.0, argGreenSignalThreshold.isSet() ? argGreenSignalThreshold.getValue() : argSignalThreshold.getValue())),
std::min(1.0, std::max(0.0, argBlueSignalThreshold.isSet() ? argBlueSignalThreshold.getValue() : argSignalThreshold.getValue())),
std::min(1.0, std::max(0.0, parser.isSet(argRedSignalThreshold) ? argRedSignalThreshold.getDouble(parser) : argSignalThreshold.getDouble(parser))),
std::min(1.0, std::max(0.0, parser.isSet(argGreenSignalThreshold) ? argGreenSignalThreshold.getDouble(parser) : argSignalThreshold.getDouble(parser))),
std::min(1.0, std::max(0.0, parser.isSet(argBlueSignalThreshold) ? argBlueSignalThreshold.getDouble(parser) : argSignalThreshold.getDouble(parser))),
50);
// set cropping values
grabber.setCropping(
std::max(0, argCropLeft.getValue()),
std::max(0, argCropRight.getValue()),
std::max(0, argCropTop.getValue()),
std::max(0, argCropBottom.getValue()));
parser.isSet(argCropLeft) ? argCropLeft.getInt(parser) : argCropWidth.getInt(parser),
parser.isSet(argCropRight) ? argCropRight.getInt(parser) : argCropWidth.getInt(parser),
parser.isSet(argCropTop) ? argCropTop.getInt(parser) : argCropHeight.getInt(parser),
parser.isSet(argCropBottom) ? argCropBottom.getInt(parser) : argCropHeight.getInt(parser));
// set 3D mode if applicable
if (arg3DSBS.isSet())
if (parser.isSet(arg3DSBS))
{
grabber.set3D(VIDEO_3DSBS);
}
else if (arg3DTAB.isSet())
else if (parser.isSet(arg3DTAB))
{
grabber.set3D(VIDEO_3DTAB);
}
// run the grabber
if (argScreenshot.isSet())
if (parser.isSet(argScreenshot))
{
ScreenshotHandler handler("screenshot.png");
QObject::connect(&grabber, SIGNAL(newFrame(Image<ColorRgb>)), &handler, SLOT(receiveImage(Image<ColorRgb>)));
@@ -162,8 +144,8 @@ int main(int argc, char** argv)
}
else
{
ProtoConnectionWrapper handler(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
QObject::connect(&grabber, SIGNAL(newFrame(Image<ColorRgb>)), &handler, SLOT(receiveImage(Image<ColorRgb>)));
ProtoConnectionWrapper protoWrapper(argAddress.value(parser), argPriority.getInt(parser), 1000, parser.isSet(argSkipReply));
QObject::connect(&grabber, SIGNAL(newFrame(Image<ColorRgb>)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));
if (grabber.start())
QCoreApplication::exec();
grabber.stop();

View File

@@ -31,8 +31,8 @@ add_executable(${PROJECT_NAME}
)
target_link_libraries(${PROJECT_NAME}
getoptPlusPlus
blackborder
commandline
hyperion-utils
protoserver
x11-grabber

View File

@@ -3,17 +3,15 @@
#include <QCoreApplication>
#include <QImage>
// getoptPlusPLus includes
#include <getoptPlusPlus/getoptpp.h>
#include <commandline/Parser.h>
#include "protoserver/ProtoConnectionWrapper.h"
#include "X11Wrapper.h"
#include "HyperionConfig.h"
using namespace vlofgren;
using namespace commandline;
// save the image as screenshot
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
void saveScreenshot(QString filename, const Image<ColorRgb> & image)
{
// store as PNG
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
@@ -32,65 +30,47 @@ int main(int argc, char ** argv)
try
{
// create the option parser and initialize all parameters
OptionsParser optionParser("X11 capture application for Hyperion");
ParameterSet & parameters = optionParser.getParameters();
Parser parser("X11 capture application for Hyperion");
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Capture frame rate [default: 10]");
SwitchParameter<> & argXGetImage = parameters.add<SwitchParameter<>> ('x', "xgetimage", "Use XGetImage instead of XRender");
IntParameter & argCropWidth = parameters.add<IntParameter> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: 0]");
IntParameter & argCropHeight = parameters.add<IntParameter> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: 0]");
IntParameter & argCropLeft = parameters.add<IntParameter> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
IntParameter & argCropRight = parameters.add<IntParameter> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
IntParameter & argCropTop = parameters.add<IntParameter> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
IntParameter & argCropBottom = parameters.add<IntParameter> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=8]");
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
// set defaults
argFps.setDefault(10);
argCropWidth.setDefault(0);
argCropHeight.setDefault(0);
argSizeDecimation.setDefault(8);
argAddress.setDefault("127.0.0.1:19445");
argPriority.setDefault(800);
IntOption & argFps = parser.add<IntOption> ('f', "framerate", "Capture frame rate [default: %1]", "10");
BooleanOption & argXGetImage = parser.add<BooleanOption> ('x', "xgetimage", "Use XGetImage instead of XRender");
IntOption & argCropWidth = parser.add<IntOption> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: %1]", "0");
IntOption & argCropHeight = parser.add<IntOption> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: %1]", "0");
IntOption & argCropLeft = parser.add<IntOption> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
IntOption & argCropRight = parser.add<IntOption> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
IntOption & argCropTop = parser.add<IntOption> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
IntOption & argCropBottom = parser.add<IntOption> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
IntOption & argSizeDecimation = parser.add<IntOption> ('s', "size-decimator", "Decimation factor for the output size [default=%1]", "8");
BooleanOption & argScreenshot = parser.add<BooleanOption> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
Option & argAddress = parser.add<Option> ('a', "address", "Set the address of the hyperion server [default: %1]", "127.0.0.1:19445");
IntOption & argPriority = parser.add<IntOption> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: %1]", "800");
BooleanOption & argSkipReply = parser.add<BooleanOption> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
BooleanOption & argHelp = parser.add<BooleanOption> ('h', "help", "Show this help message and exit");
// parse all options
optionParser.parse(argc, const_cast<const char **>(argv));
parser.process(app);
// check if we need to display the usage. exit if we do.
if (argHelp.isSet())
if (parser.isSet(argHelp))
{
optionParser.usage();
return 0;
parser.showHelp(0);
}
// cropping values if not defined
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());
// Create the X11 grabbing stuff
int grabInterval = 1000 / argFps.getValue();
bool useXGetImage = argXGetImage.isSet();
X11Wrapper x11Wrapper(
grabInterval,
useXGetImage,
argCropLeft.getValue(),
argCropRight.getValue(),
argCropTop.getValue(),
argCropBottom.getValue(),
argSizeDecimation.getValue(), // horizontal decimation
argSizeDecimation.getValue()); // vertical decimation
1000 / argFps.getInt(parser),
parser.isSet(argXGetImage),
parser.isSet(argCropLeft) ? argCropLeft.getInt(parser) : argCropWidth.getInt(parser),
parser.isSet(argCropRight) ? argCropRight.getInt(parser) : argCropWidth.getInt(parser),
parser.isSet(argCropTop) ? argCropTop.getInt(parser) : argCropHeight.getInt(parser),
parser.isSet(argCropBottom) ? argCropBottom.getInt(parser) : argCropHeight.getInt(parser),
argSizeDecimation.getInt(parser), // horizontal decimation
argSizeDecimation.getInt(parser)); // vertical decimation
if (!x11Wrapper.displayInit())
return -1;
if (argScreenshot.isSet())
if (parser.isSet(argScreenshot))
{
// Capture a single screenshot and finish
const Image<ColorRgb> & screenshot = x11Wrapper.getScreenshot();
@@ -99,7 +79,7 @@ int main(int argc, char ** argv)
else
{
// Create the Proto-connection with hyperiond
ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
ProtoConnectionWrapper protoWrapper(argAddress.value(parser), argPriority.getInt(parser), 1000, parser.isSet(argSkipReply));
// Connect the screen capturing to the proto processing
QObject::connect(&x11Wrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));

View File

@@ -3,7 +3,7 @@ add_executable(hyperiond
hyperiond.cpp hyperiond.h main.cpp)
target_link_libraries(hyperiond
getoptPlusPlus
commandline
hyperion
kodivideochecker
effectengine

View File

@@ -43,7 +43,9 @@ HyperionDaemon::HyperionDaemon(QString configFile, QObject *parent)
, _udpListener(nullptr)
, _v4l2Grabber(nullptr)
, _dispmanx(nullptr)
#ifdef ENABLE_X11
, _x11Grabber(nullptr)
#endif
, _amlGrabber(nullptr)
, _fbGrabber(nullptr)
, _osxGrabber(nullptr)

View File

@@ -81,7 +81,9 @@ private:
UDPListener* _udpListener;
V4L2Wrapper* _v4l2Grabber;
DispmanxWrapper* _dispmanx;
#ifdef ENABLE_X11
X11Wrapper* _x11Grabber;
#endif
AmlogicWrapper* _amlGrabber;
FramebufferWrapper* _fbGrabber;
OsxWrapper* _osxGrabber;

View File

@@ -16,13 +16,14 @@
#include "HyperionConfig.h"
#include <getoptPlusPlus/getoptpp.h>
#include <utils/Logger.h>
#include <webconfig/WebConfig.h>
#include <commandline/Parser.h>
#include <commandline/IntOption.h>
#include "hyperiond.h"
using namespace vlofgren;
using namespace commandline;
void signal_handler(const int signum)
{
@@ -62,34 +63,34 @@ int main(int argc, char** argv)
setlocale(LC_ALL, "C");
QLocale::setDefault(QLocale::c());
OptionsParser optionParser("Hyperion Daemon");
ParameterSet & parameters = optionParser.getParameters();
Parser parser("Hyperion Daemon");
parser.addHelpOption();
SwitchParameter<> & argVersion = parameters.add<SwitchParameter<>> (0x0, "version", "Show version information");
IntParameter & argParentPid = parameters.add<IntParameter> (0x0, "parent", "pid of parent hyperiond");
SwitchParameter<> & argSilent = parameters.add<SwitchParameter<>> (0x0, "silent", "do not print any outputs");
SwitchParameter<> & argVerbose = parameters.add<SwitchParameter<>> (0x0, "verbose", "Increase verbosity");
SwitchParameter<> & argDebug = parameters.add<SwitchParameter<>> (0x0, "debug", "Show debug messages");
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
BooleanOption & versionOption = parser.add<BooleanOption>(0x0, "version", "Show version information");
IntOption & parentOption = parser.add<IntOption>('p', "parent", "pid of parent hyperiond"); // 2^22 is the max for Linux
BooleanOption & silentOption = parser.add<BooleanOption>('s', "silent", "do not print any outputs");
BooleanOption & verboseOption = parser.add<BooleanOption>('v', "verbose", "Increase verbosity");
BooleanOption & debugOption = parser.add<BooleanOption>('d', "debug", "Show debug messages");
parser.addPositionalArgument("config-files", QCoreApplication::translate("main", "Configuration files"), "[files...]");
argParentPid.setDefault(0);
optionParser.parse(argc, const_cast<const char **>(argv));
const std::vector<std::string> configFiles = optionParser.getFiles();
parser.process(app);
const QStringList configFiles = parser.positionalArguments();
int logLevelCheck = 0;
if (argSilent.isSet())
if (parser.isSet(silentOption))
{
Logger::setLogLevel(Logger::OFF);
logLevelCheck++;
}
if (argVerbose.isSet())
if (parser.isSet(verboseOption))
{
Logger::setLogLevel(Logger::INFO);
logLevelCheck++;
}
if (argDebug.isSet())
if (parser.isSet(debugOption))
{
Logger::setLogLevel(Logger::DEBUG);
logLevelCheck++;
@@ -100,15 +101,8 @@ int main(int argc, char** argv)
Error(log, "aborting, because options --silent --verbose --debug can't used together");
return 0;
}
// check if we need to display the usage. exit if we do.
if (argHelp.isSet())
{
optionParser.usage();
return 0;
}
if (argVersion.isSet())
if (parser.isSet(versionOption))
{
std::cout
<< "Hyperion Ambilight Deamon (" << getpid() << ")" << std::endl
@@ -124,24 +118,25 @@ int main(int argc, char** argv)
return 1;
}
if (argParentPid.getValue() > 0 )
int parentPid = parser.value(parentOption).toInt();
if (parentPid > 0 )
{
Info(log, "hyperiond client, parent is pid %d",argParentPid.getValue());
Info(log, "hyperiond client, parent is pid %d", parentPid);
#ifndef __APPLE__
prctl(PR_SET_PDEATHSIG, SIGHUP);
#endif
}
int argvId = -1;
for(size_t idx=0; idx < configFiles.size(); idx++) {
if ( QFile::exists(configFiles[idx].c_str()))
for(int idx=0; idx < configFiles.size(); idx++) {
if ( QFile::exists(configFiles[idx]))
{
if (argvId < 0) argvId=idx;
else startNewHyperion(getpid(), argv[0], configFiles[idx].c_str());
else startNewHyperion(getpid(), argv[0], configFiles[idx].toStdString());
}
}
if ( argvId < 0)
{
Error(log, "No valid config found");
@@ -151,7 +146,7 @@ int main(int argc, char** argv)
HyperionDaemon* hyperiond = nullptr;
try
{
hyperiond = new HyperionDaemon(QString::fromStdString(configFiles[argvId]), &app);
hyperiond = new HyperionDaemon(configFiles[argvId], &app);
hyperiond->run();
}
catch (std::exception& e)