mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Added simple direct implementation of the frame-grabber using dispmanx (copied from https://github.com/brooc/boblight-rpi/tree/master/src/clients/boblight-dispmanx)
This commit is contained in:
parent
8748437901
commit
a695ab91bb
@ -29,8 +29,8 @@ set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so")
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall")
|
||||||
|
|
||||||
configure_file(bin/install_hyperion.sh ${LIBRARY_OUTPUT_PATH} @ONLY)
|
configure_file(bin/install_hyperion.sh ${LIBRARY_OUTPUT_PATH} @ONLY)
|
||||||
configure_file(config/Hyperion.config.json ${LIBRARY_OUTPUT_PATH} @ONLY)
|
configure_file(config/hyperion.config.json ${LIBRARY_OUTPUT_PATH} @ONLY)
|
||||||
configure_file(config/Hyperion.schema.json ${LIBRARY_OUTPUT_PATH} @ONLY)
|
configure_file(config/hyperion.schema.json ${LIBRARY_OUTPUT_PATH} @ONLY)
|
||||||
|
|
||||||
# Add the source/lib directories
|
# Add the source/lib directories
|
||||||
add_subdirectory(dependencies)
|
add_subdirectory(dependencies)
|
||||||
|
@ -20,7 +20,8 @@ inline Hyperion* rasp_cast(void* hyperion_ptr)
|
|||||||
|
|
||||||
void* boblight_init()
|
void* boblight_init()
|
||||||
{
|
{
|
||||||
syslog(LOG_INFO, __PRETTY_FUNCTION__);
|
std::cout << __PRETTY_FUNCTION__ << std::endl;
|
||||||
|
// syslog(LOG_INFO, __PRETTY_FUNCTION__);
|
||||||
|
|
||||||
const char* homeDir = getenv("RASPILIGHT_HOME");
|
const char* homeDir = getenv("RASPILIGHT_HOME");
|
||||||
if (!homeDir)
|
if (!homeDir)
|
||||||
@ -83,6 +84,7 @@ int boblight_sendrgb(void* hyperion_ptr, int sync, int* outputused)
|
|||||||
|
|
||||||
int boblight_connect(void* hyperion_ptr, const char* address, int port, int usectimeout)
|
int boblight_connect(void* hyperion_ptr, const char* address, int port, int usectimeout)
|
||||||
{
|
{
|
||||||
|
std::cout << "SUCCESFULL NO CONNECTION WITH BOBLIGHT" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +95,7 @@ const char* boblight_geterror(void* hyperion_ptr)
|
|||||||
|
|
||||||
int boblight_setpriority(void* hyperion_ptr, int priority)
|
int boblight_setpriority(void* hyperion_ptr, int priority)
|
||||||
{
|
{
|
||||||
|
std::cout << __PRETTY_FUNCTION__ << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,20 +65,21 @@ void Hyperion::setInputSize(const unsigned width, const unsigned height)
|
|||||||
void Hyperion::commit()
|
void Hyperion::commit()
|
||||||
{
|
{
|
||||||
// Derive the color per led
|
// Derive the color per led
|
||||||
const std::vector<RgbColor> ledColors = mLedsMap.getMedianLedColor();
|
std::vector<RgbColor> ledColors = mLedsMap.getMeanLedColor();
|
||||||
|
// const std::vector<RgbColor> ledColors = mLedsMap.getMedianLedColor();
|
||||||
|
|
||||||
// Write the Led colors to the led-string
|
// Write the Led colors to the led-string
|
||||||
mDevice->write(ledColors);
|
mDevice->write(ledColors);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Hyperion::operator() (const RgbImage& inputImage)
|
void Hyperion::operator() (const RgbImage& inputImage)
|
||||||
{
|
{
|
||||||
std::cout << "Cached image size: [" << mImage->width() << "x" << mImage->height() << "]. Input image size: [" << inputImage.width() << "x" << inputImage.height() << "]" << std::endl;
|
|
||||||
// Copy the input-image into the buffer
|
// Copy the input-image into the buffer
|
||||||
mImage->copy(inputImage);
|
mImage->copy(inputImage);
|
||||||
|
|
||||||
// Derive the color per led
|
// Derive the color per led
|
||||||
// std::vector<RgbColor> ledColors = mLedsMap.getMeanLedColor();
|
std::vector<RgbColor> ledColors = mLedsMap.getMeanLedColor();
|
||||||
std::vector<RgbColor> ledColors = mLedsMap.getMedianLedColor();
|
// std::vector<RgbColor> ledColors = mLedsMap.getMedianLedColor();
|
||||||
applyTransform(ledColors);
|
applyTransform(ledColors);
|
||||||
|
|
||||||
// Write the Led colors to the led-string
|
// Write the Led colors to the led-string
|
||||||
|
@ -42,3 +42,37 @@ add_executable(Test2BobLight
|
|||||||
|
|
||||||
target_link_libraries(Test2BobLight
|
target_link_libraries(Test2BobLight
|
||||||
bob2hyperion)
|
bob2hyperion)
|
||||||
|
|
||||||
|
add_executable(boblight-dispmanx
|
||||||
|
boblight-dispmanx.cpp
|
||||||
|
flagmanager.h
|
||||||
|
flagmanager.cpp
|
||||||
|
flagmanager-dispmanx.h
|
||||||
|
flagmanager-dispmanx.cpp
|
||||||
|
grabber-dispmanx.h
|
||||||
|
grabber-dispmanx.cpp
|
||||||
|
misc.h
|
||||||
|
misc.cpp
|
||||||
|
timer.h
|
||||||
|
timer.cpp
|
||||||
|
timeutils.h
|
||||||
|
timeutils.cpp)
|
||||||
|
|
||||||
|
SET(VC_INCLUDE_DIRS
|
||||||
|
/opt/vc/include
|
||||||
|
/opt/vc/include/interface/vcos/pthreads
|
||||||
|
/opt/vc/include/interface/vmcs_host/linux)
|
||||||
|
SET(VC_LIBS
|
||||||
|
/home/pi/.xbmc-current/xbmc-bin/lib/xbmc/system/libbcm_host.so)
|
||||||
|
# /home/pi/.xbmc-current/xbmc-bin/lib/xbmc/system/libGLESv2.so
|
||||||
|
# /home/pi/.xbmc-current/xbmc-bin/lib/xbmc/system/libEGL.so
|
||||||
|
# /home/pi/.xbmc-current/xbmc-bin/lib/xbmc/system/libopenmaxil.so
|
||||||
|
# /home/pi/.xbmc-current/xbmc-bin/lib/xbmc/system/libvcos.so
|
||||||
|
# /home/pi/.xbmc-current/xbmc-bin/lib/xbmc/system/libvchiq_arm.so)
|
||||||
|
|
||||||
|
include_directories(${VC_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
target_link_libraries(boblight-dispmanx
|
||||||
|
# hyperion-png
|
||||||
|
bob2hyperion
|
||||||
|
${VC_LIBS})
|
||||||
|
@ -18,15 +18,29 @@ ofstream& indent(ofstream& ofs, unsigned indent)
|
|||||||
|
|
||||||
struct LedFrame
|
struct LedFrame
|
||||||
{
|
{
|
||||||
unsigned topLedCnt = 17;
|
unsigned topLedCnt;
|
||||||
unsigned rightLedCnt = 8;
|
unsigned rightLedCnt;
|
||||||
unsigned bottomLedCnt = 17;
|
unsigned bottomLedCnt;
|
||||||
unsigned leftLedCnt = 8;
|
unsigned leftLedCnt;
|
||||||
|
|
||||||
unsigned topLeftOffset = 17;
|
unsigned topLeftOffset;
|
||||||
|
|
||||||
unsigned borderWidth = 10;
|
unsigned borderWidth;
|
||||||
unsigned borderHeight = 10;
|
unsigned borderHeight;
|
||||||
|
|
||||||
|
LedFrame() :
|
||||||
|
topLedCnt(17),
|
||||||
|
rightLedCnt(8),
|
||||||
|
bottomLedCnt(17),
|
||||||
|
leftLedCnt(8),
|
||||||
|
|
||||||
|
topLeftOffset(17),
|
||||||
|
|
||||||
|
borderWidth(10),
|
||||||
|
borderHeight(10)
|
||||||
|
{
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
unsigned totalLedCnt() const
|
unsigned totalLedCnt() const
|
||||||
{
|
{
|
||||||
|
179
src/boblight-dispmanx.cpp
Normal file
179
src/boblight-dispmanx.cpp
Normal file
@ -0,0 +1,179 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//#define BOBLIGHT_DLOPEN
|
||||||
|
#include "boblight.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
//#include "config.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "flagmanager-dispmanx.h"
|
||||||
|
#include "grabber-dispmanx.h"
|
||||||
|
|
||||||
|
//OpenMax includes
|
||||||
|
#include "bcm_host.h"
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#define TEST_SAVE_IMAGE 0
|
||||||
|
#define PRINT_RET_VAL(ret, func, ...) ret = func(__VA_ARGS__); printf(#func " returned %d\n", ret);
|
||||||
|
|
||||||
|
int Run();
|
||||||
|
void SignalHandler(int signum);
|
||||||
|
|
||||||
|
volatile bool stop = false;
|
||||||
|
|
||||||
|
CFlagManagerDispmanX g_flagmanager;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
std::cout << "HACKED VERSION WITH TIMOLIGHT" << std::endl;
|
||||||
|
//load the boblight lib, if it fails we get a char* from dlerror()
|
||||||
|
// char* boblight_error = boblight_loadlibrary(NULL);
|
||||||
|
// if (boblight_error)
|
||||||
|
// {
|
||||||
|
// PrintError(boblight_error);
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
//try to parse the flags and bitch to stderr if there's an error
|
||||||
|
try
|
||||||
|
{
|
||||||
|
g_flagmanager.ParseFlags(argc, argv);
|
||||||
|
}
|
||||||
|
catch (string error)
|
||||||
|
{
|
||||||
|
PrintError(error);
|
||||||
|
g_flagmanager.PrintHelpMessage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_flagmanager.m_printhelp) //print help message
|
||||||
|
{
|
||||||
|
g_flagmanager.PrintHelpMessage();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_flagmanager.m_printboblightoptions) //print boblight options (-o [light:]option=value)
|
||||||
|
{
|
||||||
|
g_flagmanager.PrintBoblightOptions();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_flagmanager.m_fork)
|
||||||
|
{
|
||||||
|
if (fork())
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//set up signal handlers
|
||||||
|
signal(SIGTERM, SignalHandler);
|
||||||
|
signal(SIGINT, SignalHandler);
|
||||||
|
|
||||||
|
//keep running until we want to quit
|
||||||
|
return Run();
|
||||||
|
}
|
||||||
|
|
||||||
|
int Run()
|
||||||
|
{
|
||||||
|
while(!stop)
|
||||||
|
{
|
||||||
|
//init boblight
|
||||||
|
void* boblight = boblight_init();
|
||||||
|
|
||||||
|
cout << "Connecting to boblightd\n";
|
||||||
|
|
||||||
|
//try to connect, if we can't then bitch to stderr and destroy boblight
|
||||||
|
if (!boblight_connect(boblight, g_flagmanager.m_address, g_flagmanager.m_port, 5000000) ||
|
||||||
|
!boblight_setpriority(boblight, g_flagmanager.m_priority))
|
||||||
|
{
|
||||||
|
PrintError(boblight_geterror(boblight));
|
||||||
|
cout << "Waiting 10 seconds before trying again\n";
|
||||||
|
boblight_destroy(boblight);
|
||||||
|
sleep(10);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "Connection to boblightd opened\n";
|
||||||
|
|
||||||
|
//try to parse the boblight flags and bitch to stderr if we can't
|
||||||
|
try
|
||||||
|
{
|
||||||
|
g_flagmanager.ParseBoblightOptions(boblight);
|
||||||
|
}
|
||||||
|
catch (string error)
|
||||||
|
{
|
||||||
|
PrintError(error);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGrabberDispmanX *grabber = new CGrabberDispmanX(boblight, stop, g_flagmanager.m_sync);
|
||||||
|
|
||||||
|
grabber->SetInterval(g_flagmanager.m_interval);
|
||||||
|
grabber->SetSize(g_flagmanager.m_pixels);
|
||||||
|
|
||||||
|
if (!grabber->Setup()) //just exit if we can't set up the grabber
|
||||||
|
{
|
||||||
|
PrintError(grabber->GetError());
|
||||||
|
delete grabber;
|
||||||
|
boblight_destroy(boblight);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!grabber->Run()) //just exit if some unrecoverable error happens
|
||||||
|
{
|
||||||
|
PrintError(grabber->GetError());
|
||||||
|
delete grabber;
|
||||||
|
boblight_destroy(boblight);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else //boblightd probably timed out, so just try to reconnect
|
||||||
|
{
|
||||||
|
if (!grabber->GetError().empty())
|
||||||
|
PrintError(grabber->GetError());
|
||||||
|
}
|
||||||
|
|
||||||
|
delete grabber;
|
||||||
|
|
||||||
|
boblight_destroy(boblight);
|
||||||
|
}
|
||||||
|
|
||||||
|
cout << "Exiting\n";
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SignalHandler(int signum)
|
||||||
|
{
|
||||||
|
if (signum == SIGTERM)
|
||||||
|
{
|
||||||
|
cout << "caught SIGTERM\n";
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
else if (signum == SIGINT)
|
||||||
|
{
|
||||||
|
cout << "caught SIGINT\n";
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
}
|
106
src/flagmanager-dispmanx.cpp
Normal file
106
src/flagmanager-dispmanx.cpp
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "flagmanager-dispmanx.h"
|
||||||
|
//#include "config.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CFlagManagerDispmanX::CFlagManagerDispmanX()
|
||||||
|
{
|
||||||
|
//extend the base getopt flags
|
||||||
|
//i = interval, u = pixels, x = xgetimage, d = debug
|
||||||
|
m_flags += "i:u:d::";
|
||||||
|
|
||||||
|
m_interval = 0.1; //default interval is 100 milliseconds
|
||||||
|
m_pixels = 64; //-1 says to the capture classes to use default
|
||||||
|
m_debug = false; //no debugging by default
|
||||||
|
m_debugdpy = NULL; //default debug dpy is system default
|
||||||
|
m_sync = true; //sync mode enabled by default
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlagManagerDispmanX::ParseFlagsExtended(int& argc, char**& argv, int& c, char*& optarg) //we load our own flags here
|
||||||
|
{
|
||||||
|
if (c == 'i') //interval
|
||||||
|
{
|
||||||
|
bool vblank = false;
|
||||||
|
|
||||||
|
if (optarg[0] == 'v') //starting interval with v means vblank interval
|
||||||
|
{
|
||||||
|
#ifdef HAVE_LIBGL
|
||||||
|
optarg++;
|
||||||
|
vblank = true;
|
||||||
|
#else
|
||||||
|
throw string("Compiled without opengl support");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StrToFloat(optarg, m_interval) || m_interval <= 0.0)
|
||||||
|
{
|
||||||
|
throw string("Wrong value " + string(optarg) + " for interval");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vblank)
|
||||||
|
{
|
||||||
|
if (m_interval < 1.0)
|
||||||
|
{
|
||||||
|
throw string("Wrong value " + string(optarg) + " for vblank interval");
|
||||||
|
}
|
||||||
|
m_interval *= -1.0; //negative interval means vblank
|
||||||
|
optarg--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == 'u') //nr of pixels to use
|
||||||
|
{
|
||||||
|
if (!StrToInt(optarg, m_pixels) || m_pixels <= 0)
|
||||||
|
{
|
||||||
|
throw string("Wrong value " + string(optarg) + " for pixels");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == 'd') //turn on debug mode
|
||||||
|
{
|
||||||
|
m_debug = true;
|
||||||
|
if (optarg) //optional debug dpy
|
||||||
|
{
|
||||||
|
m_strdebugdpy = optarg;
|
||||||
|
m_debugdpy = m_strdebugdpy.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlagManagerDispmanX::PrintHelpMessage()
|
||||||
|
{
|
||||||
|
cout << "Usage: boblight-dispmanx [OPTION]\n";
|
||||||
|
cout << "\n";
|
||||||
|
cout << " options:\n";
|
||||||
|
cout << "\n";
|
||||||
|
cout << " -p priority, from 0 to 255, default is 128\n";
|
||||||
|
cout << " -s address:[port], set the address and optional port to connect to\n";
|
||||||
|
cout << " -o add libboblight option, syntax: [light:]option=value\n";
|
||||||
|
cout << " -l list libboblight options\n";
|
||||||
|
cout << " -i set the interval in seconds, default is 0.1\n";
|
||||||
|
cout << " -u set the number of pixels/rows to use\n";
|
||||||
|
cout << " default is 64 for xrender and 16 for xgetimage\n";
|
||||||
|
cout << " -d debug mode\n";
|
||||||
|
cout << " -f fork\n";
|
||||||
|
cout << " -y set the sync mode, default is on, valid options are \"on\" and \"off\"\n";
|
||||||
|
cout << "\n";
|
||||||
|
}
|
44
src/flagmanager-dispmanx.h
Normal file
44
src/flagmanager-dispmanx.h
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLAGMANAGERDISPMANX
|
||||||
|
#define FLAGMANAGERDISPMANX
|
||||||
|
|
||||||
|
#include "flagmanager.h"
|
||||||
|
|
||||||
|
class CFlagManagerDispmanX : public CFlagManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CFlagManagerDispmanX();
|
||||||
|
|
||||||
|
int m_color;
|
||||||
|
|
||||||
|
void ParseFlagsExtended(int& argc, char**& argv, int& c, char*& optarg); //we load our own flags here
|
||||||
|
void PrintHelpMessage();
|
||||||
|
|
||||||
|
double m_interval; //grab interval in seconds, or vertical blanks when negative
|
||||||
|
int m_pixels; //number of pixels on lines to capture
|
||||||
|
bool m_debug; //if true we make a little window where we put our captured output on, looks pretty
|
||||||
|
const char* m_debugdpy; //display to place the debug window on, default is NULL
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
std::string m_strdebugdpy; //place to store the debug dpy, cause our copied argv is destroyed
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //FLAGMANAGEROPENMAX
|
257
src/flagmanager.cpp
Normal file
257
src/flagmanager.cpp
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "flagmanager.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
//#define BOBLIGHT_DLOPEN_EXTERN
|
||||||
|
#include "boblight.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
//very simple, store a copy of argc and argv
|
||||||
|
CArguments::CArguments(int argc, char** argv)
|
||||||
|
{
|
||||||
|
m_argc = argc;
|
||||||
|
|
||||||
|
if (m_argc == 0)
|
||||||
|
{
|
||||||
|
m_argv = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_argv = new char*[m_argc];
|
||||||
|
for (int i = 0; i < m_argc; i++)
|
||||||
|
{
|
||||||
|
m_argv[i] = new char[strlen(argv[i]) + 1];
|
||||||
|
strcpy(m_argv[i], argv[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//delete the copy of argv
|
||||||
|
CArguments::~CArguments()
|
||||||
|
{
|
||||||
|
if (m_argv)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_argc; i++)
|
||||||
|
{
|
||||||
|
delete[] m_argv[i];
|
||||||
|
}
|
||||||
|
delete[] m_argv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CFlagManager::CFlagManager()
|
||||||
|
{
|
||||||
|
m_port = -1; //-1 tells libboblight to use default port
|
||||||
|
m_address = NULL; //NULL tells libboblight to use default address
|
||||||
|
m_priority = 128; //default priority
|
||||||
|
m_printhelp = false; //don't print helpmessage unless asked to
|
||||||
|
m_printboblightoptions = false; //same for libboblight options
|
||||||
|
m_fork = false; //don't fork by default
|
||||||
|
m_sync = false; //sync mode disabled by default
|
||||||
|
|
||||||
|
// default getopt flags, can be extended in derived classes
|
||||||
|
// p = priority, s = address[:port], o = boblight option, l = list boblight options, h = print help message, f = fork
|
||||||
|
m_flags = "p:s:o:lhfy:";
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlagManager::ParseFlags(int tempargc, char** tempargv)
|
||||||
|
{
|
||||||
|
//that copy class sure comes in handy now!
|
||||||
|
CArguments arguments(tempargc, tempargv);
|
||||||
|
int argc = arguments.m_argc;
|
||||||
|
char** argv = arguments.m_argv;
|
||||||
|
|
||||||
|
string option;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
opterr = 0; //we don't want to print error messages
|
||||||
|
|
||||||
|
while ((c = getopt(argc, argv, m_flags.c_str())) != -1)
|
||||||
|
{
|
||||||
|
if (c == 'p') //priority
|
||||||
|
{
|
||||||
|
option = optarg;
|
||||||
|
if (!StrToInt(option, m_priority) || m_priority < 0 || m_priority > 255)
|
||||||
|
{
|
||||||
|
throw string("Wrong option " + string(optarg) + " for argument -p");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == 's') //address[:port]
|
||||||
|
{
|
||||||
|
option = optarg;
|
||||||
|
//store address in string and set the char* to it
|
||||||
|
m_straddress = option.substr(0, option.find(':'));
|
||||||
|
m_address = m_straddress.c_str();
|
||||||
|
|
||||||
|
if (option.find(':') != string::npos) //check if we have a port
|
||||||
|
{
|
||||||
|
option = option.substr(option.find(':') + 1);
|
||||||
|
string word;
|
||||||
|
if (!StrToInt(option, m_port) || m_port < 0 || m_port > 65535)
|
||||||
|
{
|
||||||
|
throw string("Wrong option " + string(optarg) + " for argument -s");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == 'o') //option for libboblight
|
||||||
|
{
|
||||||
|
m_options.push_back(optarg);
|
||||||
|
}
|
||||||
|
else if (c == 'l') //list libboblight options
|
||||||
|
{
|
||||||
|
m_printboblightoptions = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (c == 'h') //print help message
|
||||||
|
{
|
||||||
|
m_printhelp = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (c == 'f')
|
||||||
|
{
|
||||||
|
m_fork = true;
|
||||||
|
}
|
||||||
|
else if (c == 'y')
|
||||||
|
{
|
||||||
|
if (!StrToBool(optarg, m_sync))
|
||||||
|
{
|
||||||
|
throw string("Wrong value " + string(optarg) + " for sync mode");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (c == '?') //unknown option
|
||||||
|
{
|
||||||
|
//check if we know this option, but expected an argument
|
||||||
|
if (m_flags.find(ToString((char)optopt) + ":") != string::npos)
|
||||||
|
{
|
||||||
|
throw string("Option " + ToString((char)optopt) + "requires an argument");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw string("Unkown option " + ToString((char)optopt));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ParseFlagsExtended(argc, argv, c, optarg); //pass our argument to a derived class
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PostGetopt(optind, argc, argv); //some postprocessing
|
||||||
|
}
|
||||||
|
|
||||||
|
//go through all options and print the descriptions to stdout
|
||||||
|
void CFlagManager::PrintBoblightOptions()
|
||||||
|
{
|
||||||
|
void* boblight = boblight_init();
|
||||||
|
int nroptions = boblight_getnroptions(boblight);
|
||||||
|
|
||||||
|
for (int i = 0; i < nroptions; i++)
|
||||||
|
{
|
||||||
|
cout << boblight_getoptiondescript(boblight, i) << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
boblight_destroy(boblight);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFlagManager::ParseBoblightOptions(void* boblight)
|
||||||
|
{
|
||||||
|
int nrlights = boblight_getnrlights(boblight);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_options.size(); i++)
|
||||||
|
{
|
||||||
|
string option = m_options[i];
|
||||||
|
string lightname;
|
||||||
|
string optionname;
|
||||||
|
string optionvalue;
|
||||||
|
int lightnr = -1;
|
||||||
|
|
||||||
|
//check if we have a lightname, otherwise we use all lights
|
||||||
|
if (option.find(':') != string::npos)
|
||||||
|
{
|
||||||
|
lightname = option.substr(0, option.find(':'));
|
||||||
|
if (option.find(':') == option.size() - 1) //check if : isn't the last char in the string
|
||||||
|
{
|
||||||
|
throw string("wrong option \"" + option + "\", syntax is [light:]option=value");
|
||||||
|
}
|
||||||
|
option = option.substr(option.find(':') + 1); //shave off the lightname
|
||||||
|
|
||||||
|
//check which light this is
|
||||||
|
bool lightfound = false;
|
||||||
|
for (int j = 0; j < nrlights; j++)
|
||||||
|
{
|
||||||
|
if (lightname == boblight_getlightname(boblight, j))
|
||||||
|
{
|
||||||
|
lightfound = true;
|
||||||
|
lightnr = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!lightfound)
|
||||||
|
{
|
||||||
|
throw string("light \"" + lightname + "\" used in option \"" + m_options[i] + "\" doesn't exist");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if '=' exists and it's not at the end of the string
|
||||||
|
if (option.find('=') == string::npos || option.find('=') == option.size() - 1)
|
||||||
|
{
|
||||||
|
throw string("wrong option \"" + option + "\", syntax is [light:]option=value");
|
||||||
|
}
|
||||||
|
|
||||||
|
optionname = option.substr(0, option.find('=')); //option name is everything before = (already shaved off the lightname here)
|
||||||
|
optionvalue = option.substr(option.find('=') + 1); //value is everything after =
|
||||||
|
|
||||||
|
option = optionname + " " + optionvalue; //libboblight wants syntax without =
|
||||||
|
|
||||||
|
//bitch if we can't set this option
|
||||||
|
if (!boblight_setoption(boblight, lightnr, option.c_str()))
|
||||||
|
{
|
||||||
|
throw string(boblight_geterror(boblight));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFlagManager::SetVideoGamma()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < m_options.size(); i++)
|
||||||
|
{
|
||||||
|
string option = m_options[i];
|
||||||
|
if (option.find(':') != string::npos)
|
||||||
|
option = option.substr(option.find(':') + 1); //shave off the lightname
|
||||||
|
|
||||||
|
if (option.find('=') != string::npos)
|
||||||
|
{
|
||||||
|
if (option.substr(0, option.find('=')) == "gamma")
|
||||||
|
return false; //gamma set by user, don't override
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_options.push_back("gamma=" + ToString(VIDEOGAMMA));
|
||||||
|
|
||||||
|
cout << "Gamma not set, using " << VIDEOGAMMA << " since this is default for video\n";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
72
src/flagmanager.h
Normal file
72
src/flagmanager.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLAGMANAGER
|
||||||
|
#define FLAGMANAGER
|
||||||
|
|
||||||
|
#define VIDEOGAMMA 2.2
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
//class for making a copy of argc and argv
|
||||||
|
class CArguments
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CArguments(int argc, char** argv);
|
||||||
|
~CArguments();
|
||||||
|
|
||||||
|
int m_argc;
|
||||||
|
char** m_argv;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CFlagManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CFlagManager();
|
||||||
|
|
||||||
|
bool m_printhelp; //if we need to print the help message
|
||||||
|
bool m_printboblightoptions; //if we need to print the boblight options
|
||||||
|
|
||||||
|
const char* m_address; //address to connect to, set to NULL if none given for default
|
||||||
|
int m_port; //port to connect to, set to -1 if none given for default
|
||||||
|
int m_priority; //priority, set to 128 if none given for default
|
||||||
|
bool m_fork; //if we should fork
|
||||||
|
bool m_sync; //if sync mode is enabled
|
||||||
|
|
||||||
|
void ParseFlags(int tempargc, char** tempargv); //parsing commandline flags
|
||||||
|
virtual void PrintHelpMessage() {};
|
||||||
|
|
||||||
|
void PrintBoblightOptions(); //printing of boblight options (-o [light:]option=value)
|
||||||
|
void ParseBoblightOptions(void* boblight); //parsing of boblight options
|
||||||
|
bool SetVideoGamma(); //set gamma to 2.2 if not given, returns true if done
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
std::string m_flags; //string to pass to getopt, for example "c:r:a:p"
|
||||||
|
std::string m_straddress; //place to store address to connect to, because CArguments deletes argv
|
||||||
|
|
||||||
|
std::vector<std::string> m_options; //place to store boblight options
|
||||||
|
|
||||||
|
//gets called from ParseFlags, for derived classes
|
||||||
|
virtual void ParseFlagsExtended(int& argc, char**& argv, int& c, char*& optarg){};
|
||||||
|
//gets called after getopt
|
||||||
|
virtual void PostGetopt(int optind, int argc, char** argv) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //FLAGMANAGER
|
165
src/grabber-dispmanx.cpp
Normal file
165
src/grabber-dispmanx.cpp
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
#include "grabber-dispmanx.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
//#define BOBLIGHT_DLOPEN_EXTERN
|
||||||
|
#include "boblight.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CGrabberDispmanX::CGrabberDispmanX(void* boblight, volatile bool& stop, bool sync) : m_stop(stop), m_timer(&stop)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
bcm_host_init();
|
||||||
|
|
||||||
|
m_boblight = boblight;
|
||||||
|
m_debug = false;
|
||||||
|
m_sync = sync;
|
||||||
|
|
||||||
|
type = VC_IMAGE_RGB888;
|
||||||
|
|
||||||
|
display = vc_dispmanx_display_open(0);
|
||||||
|
|
||||||
|
ret = vc_dispmanx_display_get_info(display, &info);
|
||||||
|
assert(ret == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
CGrabberDispmanX::~CGrabberDispmanX()
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
free(image);
|
||||||
|
|
||||||
|
ret = vc_dispmanx_resource_delete(resource);
|
||||||
|
assert( ret == 0 );
|
||||||
|
ret = vc_dispmanx_display_close(display);
|
||||||
|
assert( ret == 0 );
|
||||||
|
|
||||||
|
bcm_host_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGrabberDispmanX::Setup()
|
||||||
|
{
|
||||||
|
if (m_interval > 0.0) //set up timer
|
||||||
|
{
|
||||||
|
m_timer.SetInterval(Round64(m_interval * 1000000.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
pitch = ALIGN_UP(m_size*3, 32);
|
||||||
|
|
||||||
|
image = new char[m_size * m_size * 3];
|
||||||
|
|
||||||
|
resource = vc_dispmanx_resource_create(type,
|
||||||
|
m_size,
|
||||||
|
m_size,
|
||||||
|
&vc_image_ptr );
|
||||||
|
assert(resource);
|
||||||
|
|
||||||
|
m_error.clear();
|
||||||
|
|
||||||
|
return ExtendedSetup(); //run stuff from derived classes
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGrabberDispmanX::ExtendedSetup()
|
||||||
|
{
|
||||||
|
if (!CheckExtensions())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGrabberDispmanX::CheckExtensions()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGrabberDispmanX::Run()
|
||||||
|
{
|
||||||
|
int rgb[3];
|
||||||
|
VC_RECT_T rectangle;
|
||||||
|
char* image_ptr;
|
||||||
|
|
||||||
|
boblight_setscanrange(m_boblight, m_size, m_size);
|
||||||
|
|
||||||
|
while(!m_stop)
|
||||||
|
{
|
||||||
|
vc_dispmanx_snapshot(display,resource, VC_IMAGE_ROT0);
|
||||||
|
|
||||||
|
vc_dispmanx_rect_set(&rectangle, 0, 0, m_size, m_size);
|
||||||
|
|
||||||
|
vc_dispmanx_resource_read_data(resource, &rectangle, image, m_size*3);
|
||||||
|
|
||||||
|
image_ptr = (char *)image;
|
||||||
|
//read out the pixels
|
||||||
|
for (int y = 0; y < m_size && !m_stop; y++)
|
||||||
|
{
|
||||||
|
// image_ptr += y*m_size*3;
|
||||||
|
for (int x = 0; x < m_size && !m_stop; x++)
|
||||||
|
{
|
||||||
|
rgb[0] = image_ptr[y*m_size*3+x*3];
|
||||||
|
rgb[1] = image_ptr[y*m_size*3+x*3 + 1];
|
||||||
|
rgb[2] = image_ptr[y*m_size*3+x*3 + 2];
|
||||||
|
|
||||||
|
boblight_addpixelxy(m_boblight, x, y, rgb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//send pixeldata to boblight
|
||||||
|
if (!boblight_sendrgb(m_boblight, m_sync, NULL))
|
||||||
|
{
|
||||||
|
m_error = boblight_geterror(m_boblight);
|
||||||
|
return true; //recoverable error
|
||||||
|
}
|
||||||
|
|
||||||
|
//when in debug mode, put the captured image on the debug window
|
||||||
|
if (m_debug)
|
||||||
|
{
|
||||||
|
printf("Debug not supproted!\n");
|
||||||
|
m_debug = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Wait())
|
||||||
|
{
|
||||||
|
return false; //unrecoverable error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_error.clear();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CGrabberDispmanX::Wait()
|
||||||
|
{
|
||||||
|
if (m_interval > 0.0) //wait for timer
|
||||||
|
{
|
||||||
|
m_timer.Wait();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
90
src/grabber-dispmanx.h
Normal file
90
src/grabber-dispmanx.h
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef GRABBERDISPMANX
|
||||||
|
#define GRABBERDISPMANX
|
||||||
|
|
||||||
|
#include "bcm_host.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
//#include "config.h"
|
||||||
|
#include "timer.h"
|
||||||
|
|
||||||
|
#ifndef ALIGN_UP
|
||||||
|
#define ALIGN_UP(x,y) ((x + (y)-1) & ~((y)-1))
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//class for grabbing with DispmanX
|
||||||
|
class CGrabberDispmanX
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CGrabberDispmanX(void* boblight, volatile bool& stop, bool sync);
|
||||||
|
~CGrabberDispmanX();
|
||||||
|
|
||||||
|
bool ExtendedSetup();
|
||||||
|
bool Run();
|
||||||
|
|
||||||
|
std::string& GetError() { return m_error; } //retrieves the latest error
|
||||||
|
|
||||||
|
void SetInterval(double interval) { m_interval = interval; } //sets interval, negative means vblanks
|
||||||
|
void SetSize(int size) { m_size = size; } //sets how many pixels we want to grab
|
||||||
|
|
||||||
|
bool Setup(); //base setup function
|
||||||
|
|
||||||
|
void SetDebug(const char* display); //turn on debug window
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
bool Wait(); //wait for the timer or on the vblank
|
||||||
|
volatile bool& m_stop;
|
||||||
|
|
||||||
|
std::string m_error; //latest error
|
||||||
|
|
||||||
|
void* m_boblight; //our handle from libboblight
|
||||||
|
|
||||||
|
int m_size; //nr of pixels on lines to grab
|
||||||
|
|
||||||
|
bool m_debug; //if we have debug mode on
|
||||||
|
|
||||||
|
long double m_lastupdate;
|
||||||
|
long double m_lastmeasurement;
|
||||||
|
long double m_measurements;
|
||||||
|
int m_nrmeasurements;
|
||||||
|
|
||||||
|
double m_interval; //interval in seconds, or negative for vblanks
|
||||||
|
CTimer m_timer; //our timer
|
||||||
|
bool m_sync; //sync mode for libboblight
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
bool CheckExtensions();
|
||||||
|
|
||||||
|
DISPMANX_DISPLAY_HANDLE_T display;
|
||||||
|
DISPMANX_MODEINFO_T info;
|
||||||
|
void *image;
|
||||||
|
DISPMANX_UPDATE_HANDLE_T update;
|
||||||
|
DISPMANX_RESOURCE_HANDLE_T resource;
|
||||||
|
DISPMANX_ELEMENT_HANDLE_T element;
|
||||||
|
uint32_t vc_image_ptr;
|
||||||
|
VC_IMAGE_TYPE_T type;
|
||||||
|
int pitch;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //GRABBEROPENMAX
|
81
src/misc.cpp
Normal file
81
src/misc.cpp
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <locale.h>
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void PrintError(const std::string& error)
|
||||||
|
{
|
||||||
|
std::cerr << "ERROR: " << error << "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
//get the first word (separated by whitespace) from string data and place that in word
|
||||||
|
//then remove that word from string data
|
||||||
|
bool GetWord(string& data, string& word)
|
||||||
|
{
|
||||||
|
stringstream datastream(data);
|
||||||
|
string end;
|
||||||
|
|
||||||
|
datastream >> word;
|
||||||
|
if (datastream.fail())
|
||||||
|
{
|
||||||
|
data.clear();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pos = data.find(word) + word.length();
|
||||||
|
|
||||||
|
if (pos >= data.length())
|
||||||
|
{
|
||||||
|
data.clear();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
data = data.substr(pos);
|
||||||
|
|
||||||
|
datastream.clear();
|
||||||
|
datastream.str(data);
|
||||||
|
|
||||||
|
datastream >> end;
|
||||||
|
if (datastream.fail())
|
||||||
|
data.clear();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//convert . or , to the current locale for correct conversion of ascii float
|
||||||
|
void ConvertFloatLocale(std::string& strfloat)
|
||||||
|
{
|
||||||
|
static struct lconv* locale = localeconv();
|
||||||
|
|
||||||
|
size_t pos = strfloat.find_first_of(",.");
|
||||||
|
|
||||||
|
while (pos != string::npos)
|
||||||
|
{
|
||||||
|
strfloat.replace(pos, 1, 1, *locale->decimal_point);
|
||||||
|
pos++;
|
||||||
|
|
||||||
|
if (pos >= strfloat.size())
|
||||||
|
break;
|
||||||
|
|
||||||
|
pos = strfloat.find_first_of(",.", pos);
|
||||||
|
}
|
||||||
|
}
|
191
src/misc.h
Normal file
191
src/misc.h
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MISCUTIL
|
||||||
|
#define MISCUTIL
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
#include <exception>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
void PrintError(const std::string& error);
|
||||||
|
bool GetWord(std::string& data, std::string& word);
|
||||||
|
void ConvertFloatLocale(std::string& strfloat);
|
||||||
|
|
||||||
|
template <class Value>
|
||||||
|
inline std::string ToString(Value value)
|
||||||
|
{
|
||||||
|
std::string data;
|
||||||
|
std::stringstream valuestream;
|
||||||
|
valuestream << value;
|
||||||
|
valuestream >> data;
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string GetErrno()
|
||||||
|
{
|
||||||
|
return strerror(errno);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string GetErrno(int err)
|
||||||
|
{
|
||||||
|
return strerror(err);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class B, class C>
|
||||||
|
inline A Clamp(A value, B min, C max)
|
||||||
|
{
|
||||||
|
return value < max ? (value > min ? value : min) : max;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
inline A Max(A value1, B value2)
|
||||||
|
{
|
||||||
|
return value1 > value2 ? value1 : value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class B, class C>
|
||||||
|
inline A Max(A value1, B value2, C value3)
|
||||||
|
{
|
||||||
|
return (value1 > value2) ? (value1 > value3 ? value1 : value3) : (value2 > value3 ? value2 : value3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
inline A Min(A value1, B value2)
|
||||||
|
{
|
||||||
|
return value1 < value2 ? value1 : value2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class B, class C>
|
||||||
|
inline A Min(A value1, B value2, C value3)
|
||||||
|
{
|
||||||
|
return (value1 < value2) ? (value1 < value3 ? value1 : value3) : (value2 < value3 ? value2 : value3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T Abs(T value)
|
||||||
|
{
|
||||||
|
return value > 0 ? value : -value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class B>
|
||||||
|
inline A Round(B value)
|
||||||
|
{
|
||||||
|
if (value == 0.0)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (value > 0.0)
|
||||||
|
{
|
||||||
|
return (A)(value + 0.5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return (A)(value - 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t Round32(float value)
|
||||||
|
{
|
||||||
|
return lroundf(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int32_t Round32(double value)
|
||||||
|
{
|
||||||
|
return lround(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int64_t Round64(float value)
|
||||||
|
{
|
||||||
|
return llroundf(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline int64_t Round64(double value)
|
||||||
|
{
|
||||||
|
return llround(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool StrToInt(const std::string& data, int& value)
|
||||||
|
{
|
||||||
|
return sscanf(data.c_str(), "%i", &value) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool StrToInt(const std::string& data, int64_t& value)
|
||||||
|
{
|
||||||
|
return sscanf(data.c_str(), "%ld", &value) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool HexStrToInt(const std::string& data, int& value)
|
||||||
|
{
|
||||||
|
return sscanf(data.c_str(), "%x", &value) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool HexStrToInt(const std::string& data, int64_t& value)
|
||||||
|
{
|
||||||
|
return sscanf(data.c_str(), "%x", &value) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool StrToFloat(const std::string& data, float& value)
|
||||||
|
{
|
||||||
|
return sscanf(data.c_str(), "%f", &value) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool StrToFloat(const std::string& data, double& value)
|
||||||
|
{
|
||||||
|
return sscanf(data.c_str(), "%lf", &value) == 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool StrToBool(const std::string& data, bool& value)
|
||||||
|
{
|
||||||
|
std::string data2 = data;
|
||||||
|
std::string word;
|
||||||
|
if (!GetWord(data2, word))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (word == "1" || word == "true" || word == "on" || word == "yes")
|
||||||
|
{
|
||||||
|
value = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (word == "0" || word == "false" || word == "off" || word == "no")
|
||||||
|
{
|
||||||
|
value = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ivalue;
|
||||||
|
if (StrToInt(word, ivalue))
|
||||||
|
{
|
||||||
|
value = ivalue != 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif //MISCUTIL
|
69
src/timer.cpp
Normal file
69
src/timer.cpp
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "timer.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "timeutils.h"
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
CTimer::CTimer(volatile bool* stop /*=NULL*/)
|
||||||
|
{
|
||||||
|
m_interval = -1;
|
||||||
|
m_timerstop = stop;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimer::SetInterval(int64_t usecs)
|
||||||
|
{
|
||||||
|
m_interval = usecs;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t CTimer::GetInterval()
|
||||||
|
{
|
||||||
|
return m_interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimer::Reset()
|
||||||
|
{
|
||||||
|
m_time = GetTimeUs();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CTimer::Wait()
|
||||||
|
{
|
||||||
|
int64_t sleeptime;
|
||||||
|
|
||||||
|
//keep looping until we have a timestamp that's not too old
|
||||||
|
int64_t now = GetTimeUs();
|
||||||
|
do
|
||||||
|
{
|
||||||
|
m_time += m_interval;
|
||||||
|
sleeptime = m_time - now;
|
||||||
|
}
|
||||||
|
while(sleeptime <= m_interval * -2LL);
|
||||||
|
|
||||||
|
if (sleeptime > m_interval * 2LL) //failsafe, m_time must be bork if we get here
|
||||||
|
{
|
||||||
|
sleeptime = m_interval * 2LL;
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
USleep(sleeptime, m_timerstop);
|
||||||
|
}
|
||||||
|
|
42
src/timer.h
Normal file
42
src/timer.h
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef CTIMER
|
||||||
|
#define CTIMER
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
class CTimer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CTimer(volatile bool* stop = NULL);
|
||||||
|
void SetInterval(int64_t usecs);
|
||||||
|
virtual void Wait();
|
||||||
|
void Reset();
|
||||||
|
|
||||||
|
int64_t GetInterval();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int64_t m_time;
|
||||||
|
int64_t m_interval;
|
||||||
|
volatile bool* m_timerstop;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
56
src/timeutils.cpp
Normal file
56
src/timeutils.cpp
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "timeutils.h"
|
||||||
|
|
||||||
|
void USleep(int64_t usecs, volatile bool* stop /*= NULL*/)
|
||||||
|
{
|
||||||
|
if (usecs <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (stop && usecs > 1000000) //when a pointer to a bool is passed, check it every second and stop when it's true
|
||||||
|
{
|
||||||
|
int64_t now = GetTimeUs();
|
||||||
|
int64_t end = now + usecs;
|
||||||
|
|
||||||
|
while (now < end)
|
||||||
|
{
|
||||||
|
struct timespec sleeptime = {};
|
||||||
|
|
||||||
|
if (*stop)
|
||||||
|
return;
|
||||||
|
else if (end - now >= 1000000)
|
||||||
|
sleeptime.tv_sec = 1;
|
||||||
|
else
|
||||||
|
sleeptime.tv_nsec = ((end - now) % 1000000) * 1000;
|
||||||
|
|
||||||
|
nanosleep(&sleeptime, NULL);
|
||||||
|
now = GetTimeUs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
struct timespec sleeptime;
|
||||||
|
sleeptime.tv_sec = usecs / 1000000;
|
||||||
|
sleeptime.tv_nsec = (usecs % 1000000) * 1000;
|
||||||
|
|
||||||
|
nanosleep(&sleeptime, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
49
src/timeutils.h
Normal file
49
src/timeutils.h
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*
|
||||||
|
* boblight
|
||||||
|
* Copyright (C) Bob 2009
|
||||||
|
*
|
||||||
|
* boblight is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* boblight is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TIMEUTILS
|
||||||
|
#define TIMEUTILS
|
||||||
|
|
||||||
|
#include "stdint.h"
|
||||||
|
//#include "config.h"
|
||||||
|
|
||||||
|
#include <time.h>
|
||||||
|
#include <sys/time.h>
|
||||||
|
|
||||||
|
inline int64_t GetTimeUs()
|
||||||
|
{
|
||||||
|
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||||
|
struct timespec time;
|
||||||
|
clock_gettime(CLOCK_MONOTONIC, &time);
|
||||||
|
return ((int64_t)time.tv_sec * 1000000LL) + (int64_t)(time.tv_nsec + 500) / 1000LL;
|
||||||
|
#else
|
||||||
|
struct timeval time;
|
||||||
|
gettimeofday(&time, NULL);
|
||||||
|
return ((int64_t)time.tv_sec * 1000000LL) + (int64_t)time.tv_usec;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline T GetTimeSec()
|
||||||
|
{
|
||||||
|
return (T)GetTimeUs() / (T)1000000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void USleep(int64_t usecs, volatile bool* stop = NULL);
|
||||||
|
|
||||||
|
#endif //TIMEUTILS
|
Loading…
Reference in New Issue
Block a user