mirror of
				https://github.com/hyperion-project/hyperion.ng.git
				synced 2025-03-01 10:33:28 +00:00 
			
		
		
		
	Added code for amlogic grabber.
Former-commit-id: fdb9c1c5d8ce02d531d2008057e22f1ae8f7d04e
This commit is contained in:
		| @@ -7,37 +7,40 @@ cmake_minimum_required(VERSION 2.8) | ||||
| #set(CMAKE_TOOLCHAIN_FILE /opt/raspberrypi/Toolchain-RaspberryPi.cmake) | ||||
|  | ||||
| # set the build options | ||||
| option(ENABLE_AMLOGIC "Enable the AMLOGIC video grabber" OFF) | ||||
| message(STATUS "ENABLE_AMLOGIC = " ${ENABLE_AMLOGIC}) | ||||
|  | ||||
| option(ENABLE_DISPMANX "Enable the RPi dispmanx grabber" ON) | ||||
| message(STATUS "ENABLE_DISPMANX = " ${ENABLE_DISPMANX}) | ||||
|  | ||||
| option(ENABLE_SPIDEV   "Enable the SPIDEV device" ON) | ||||
| message(STATUS "ENABLE_SPIDEV   = " ${ENABLE_SPIDEV}) | ||||
|  | ||||
| option(ENABLE_WS2812BPWM   "Enable the WS2812b-PWM device" OFF) | ||||
| message(STATUS "ENABLE_WS2812BPWM = " ${ENABLE_WS2812BPWM}) | ||||
|  | ||||
| option(ENABLE_V4L2 "Enable the V4L2 grabber" ON) | ||||
| message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2}) | ||||
|  | ||||
| option(ENABLE_X11 "Enable the X11 grabber" OFF) | ||||
| message(STATUS "ENABLE_X11 = " ${ENABLE_X11}) | ||||
|  | ||||
| option(ENABLE_TINKERFORGE "Enable the TINKERFORGE device" ON) | ||||
| message(STATUS "ENABLE_TINKERFORGE = " ${ENABLE_TINKERFORGE}) | ||||
|  | ||||
| option(ENABLE_PROTOBUF "Enable PROTOBUF server" ON) | ||||
| message(STATUS "ENABLE_PROTOBUF = " ${ENABLE_PROTOBUF}) | ||||
|  | ||||
| if(ENABLE_V4L2 AND NOT ENABLE_PROTOBUF) | ||||
| 	message(FATAL_ERROR "V4L2 grabber requires PROTOBUF. Disable V4L2 or enable PROTOBUF") | ||||
| endif(ENABLE_V4L2 AND NOT ENABLE_PROTOBUF) | ||||
|  | ||||
| option(ENABLE_FB "Enable the framebuffer grabber" OFF) | ||||
| message(STATUS "ENABLE_FB = " ${ENABLE_FB}) | ||||
|  | ||||
| option(ENABLE_OSX "Enable the osx grabber" OFF) | ||||
| message(STATUS "ENABLE_OSX = " ${ENABLE_OSX}) | ||||
|  | ||||
| option(ENABLE_PROTOBUF "Enable PROTOBUF server" ON) | ||||
| message(STATUS "ENABLE_PROTOBUF = " ${ENABLE_PROTOBUF}) | ||||
|  | ||||
| option(ENABLE_SPIDEV   "Enable the SPIDEV device" ON) | ||||
| message(STATUS "ENABLE_SPIDEV   = " ${ENABLE_SPIDEV}) | ||||
|  | ||||
| option(ENABLE_TINKERFORGE "Enable the TINKERFORGE device" ON) | ||||
| message(STATUS "ENABLE_TINKERFORGE = " ${ENABLE_TINKERFORGE}) | ||||
|  | ||||
| option(ENABLE_V4L2 "Enable the V4L2 grabber" ON) | ||||
| message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2}) | ||||
|  | ||||
| option(ENABLE_WS2812BPWM   "Enable the WS2812b-PWM device" OFF) | ||||
| message(STATUS "ENABLE_WS2812BPWM = " ${ENABLE_WS2812BPWM}) | ||||
|  | ||||
| option(ENABLE_X11 "Enable the X11 grabber" OFF) | ||||
| message(STATUS "ENABLE_X11 = " ${ENABLE_X11}) | ||||
|  | ||||
| if(ENABLE_V4L2 AND NOT ENABLE_PROTOBUF) | ||||
| 	message(FATAL_ERROR "V4L2 grabber requires PROTOBUF. Disable V4L2 or enable PROTOBUF") | ||||
| endif(ENABLE_V4L2 AND NOT ENABLE_PROTOBUF) | ||||
|  | ||||
| if(ENABLE_FB AND ENABLE_DISPMANX) | ||||
| 	message(FATAL_ERROR "dispmanx grabber and framebuffer grabber cannot be used at the same time") | ||||
| endif(ENABLE_FB AND ENABLE_DISPMANX) | ||||
| @@ -89,10 +92,6 @@ find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED QUIET) | ||||
| find_package(libusb-1.0 REQUIRED) | ||||
| find_package(Threads REQUIRED) | ||||
|  | ||||
| if (ENABLE_TINKERFORGE) | ||||
| 	#find_package(libtinkerforge-1.0 REQUIRED) | ||||
| endif (ENABLE_TINKERFORGE) | ||||
|  | ||||
| include(${QT_USE_FILE}) | ||||
| add_definitions(${QT_DEFINITIONS}) | ||||
| # TODO[TvdZ]: This linking directory should only be added if we are cross compiling | ||||
|   | ||||
							
								
								
									
										94
									
								
								include/grabber/AmlogicWrapper.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								include/grabber/AmlogicWrapper.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,94 @@ | ||||
| #pragma once | ||||
|  | ||||
| // QT includes | ||||
| #include <QObject> | ||||
| #include <QTimer> | ||||
|  | ||||
| // Utils includes | ||||
| #include <utils/Image.h> | ||||
| #include <utils/ColorRgb.h> | ||||
| #include <utils/ColorRgba.h> | ||||
| #include <utils/GrabbingMode.h> | ||||
| #include <utils/VideoMode.h> | ||||
|  | ||||
| // Forward class declaration | ||||
| class AmlogicGrabber; | ||||
| class Hyperion; | ||||
| class ImageProcessor; | ||||
|  | ||||
| /// | ||||
| /// The DispmanxWrapper uses an instance of the DispmanxFrameGrabber to obtain ImageRgb's from the | ||||
| /// displayed content. This ImageRgb is processed to a ColorRgb for each led and commmited to the | ||||
| /// attached Hyperion. | ||||
| /// | ||||
| class AmlogicWrapper : public QObject | ||||
| { | ||||
| 	Q_OBJECT | ||||
| public: | ||||
| 	/// | ||||
| 	/// Constructs the dispmanx frame grabber with a specified grab size and update rate. | ||||
| 	/// | ||||
| 	/// @param[in] grabWidth  The width of the grabbed image [pixels] | ||||
| 	/// @param[in] grabHeight  The height of the grabbed images [pixels] | ||||
| 	/// @param[in] updateRate_Hz  The image grab rate [Hz] | ||||
| 	/// @param[in] hyperion  The instance of Hyperion used to write the led values | ||||
| 	/// | ||||
| 	AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, Hyperion * hyperion); | ||||
|  | ||||
| 	/// | ||||
| 	/// Destructor of this dispmanx frame grabber. Releases any claimed resources. | ||||
| 	/// | ||||
| 	virtual ~AmlogicWrapper(); | ||||
|  | ||||
| public slots: | ||||
| 	/// | ||||
| 	/// Starts the grabber wich produces led values with the specified update rate | ||||
| 	/// | ||||
| 	void start(); | ||||
|  | ||||
| 	/// | ||||
| 	/// Performs a single frame grab and computes the led-colors | ||||
| 	/// | ||||
| 	void action(); | ||||
|  | ||||
| 	/// | ||||
| 	/// Stops the grabber | ||||
| 	/// | ||||
| 	void stop(); | ||||
|  | ||||
| 	/// | ||||
| 	/// Set the grabbing mode | ||||
| 	/// @param[in] mode The new grabbing mode | ||||
| 	/// | ||||
| 	void setGrabbingMode(const GrabbingMode mode); | ||||
|  | ||||
| 	/// | ||||
| 	/// Set the video mode (2D/3D) | ||||
| 	/// @param[in] mode The new video mode | ||||
| 	/// | ||||
| 	void setVideoMode(const VideoMode videoMode); | ||||
|  | ||||
| private: | ||||
| 	/// The update rate [Hz] | ||||
| 	const int _updateInterval_ms; | ||||
| 	/// The timeout of the led colors [ms] | ||||
| 	const int _timeout_ms; | ||||
| 	/// The priority of the led colors | ||||
| 	const int _priority; | ||||
|  | ||||
| 	/// The timer for generating events with the specified update rate | ||||
| 	QTimer _timer; | ||||
|  | ||||
| 	/// The image used for grabbing frames | ||||
| 	Image<ColorRgb> _image; | ||||
| 	/// The actual grabber | ||||
| 	AmlogicGrabber * _frameGrabber; | ||||
| 	/// The processor for transforming images to led colors | ||||
| 	ImageProcessor * _processor; | ||||
|  | ||||
| 	/// The list with computed led colors | ||||
| 	std::vector<ColorRgb> _ledColors; | ||||
|  | ||||
| 	/// Pointer to Hyperion for writing led values | ||||
| 	Hyperion * _hyperion; | ||||
| }; | ||||
| @@ -1,3 +1,7 @@ | ||||
| if (ENABLE_AMLOGIC) | ||||
| 	add_subdirectory(amlogic) | ||||
| endif (ENABLE_AMLOGIC) | ||||
|  | ||||
| if (ENABLE_DISPMANX) | ||||
| 	add_subdirectory(dispmanx) | ||||
| endif (ENABLE_DISPMANX) | ||||
| @@ -6,6 +10,10 @@ if (ENABLE_FB) | ||||
| 	add_subdirectory(framebuffer) | ||||
| endif (ENABLE_FB) | ||||
|  | ||||
| if (ENABLE_OSX) | ||||
| 	add_subdirectory(osx) | ||||
| endif() | ||||
|  | ||||
| if (ENABLE_V4L2) | ||||
| 	add_subdirectory(v4l2) | ||||
| endif (ENABLE_V4L2) | ||||
| @@ -13,7 +21,3 @@ endif (ENABLE_V4L2) | ||||
| if (ENABLE_X11) | ||||
| 	add_subdirectory(x11) | ||||
| endif() | ||||
|  | ||||
| if (ENABLE_OSX) | ||||
| 	add_subdirectory(osx) | ||||
| endif() | ||||
|   | ||||
							
								
								
									
										87
									
								
								libsrc/grabber/amlogic/AmlogicGrabber.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										87
									
								
								libsrc/grabber/amlogic/AmlogicGrabber.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,87 @@ | ||||
|  | ||||
| // STL includes | ||||
| #include <cassert> | ||||
| #include <iostream> | ||||
|  | ||||
| // Linux includes | ||||
| #include <errno.h> | ||||
| #include <fcntl.h> | ||||
| #include <unistd.h> | ||||
| #include <sys/ioctl.h> | ||||
| #include <sys/stat.h> | ||||
| #include <sys/types.h> | ||||
|  | ||||
| // Local includes | ||||
| #include "AmlogicGrabber.h" | ||||
|  | ||||
| // Flags copied from 'linux/amlogic/amports/amvideocap.h' at https://github.com/codesnake/linux-amlogic/ | ||||
| #define AMVIDEOCAP_IOC_MAGIC 'V' | ||||
| #define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH      		_IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int) | ||||
| #define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT     		_IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int) | ||||
|  | ||||
| AmlogicGrabber::AmlogicGrabber(const unsigned width, const unsigned height) : | ||||
| 	_width(width), | ||||
| 	_height(height), | ||||
| 	_amlogicCaptureDev(-1) | ||||
| { | ||||
| 	_amlogicCaptureDev = open("/dev/amvideocap0", O_RDONLY, 0); | ||||
| 	if (_amlogicCaptureDev == -1) | ||||
| 	{ | ||||
| 		std::cerr << "[" << __PRETTY_FUNCTION__ << "] Failed to open the AMLOGIC device (" << errno << ")" << std::endl; | ||||
| 		return; | ||||
| 	} | ||||
| 	 | ||||
| 	if (ioctl(_amlogicCaptureDev, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH,  _width)  == -1 ||  | ||||
| 	    ioctl(_amlogicCaptureDev, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, _height) == -1) | ||||
| 	{ | ||||
| 		// Failed to configure frame width | ||||
| 		std::cerr << "[" << __PRETTY_FUNCTION__ << "] Failed to configure capture size (" << errno << ")" << std::endl; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| AmlogicGrabber::~AmlogicGrabber() | ||||
| { | ||||
| 	if (_amlogicCaptureDev != -1) | ||||
| 	{ | ||||
| 		if (close(_amlogicCaptureDev) == -1) | ||||
| 		{ | ||||
| 			std::cerr << "[" << __PRETTY_FUNCTION__ << "] Failed to close AMLOGIC device (" << errno << ")" << std::endl; | ||||
| 		} | ||||
| 		_amlogicCaptureDev = -1; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AmlogicGrabber::setVideoMode(const VideoMode videoMode) | ||||
| { | ||||
| 	switch (videoMode) { | ||||
| 	case VIDEO_3DSBS: | ||||
| 		//vc_dispmanx_rect_set(&_rectangle, 0, 0, _width/2, _height); | ||||
| 		break; | ||||
| 	case VIDEO_3DTAB: | ||||
| 		//vc_dispmanx_rect_set(&_rectangle, 0, 0, _width, _height/2); | ||||
| 		break; | ||||
| 	case VIDEO_2D: | ||||
| 	default: | ||||
| 		//vc_dispmanx_rect_set(&_rectangle, 0, 0, _width, _height); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AmlogicGrabber::grabFrame(Image<ColorRgb> & image) | ||||
| { | ||||
| 	// resize the given image if needed | ||||
| 	if (image.width() != unsigned(_rectangle.width) || image.height() != unsigned(_rectangle.height)) | ||||
| 	{ | ||||
| 		image.resize(_rectangle.width, _rectangle.height); | ||||
| 	} | ||||
| 	 | ||||
| 	// Read the snapshot into the memory | ||||
| 	void * image_ptr = image.memptr(); | ||||
| 	const size_t bytesToRead = _width * _height * sizeof(ColorRgb); | ||||
| 	const size_t bytesRead   = pread(amlogicCaptureDev, image_ptr, bytesToRead, 0) | ||||
| 	if (bytesToRead != bytesRead) | ||||
| 	{ | ||||
| 		// Read of snapshot failed | ||||
| 		std::cerr << "[" << __PRETTY_FUNCTION__ << "] Capture failed to grab entire image [bytesToRead(" << bytesToRead << ") != bytesRead(" << bytesRead << ")]" << std::endl; | ||||
| 	} | ||||
| } | ||||
							
								
								
									
										52
									
								
								libsrc/grabber/amlogic/AmlogicGrabber.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										52
									
								
								libsrc/grabber/amlogic/AmlogicGrabber.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,52 @@ | ||||
| #pragma once | ||||
|  | ||||
| // STL includes | ||||
| #include <cstdint> | ||||
|  | ||||
| // Utils includes | ||||
| #include <utils/Image.h> | ||||
| #include <utils/ColorRgba.h> | ||||
| #include <utils/VideoMode.h> | ||||
|  | ||||
| /// | ||||
| /// The DispmanxFrameGrabber is used for creating snapshots of the display (screenshots) with a | ||||
| /// downsized and scaled resolution. | ||||
| /// | ||||
| class AmlogicGrabber | ||||
| { | ||||
| public: | ||||
| 	/// | ||||
| 	/// Construct a AmlogicGrabber that will capture snapshots with specified dimensions. | ||||
| 	/// | ||||
| 	/// @param[in] width  The width of the captured screenshot | ||||
| 	/// @param[in] height The heigth of the captured screenshot | ||||
| 	/// | ||||
| 	AmlogicGrabber(const unsigned width, const unsigned height); | ||||
| 	~AmlogicGrabber(); | ||||
|  | ||||
| 	/// | ||||
| 	/// Set the video mode (2D/3D) | ||||
| 	/// @param[in] mode The new video mode | ||||
| 	/// | ||||
| 	void setVideoMode(const VideoMode videoMode); | ||||
|  | ||||
| 	/// | ||||
| 	/// Captures a single snapshot of the display and writes the data to the given image. The | ||||
| 	/// provided image should have the same dimensions as the configured values (_width and | ||||
| 	/// _height) | ||||
| 	/// | ||||
| 	/// @param[out] image  The snapped screenshot (should be initialized with correct width and | ||||
| 	/// height) | ||||
| 	/// | ||||
| 	void grabFrame(Image<ColorRgba> & image); | ||||
|  | ||||
| private: | ||||
|  | ||||
| 	/// With of the captured snapshot [pixels] | ||||
| 	const unsigned _width; | ||||
| 	/// Height of the captured snapshot [pixels] | ||||
| 	const unsigned _height; | ||||
| 	 | ||||
| 	/** The snapshot/capture device of the amlogic video chip */ | ||||
| 	int _amlogicCaptureDev; | ||||
| }; | ||||
							
								
								
									
										88
									
								
								libsrc/grabber/amlogic/AmlogicWrapper.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										88
									
								
								libsrc/grabber/amlogic/AmlogicWrapper.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,88 @@ | ||||
| // QT includes | ||||
| #include <QDebug> | ||||
| #include <QDateTime> | ||||
|  | ||||
| // Hyperion includes | ||||
| #include <hyperion/Hyperion.h> | ||||
| #include <hyperion/ImageProcessorFactory.h> | ||||
| #include <hyperion/ImageProcessor.h> | ||||
|  | ||||
| // Amlogic grabber includes | ||||
| #include <grabber/AmlogicWrapper.h> | ||||
| #include "AmlogicGrabber.h" | ||||
|  | ||||
|  | ||||
| AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz, Hyperion * hyperion) : | ||||
| 	_updateInterval_ms(1000/updateRate_Hz), | ||||
| 	_timeout_ms(2 * _updateInterval_ms), | ||||
| 	_priority(1000), | ||||
| 	_timer(), | ||||
| 	_image(grabWidth, grabHeight), | ||||
| 	_frameGrabber(new DispmanxFrameGrabber(grabWidth, grabHeight)), | ||||
| 	_processor(ImageProcessorFactory::getInstance().newImageProcessor()), | ||||
| 	_ledColors(hyperion->getLedCount(), ColorRgb{0,0,0}), | ||||
| 	_hyperion(hyperion) | ||||
| { | ||||
| 	// Configure the timer to generate events every n milliseconds | ||||
| 	_timer.setInterval(_updateInterval_ms); | ||||
| 	_timer.setSingleShot(false); | ||||
|  | ||||
| 	_processor->setSize(grabWidth, grabHeight); | ||||
|  | ||||
| 	// Connect the QTimer to this | ||||
| 	QObject::connect(&_timer, SIGNAL(timeout()), this, SLOT(action())); | ||||
| } | ||||
|  | ||||
| AmlogicWrapper::~AmlogicWrapper() | ||||
| { | ||||
| 	// Cleanup used resources (ImageProcessor and FrameGrabber) | ||||
| 	delete _processor; | ||||
| 	delete _frameGrabber; | ||||
| } | ||||
|  | ||||
| void AmlogicWrapper::start() | ||||
| { | ||||
| 	// Start the timer with the pre configured interval | ||||
| 	_timer.start(); | ||||
| } | ||||
|  | ||||
| void AmlogicWrapper::action() | ||||
| { | ||||
| 	// Grab frame into the allocated image | ||||
| 	_frameGrabber->grabFrame(_image); | ||||
|  | ||||
| 	_processor->process(_image, _ledColors); | ||||
|  | ||||
| 	_hyperion->setColors(_priority, _ledColors, _timeout_ms); | ||||
| } | ||||
| void AmlogicWrapper::stop() | ||||
| { | ||||
| 	// Stop the timer, effectivly stopping the process | ||||
| 	_timer.stop(); | ||||
| } | ||||
|  | ||||
| void AmlogicWrapper::setGrabbingMode(const GrabbingMode mode) | ||||
| { | ||||
| 	switch (mode) | ||||
| 	{ | ||||
| 	case GRABBINGMODE_VIDEO: | ||||
| //		_frameGrabber->setFlags(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL); | ||||
| 		start(); | ||||
| 		break; | ||||
| 	case GRABBINGMODE_AUDIO: | ||||
| 	case GRABBINGMODE_PHOTO: | ||||
| 	case GRABBINGMODE_MENU: | ||||
| 	case GRABBINGMODE_INVALID: | ||||
| //		_frameGrabber->setFlags(0); | ||||
| 		start(); | ||||
| 		break; | ||||
| 	case GRABBINGMODE_OFF: | ||||
| 		stop(); | ||||
| 		break; | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void AmlogicWrapper::setVideoMode(const VideoMode mode) | ||||
| { | ||||
| 	_frameGrabber->setVideoMode(mode); | ||||
| } | ||||
							
								
								
									
										29
									
								
								libsrc/grabber/amlogic/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								libsrc/grabber/amlogic/CMakeLists.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,29 @@ | ||||
|  | ||||
| # Define the current source locations | ||||
| SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber) | ||||
| SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/amlogic) | ||||
|  | ||||
| # Group the headers that go through the MOC compiler | ||||
| SET(AmlogicQT_HEADERS ${CURRENT_HEADER_DIR}/AmlogicWrapper.h) | ||||
|  | ||||
| SET(AmlogicHEADERS | ||||
| 		${CURRENT_SOURCE_DIR}/AmlogicGrabber.h | ||||
| ) | ||||
|  | ||||
| SET(AmlogicSOURCES | ||||
| 		${CURRENT_SOURCE_DIR}/AmlogicWrapper.cpp | ||||
| 		${CURRENT_SOURCE_DIR}/AmlogicFrameGrabber.cpp | ||||
| ) | ||||
|  | ||||
| QT4_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS}) | ||||
|  | ||||
| add_library(amlogic-grabber | ||||
| 		${AmlogicHEADERS} | ||||
| 		${AmlogicQT_HEADERS} | ||||
| 		${AmlogicHEADERS_MOC} | ||||
| 		${AmlogicSOURCES} | ||||
| ) | ||||
|  | ||||
| target_link_libraries(amlogic-grabber | ||||
| 		hyperion | ||||
| 		${QT_LIBRARIES}) | ||||
		Reference in New Issue
	
	Block a user