Added HyperionPng with similar interface as Hyperion to test frame-capture and handling.

This commit is contained in:
T. van der Zwan 2013-08-02 11:54:09 +02:00
parent f6672499f5
commit 240218a6bd
13 changed files with 261 additions and 12 deletions

View File

@ -18,6 +18,6 @@ SET(BCM_INCLUDE_DIRS
${BCM_INCLUDE_DIR}/interface/vcos/pthreads ${BCM_INCLUDE_DIR}/interface/vcos/pthreads
${BCM_INCLUDE_DIR}/interface/vmcs_host/linux) ${BCM_INCLUDE_DIR}/interface/vmcs_host/linux)
FIND_LIBRARY(BCM_LIBS FIND_LIBRARY(BCM_LIBRARIES
NAMES bcm_host NAMES bcm_host
PATHS /usr/lib /usr/local/lib /opt/vc/lib) PATHS /usr/lib /usr/local/lib /opt/vc/lib)

View File

@ -0,0 +1,47 @@
#pragma once
// Utils includes
#include <utils/RgbImage.h>
// Forward class declaration
class pngwriter;
/**
* @brief The HyperionPng class implements the same interface
*/
class HyperionPng
{
public:
HyperionPng();
~HyperionPng();
void setInputSize(const unsigned width, const unsigned height);
RgbImage& image();
void commit();
void operator() (const RgbImage& inputImage);
private:
RgbImage* mBuffer;
unsigned mFrameCnt;
unsigned mWriteFrequency;
pngwriter *mWriter;
unsigned long mFileIndex;
HyperionPng(const HyperionPng&)
{
// empty
}
HyperionPng& operator=(const HyperionPng&)
{
return *this;
}
};

View File

@ -47,6 +47,16 @@ private:
return y*mWidth + x; return y*mWidth + x;
} }
RgbImage(const RgbImage&)
{
// empty
}
RgbImage& operator=(const RgbImage& other)
{
return *this;
}
private: private:
unsigned mWidth; unsigned mWidth;
unsigned mHeight; unsigned mHeight;

View File

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

View File

@ -9,7 +9,7 @@
// PNGWriter includes // PNGWriter includes
#define NO_FREETYPE #define NO_FREETYPE
#include "pngwriter.h" #include "hyperionpng/pngwriter.h"
struct RaspiPng struct RaspiPng
{ {

View File

@ -11,9 +11,11 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/hyperionpng)
# Create the 'rasplight-png' library # Create the 'rasplight-png' library
add_library(hyperion-png SHARED add_library(hyperion-png SHARED
${CURRENT_SOURCE_DIR}/hyperion-png.cpp ${CURRENT_HEADER_DIR}/HyperionPng.h
${CURRENT_SOURCE_DIR}/HyperionPng.cpp
${CURRENT_SOURCE_DIR}/pngwriter.h ${CURRENT_SOURCE_DIR}/pngwriter.h
${CURRENT_SOURCE_DIR}/pngwriter.cc) ${CURRENT_SOURCE_DIR}/pngwriter.cc)
target_link_libraries(hyperion-png target_link_libraries(hyperion-png
hyperion-utils
${PNG_LIBRARIES}) ${PNG_LIBRARIES})

View File

@ -0,0 +1,71 @@
// PNG includes
#ifndef NO_FREETYPE
#define NO_FREETYPE
#endif
#include "pngwriter.h"
#include <hyperionpng/HyperionPng.h>
HyperionPng::HyperionPng() :
mBuffer(nullptr),
mFrameCnt(0),
mWriter(new pngwriter()),
mFileIndex(0)
{
// empty
}
HyperionPng::~HyperionPng()
{
std::cout << "HyperionPng is being deleted" << std::endl;
delete mBuffer;
// mWriter->close();
// delete mWriter;
}
void HyperionPng::setInputSize(const unsigned width, const unsigned height)
{
delete mBuffer;
mBuffer = new RgbImage(width, height);
}
RgbImage& HyperionPng::image()
{
return *mBuffer;
}
void HyperionPng::commit()
{
this->operator ()(*mBuffer);
}
void HyperionPng::operator() (const RgbImage& inputImage)
{
// Write only every n'th frame
if (mFrameCnt%mWriteFrequency == 0)
{
// Set the filename for the PNG
char filename[64];
sprintf(filename, "/home/pi/RASPI_%04ld.png", mFileIndex);
mWriter->pngwriter_rename(filename);
// Plot the pixels from the image to the PNG-Writer
for (unsigned y=0; y<inputImage.width(); ++y)
{
for (unsigned x=0; x<inputImage.height(); ++x)
{
const RgbColor& color = inputImage(x,y);
mWriter->plot(x+1, inputImage.height()-y, color.red/255.0, color.green/255.0, color.blue/255.0);
}
}
// Write-out the current frame and prepare for the next
mWriter->write_png();
++mFileIndex;
}
++mFrameCnt;
}

View File

@ -10,7 +10,7 @@
RgbImage::RgbImage(const unsigned width, const unsigned height, const RgbColor background) : RgbImage::RgbImage(const unsigned width, const unsigned height, const RgbColor background) :
mWidth(width), mWidth(width),
mHeight(height), mHeight(height),
mColors(NULL) mColors(nullptr)
{ {
mColors = new RgbColor[width*height]; mColors = new RgbColor[width*height];
for (RgbColor* color = mColors; color <= mColors+(mWidth*mHeight); ++color) for (RgbColor* color = mColors; color <= mColors+(mWidth*mHeight); ++color)
@ -21,6 +21,8 @@ RgbImage::RgbImage(const unsigned width, const unsigned height, const RgbColor b
RgbImage::~RgbImage() RgbImage::~RgbImage()
{ {
std::cout << "RgbImage(" << this << ") is being deleted" << std::endl;
delete[] mColors; delete[] mColors;
} }

View File

@ -25,14 +25,14 @@ include_directories(${BCM_INCLUDE_DIRS})
target_link_libraries(boblight-dispmanx target_link_libraries(boblight-dispmanx
# hyperion-png # hyperion-png
bob2hyperion bob2hyperion
${BCM_LIBS}) ${BCM_LIBRARIES})
add_executable(HyperionDispmanX add_executable(HyperionDispmanX
HyperionDispmanX.cpp) HyperionDispmanX.cpp)
target_link_libraries(HyperionDispmanX target_link_libraries(HyperionDispmanX
hyperion hyperion
${BCM_LIBS}) ${BCM_LIBRARIES})
# Find the libPNG # Find the libPNG
@ -50,3 +50,5 @@ if(PNG_FOUND)
hyperion-utils hyperion-utils
${PNG_LIBRARIES}) ${PNG_LIBRARIES})
endif(PNG_FOUND) endif(PNG_FOUND)
add_subdirectory(dispmanx-png)

View File

@ -55,16 +55,15 @@ int main(int /*argc*/, char** /*argv*/)
RgbImage* image_ptr = &(hyperion.image()); RgbImage* image_ptr = &(hyperion.image());
void* image_vp = reinterpret_cast<void*>(image_ptr); void* image_vp = reinterpret_cast<void*>(image_ptr);
const unsigned imageSize_bytes = width*height*3; const uint32_t pitch = width * 3;
timespec updateInterval; timespec updateInterval;
updateInterval.tv_sec = 0; updateInterval.tv_sec = 0;
updateInterval.tv_nsec = 100000000000; updateInterval.tv_nsec = 100000000;
while(running) while(running)
{ {
vc_dispmanx_snapshot(display, resource, VC_IMAGE_ROT0); vc_dispmanx_snapshot(display, resource, VC_IMAGE_ROT0);
vc_dispmanx_resource_read_data(resource, &rectangle, image_vp, imageSize_bytes); vc_dispmanx_resource_read_data(resource, &rectangle, image_vp, pitch);
hyperion.commit(); hyperion.commit();

View File

@ -0,0 +1,13 @@
# Find the BCM-package (VC control)
find_package(BCM REQUIRED)
# Add the include dirs to the search path
include_directories(${BCM_INCLUDE_DIRS})
add_executable(dispmanx-png
dispmanx-png.cpp)
target_link_libraries(dispmanx-png
hyperion-png
${BCM_LIBRARIES})

View File

@ -0,0 +1,91 @@
// STL includes
#include <csignal>
// VC includes
#include <bcm_host.h>
// Hyperion includes
#include <hyperionpng/HyperionPng.h>
static volatile bool sRunning = true;
void signal_handler(int signum)
{
std::cout << "RECEIVED SIGNAL: " << signum << std::endl;
sRunning = false;
}
template <typename Hyperion_T>
int dispmanx_process(Hyperion_T& hyperion, volatile bool& running)
{
// Configure the used image size
const unsigned width = 64;
const unsigned height = 64;
hyperion.setInputSize(width, height);
// Initiase BCM
bcm_host_init();
// Open the connection to the displaydisplay
DISPMANX_DISPLAY_HANDLE_T display = vc_dispmanx_display_open(0);
DISPMANX_MODEINFO_T info;
int ret = vc_dispmanx_display_get_info(display, &info);
assert(ret == 0);
// Create the resources for capturing image
uint32_t vc_image_ptr;
DISPMANX_RESOURCE_HANDLE_T resource = vc_dispmanx_resource_create(
VC_IMAGE_RGB888,
width,
height,
&vc_image_ptr);
assert(resource);
VC_RECT_T rectangle;
vc_dispmanx_rect_set(&rectangle, 0, 0, width, height);
RgbImage* image_ptr = &(hyperion.image());
void* image_vp = reinterpret_cast<void*>(image_ptr);
const uint32_t pitch = width * 3;
timespec updateInterval;
updateInterval.tv_sec = 0;
updateInterval.tv_nsec = 100000000;
while(running)
{
std::cout << "Grabbing a frame from display" << std::endl;
vc_dispmanx_snapshot(display, resource, VC_IMAGE_ROT0);
vc_dispmanx_resource_read_data(resource, &rectangle, image_vp, pitch);
std::cout << "Commiting the frame to Hyperion" << std::endl;
// hyperion.commit();
std::cout << "Waiting for next grab" << std::endl;
nanosleep(&updateInterval, NULL);
}
std::cout << "Cleaning VC resources" << std::endl;
// Clean up resources
vc_dispmanx_resource_delete(resource);
vc_dispmanx_display_close(display);
std::cout << "Uninitialising BCM-Host" << std::endl;
// De-init BCM
bcm_host_deinit();
std::cout << "Exit success" << std::endl;
return 0;
}
int main(int /*argc*/, char** /*argv*/)
{
// Install signal-handlers to exit the processing loop
signal(SIGTERM, signal_handler);
signal(SIGINT, signal_handler);
// Construct and initialise the PNG creator with preset size
HyperionPng hyperion;
return dispmanx_process(hyperion, sRunning);
}

View File

@ -33,5 +33,5 @@ if(PNG_FOUND)
TestHyperionPng.cpp) TestHyperionPng.cpp)
target_link_libraries(TestHyperionPng target_link_libraries(TestHyperionPng
hyperion-png) bob2hyperion-png)
endif(PNG_FOUND) endif(PNG_FOUND)