From cbbb1d740b6f56f84d9e8ada0d51611c7d8b0d85 Mon Sep 17 00:00:00 2001 From: "T. van der Zwan" Date: Sat, 3 Aug 2013 23:24:22 +0200 Subject: [PATCH] Fixed memory overwrite bug. This fixes the png writer and led control. --- CMakeLists.txt | 2 +- include/hyperionpng/HyperionPng.h | 2 + include/utils/RgbImage.h | 21 ++++------ libsrc/hyperionpng/HyperionPng.cpp | 18 +++++--- libsrc/utils/RgbImage.cpp | 9 ++-- src/HyperionDispmanX.cpp | 57 +++++++------------------ src/dispmanx-helper.h | 59 ++++++++++++++++++++++++++ src/dispmanx-png/dispmanx-png.cpp | 67 +----------------------------- test/CMakeLists.txt | 10 +++-- test/TestHyperionPng.cpp | 66 +++++++++++++++-------------- test/TestRgbImage.cpp | 22 ++++++++++ 11 files changed, 167 insertions(+), 166 deletions(-) create mode 100644 src/dispmanx-helper.h create mode 100644 test/TestRgbImage.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index d3d0d704..d42a4d63 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ include_directories(${CMAKE_SOURCE_DIR}/include) # Prefer static linking over dynamic set(CMAKE_FIND_LIBRARY_SUFFIXES ".a;.so") -#set(CMAKE_BUILD_TYPE "Release") +set(CMAKE_BUILD_TYPE "Release") # enable C++11 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x -Wall") diff --git a/include/hyperionpng/HyperionPng.h b/include/hyperionpng/HyperionPng.h index 610d59e4..4990cc1c 100644 --- a/include/hyperionpng/HyperionPng.h +++ b/include/hyperionpng/HyperionPng.h @@ -25,6 +25,8 @@ public: void operator() (const RgbImage& inputImage); +private: + void writeImage(const RgbImage& inputImage); private: RgbImage* mBuffer; diff --git a/include/utils/RgbImage.h b/include/utils/RgbImage.h index 776ab0f4..7c5cea2d 100644 --- a/include/utils/RgbImage.h +++ b/include/utils/RgbImage.h @@ -3,6 +3,7 @@ #include #include +#include // Local includes #include "RgbColor.h" @@ -33,13 +34,17 @@ public: inline void copy(const RgbImage& other) { - std::cout << "This image size: [" << width() << "x" << height() << "]. Other image size: [" << other.width() << "x" << other.height() << "]" << std::endl; assert(other.mWidth == mWidth); assert(other.mHeight == mHeight); memcpy(mColors, other.mColors, mWidth*mHeight*sizeof(RgbColor)); } + RgbColor* memptr() + { + return mColors; + } + private: inline unsigned toIndex(const unsigned x, const unsigned y) const @@ -47,19 +52,9 @@ private: return y*mWidth + x; } - RgbImage(const RgbImage&) - { - // empty - } - - RgbImage& operator=(const RgbImage& other) - { - return *this; - } - private: - unsigned mWidth; - unsigned mHeight; + const unsigned mWidth; + const unsigned mHeight; /** The colors of the image */ RgbColor* mColors; diff --git a/libsrc/hyperionpng/HyperionPng.cpp b/libsrc/hyperionpng/HyperionPng.cpp index 3646217d..2c59734e 100644 --- a/libsrc/hyperionpng/HyperionPng.cpp +++ b/libsrc/hyperionpng/HyperionPng.cpp @@ -21,8 +21,8 @@ HyperionPng::~HyperionPng() std::cout << "HyperionPng is being deleted" << std::endl; delete mBuffer; -// mWriter->close(); -// delete mWriter; + mWriter->close(); + delete mWriter; } void HyperionPng::setInputSize(const unsigned width, const unsigned height) @@ -38,18 +38,24 @@ RgbImage& HyperionPng::image() void HyperionPng::commit() { - this->operator ()(*mBuffer); + writeImage(*mBuffer); } void HyperionPng::operator() (const RgbImage& inputImage) +{ + writeImage(inputImage); +} + +void HyperionPng::writeImage(const RgbImage& inputImage) { // Write only every n'th frame - if (mFrameCnt%mWriteFrequency == 0) + if (mFrameCnt%10 == 0) { // Set the filename for the PNG char filename[64]; - sprintf(filename, "/home/pi/RASPI_%04ld.png", mFileIndex); + sprintf(filename, "/home/pi/RASPI_%04lu.png", mFileIndex); mWriter->pngwriter_rename(filename); + mWriter->resize(inputImage.width(), inputImage.height()); // Plot the pixels from the image to the PNG-Writer for (unsigned y=0; ywrite_png(); ++mFileIndex; + std::cout << "PNGWRITER FINISHED" << std::endl; } ++mFrameCnt; } diff --git a/libsrc/utils/RgbImage.cpp b/libsrc/utils/RgbImage.cpp index aaf8a71a..6372f92f 100644 --- a/libsrc/utils/RgbImage.cpp +++ b/libsrc/utils/RgbImage.cpp @@ -10,19 +10,16 @@ RgbImage::RgbImage(const unsigned width, const unsigned height, const RgbColor background) : mWidth(width), mHeight(height), - mColors(nullptr) + mColors(new RgbColor[width*height]) { - mColors = new RgbColor[width*height]; - for (RgbColor* color = mColors; color <= mColors+(mWidth*mHeight); ++color) + for (unsigned i=0; i #include + +#include "dispmanx-helper.h" + +static volatile bool sRunning = true; + +void signal_handler(int signum) +{ + std::cout << "RECEIVED SIGNAL: " << signum << std::endl; + sRunning = false; +} + int main(int /*argc*/, char** /*argv*/) { + // Install signal-handlers to exit the processing loop + signal(SIGTERM, signal_handler); + signal(SIGINT, signal_handler); + const char* homeDir = getenv("RASPILIGHT_HOME"); if (!homeDir) { @@ -28,47 +43,7 @@ int main(int /*argc*/, char** /*argv*/) } Hyperion hyperion(raspiConfig); - const unsigned width = 64; - const unsigned height = 64; - - hyperion.setInputSize(width, height); - - volatile bool running = true; - - // 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(image_ptr); - const uint32_t pitch = width * 3; - - timespec updateInterval; - updateInterval.tv_sec = 0; - updateInterval.tv_nsec = 100000000; - while(running) - { - vc_dispmanx_snapshot(display, resource, VC_IMAGE_ROT0); - vc_dispmanx_resource_read_data(resource, &rectangle, image_vp, pitch); - - hyperion.commit(); - - nanosleep(&updateInterval, NULL); - } + dispmanx_process(hyperion, sRunning); return 0; } diff --git a/src/dispmanx-helper.h b/src/dispmanx-helper.h new file mode 100644 index 00000000..6e079fca --- /dev/null +++ b/src/dispmanx-helper.h @@ -0,0 +1,59 @@ +#pragma once + +// VC includes +#include + +template +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); + + void* image_ptr = hyperion.image().memptr(); + const uint32_t pitch = width * 3; + + timespec updateInterval; + updateInterval.tv_sec = 0; + updateInterval.tv_nsec = 100000000; + while(running) + { + vc_dispmanx_snapshot(display, resource, VC_IMAGE_ROT0); + vc_dispmanx_resource_read_data(resource, &rectangle, image_ptr, pitch); + + hyperion.commit(); + + nanosleep(&updateInterval, NULL); + } + + // Clean up resources + vc_dispmanx_resource_delete(resource); + vc_dispmanx_display_close(display); + + // De-init BCM + bcm_host_deinit(); + + return 0; +} diff --git a/src/dispmanx-png/dispmanx-png.cpp b/src/dispmanx-png/dispmanx-png.cpp index 27ef568b..8aa2c6b8 100644 --- a/src/dispmanx-png/dispmanx-png.cpp +++ b/src/dispmanx-png/dispmanx-png.cpp @@ -2,12 +2,11 @@ // STL includes #include -// VC includes -#include - // Hyperion includes #include +#include "../dispmanx-helper.h" + static volatile bool sRunning = true; void signal_handler(int signum) @@ -16,68 +15,6 @@ void signal_handler(int signum) sRunning = false; } -template -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(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*/) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b3f9e97d..aea05b4e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -20,6 +20,10 @@ add_executable(Test2BobLight target_link_libraries(Test2BobLight bob2hyperion) +add_executable(TestRgbImage + TestRgbImage.cpp) +target_link_libraries(TestRgbImage + hyperion-utils) # Find the libPNG find_package(PNG REQUIRED QUIET) @@ -27,11 +31,11 @@ find_package(PNG REQUIRED QUIET) # Add additional includes dirs include_directories(${PNG_INCLUDE_DIR}) -if(PNG_FOUND) +#if(PNG_FOUND) add_executable(TestHyperionPng TestHyperionPng.cpp) target_link_libraries(TestHyperionPng - bob2hyperion-png) -endif(PNG_FOUND) + hyperion-png) +#endif(PNG_FOUND) diff --git a/test/TestHyperionPng.cpp b/test/TestHyperionPng.cpp index 39da58d3..ca701f55 100644 --- a/test/TestHyperionPng.cpp +++ b/test/TestHyperionPng.cpp @@ -2,42 +2,44 @@ // STL includes #include -// Boblight includes -#include +// HyperionPNG includes +#include + +template +void process(Hyperion_T& hyperion) +{ + hyperion.setInputSize(64, 64); + + // Obtain reference to buffer + RgbImage& image = hyperion.image(); + + // Write some data to the image + std::cout << "Write data to buffer-image" << std::endl; + for (unsigned y=0; y + +int main() +{ + std::cout << "Constructing image" << std::endl; + RgbImage image(64, 64, RgbColor::BLACK); + + std::cout << "Writing image" << std::endl; + for (unsigned y=0; y<64; ++y) + { + for (unsigned x=0; x<64; ++x) + { + image(x,y) = RgbColor::RED; + } + } + + std::cout << "Finished (destruction will be performed)" << std::endl; + + return 0; +}