From f2eef4eceac7a1bd28aa767b6a128084e8e98e84 Mon Sep 17 00:00:00 2001 From: Portisch Date: Wed, 27 Mar 2019 09:07:20 +0100 Subject: [PATCH] Amlogic: implement CAP_FLAG_AT_END mode The OSD will use 20Hz for frame capture frequency The video capture frequency is based on the amlvideodri capture module --- include/grabber/AmlogicWrapper.h | 3 +-- include/hyperion/GrabberWrapper.h | 2 +- libsrc/grabber/amlogic/AmlogicGrabber.cpp | 10 +++++----- libsrc/grabber/amlogic/AmlogicWrapper.cpp | 4 ++-- libsrc/grabber/amlogic/Amvideocap.h | 1 + src/hyperion-aml/AmlogicWrapper.cpp | 24 +++++++++++++---------- src/hyperion-aml/AmlogicWrapper.h | 13 ++++++------ src/hyperion-aml/hyperion-aml.cpp | 3 +-- src/hyperiond/hyperiond.cpp | 2 +- 9 files changed, 32 insertions(+), 30 deletions(-) diff --git a/include/grabber/AmlogicWrapper.h b/include/grabber/AmlogicWrapper.h index 0f241162..5df6c95a 100644 --- a/include/grabber/AmlogicWrapper.h +++ b/include/grabber/AmlogicWrapper.h @@ -17,9 +17,8 @@ public: /// /// @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] /// - AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz); + AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight); /// /// Destructor of this dispmanx frame grabber. Releases any claimed resources. diff --git a/include/hyperion/GrabberWrapper.h b/include/hyperion/GrabberWrapper.h index 7c3bb53b..72deaa90 100644 --- a/include/hyperion/GrabberWrapper.h +++ b/include/hyperion/GrabberWrapper.h @@ -24,7 +24,7 @@ class GrabberWrapper : public QObject { Q_OBJECT public: - GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned width, unsigned height, const unsigned updateRate_Hz); + GrabberWrapper(QString grabberName, Grabber * ggrabber, unsigned width, unsigned height, const unsigned updateRate_Hz = 0); virtual ~GrabberWrapper(); diff --git a/libsrc/grabber/amlogic/AmlogicGrabber.cpp b/libsrc/grabber/amlogic/AmlogicGrabber.cpp index 5ef1e3ea..f8581177 100644 --- a/libsrc/grabber/amlogic/AmlogicGrabber.cpp +++ b/libsrc/grabber/amlogic/AmlogicGrabber.cpp @@ -109,6 +109,8 @@ int AmlogicGrabber::grabFrame(Image & image) _lastError = 0; } _fbGrabber.grabFrame(image); + + usleep(50 * 1000); } return 0; @@ -129,11 +131,11 @@ int AmlogicGrabber::grabFrame_amvideocap(Image & image) long r1 = ioctl(_captureDev, AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH, _width); long r2 = ioctl(_captureDev, AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT, _height); + long r3 = ioctl(_captureDev, AMVIDEOCAP_IOW_SET_WANTFRAME_AT_FLAGS, CAP_FLAG_AT_END); - if (r1<0 || r2<0 || _height==0 || _width==0) + if (r1<0 || r2<0 || r3<0 || _height==0 || _width==0) { - ErrorIf(_lastError != 2,_log,"Failed to configure capture size (%d - %s)", errno, strerror(errno)); - closeDev(_captureDev); + ErrorIf(_lastError != 2,_log,"Failed to configure capture device (%d - %s)", errno, strerror(errno)); _lastError = 2; return -1; } @@ -145,7 +147,6 @@ int AmlogicGrabber::grabFrame_amvideocap(Image & image) if (bytesRead < 0) { ErrorIf(_lastError != 3, _log,"Read of device failed: %d - %s", errno, strerror(errno)); - closeDev(_captureDev); _lastError = 3; return -1; } @@ -153,7 +154,6 @@ int AmlogicGrabber::grabFrame_amvideocap(Image & image) { // Read of snapshot failed ErrorIf(_lastError != 4, _log,"Capture failed to grab entire image [bytesToRead(%d) != bytesRead(%d)]", _bytesToRead, bytesRead); - closeDev(_captureDev); _lastError = 4; return -1; } diff --git a/libsrc/grabber/amlogic/AmlogicWrapper.cpp b/libsrc/grabber/amlogic/AmlogicWrapper.cpp index 205787e8..49028229 100644 --- a/libsrc/grabber/amlogic/AmlogicWrapper.cpp +++ b/libsrc/grabber/amlogic/AmlogicWrapper.cpp @@ -1,7 +1,7 @@ #include -AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz) - : GrabberWrapper("AmLogic", &_grabber, grabWidth, grabHeight, updateRate_Hz) +AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight) + : GrabberWrapper("AmLogic", &_grabber, grabWidth, grabHeight) , _grabber(grabWidth, grabHeight) {} diff --git a/libsrc/grabber/amlogic/Amvideocap.h b/libsrc/grabber/amlogic/Amvideocap.h index 5dc2fb7b..828aa895 100644 --- a/libsrc/grabber/amlogic/Amvideocap.h +++ b/libsrc/grabber/amlogic/Amvideocap.h @@ -14,6 +14,7 @@ // #define AMVIDEOCAP_IOW_SET_WANTFRAME_FORMAT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x01, int) #define AMVIDEOCAP_IOW_SET_WANTFRAME_WIDTH _IOW(AMVIDEOCAP_IOC_MAGIC, 0x02, int) #define AMVIDEOCAP_IOW_SET_WANTFRAME_HEIGHT _IOW(AMVIDEOCAP_IOC_MAGIC, 0x03, int) +#define AMVIDEOCAP_IOW_SET_WANTFRAME_AT_FLAGS _IOW(AMVIDEOCAP_IOC_MAGIC, 0x06, int) #define _A_M 'S' #define AMSTREAM_IOC_GET_VIDEO_DISABLE _IOR((_A_M), 0x48, int) diff --git a/src/hyperion-aml/AmlogicWrapper.cpp b/src/hyperion-aml/AmlogicWrapper.cpp index 54228208..4c7c2013 100644 --- a/src/hyperion-aml/AmlogicWrapper.cpp +++ b/src/hyperion-aml/AmlogicWrapper.cpp @@ -2,15 +2,15 @@ // Hyperion-AmLogic includes #include "AmlogicWrapper.h" -AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz) : - _timer(this), +// Linux includes +#include + +AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight) : + _thread(this), _grabber(grabWidth, grabHeight) { - _timer.setSingleShot(false); - _timer.setInterval(updateRate_Hz); - // Connect capturing to the timeout signal of the timer - connect(&_timer, SIGNAL(timeout()), this, SLOT(capture())); + connect(&_thread, SIGNAL (started()), this, SLOT(capture())); } const Image & AmlogicWrapper::getScreenshot() @@ -21,16 +21,20 @@ const Image & AmlogicWrapper::getScreenshot() void AmlogicWrapper::start() { - _timer.start(); + _thread.start(); } void AmlogicWrapper::stop() { - _timer.stop(); + _thread.quit(); } void AmlogicWrapper::capture() { - _grabber.grabFrame(_screenshot); - emit sig_screenshot(_screenshot); + while (_thread.isRunning()) + { + _grabber.grabFrame(_screenshot); + emit sig_screenshot(_screenshot); + usleep(1 * 1000); + } } diff --git a/src/hyperion-aml/AmlogicWrapper.h b/src/hyperion-aml/AmlogicWrapper.h index 7ddbcda1..7fe9334d 100644 --- a/src/hyperion-aml/AmlogicWrapper.h +++ b/src/hyperion-aml/AmlogicWrapper.h @@ -1,6 +1,6 @@ // QT includes -#include +#include // Hyperion-Dispmanx includes #include @@ -9,12 +9,12 @@ class AmlogicWrapper : public QObject { Q_OBJECT public: - AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz); + AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight); const Image & getScreenshot(); /// - /// Starts the timed capturing of screenshots + /// Starts the threaded capturing of screenshots /// void start(); @@ -25,18 +25,17 @@ signals: private slots: /// - /// Performs a single screenshot capture and publishes the capture screenshot on the screenshot signal. + /// Performs screenshot captures and publishes the capture screenshot on the screenshot signal. /// void capture(); private: - /// The QT timer to generate capture-publish events - QTimer _timer; + /// The QT thread to generate capture-publish events + QThread _thread; /// The grabber for creating screenshots AmlogicGrabber _grabber; // image buffers Image _screenshot; - }; diff --git a/src/hyperion-aml/hyperion-aml.cpp b/src/hyperion-aml/hyperion-aml.cpp index 5179f781..0d9921e0 100644 --- a/src/hyperion-aml/hyperion-aml.cpp +++ b/src/hyperion-aml/hyperion-aml.cpp @@ -37,7 +37,6 @@ int main(int argc, char ** argv) // create the option parser and initialize all parser Parser parser("AmLogic capture application for Hyperion. Will automatically search a Hyperion server if -a option isn't used. Please note that if you have more than one server running it's more or less random which one will be used."); - IntOption & argFps = parser.add ('f', "framerate", "Capture frame rate [default: %1]", "10", 1, 25); IntOption & argWidth = parser.add (0x0, "width", "Width of the captured image [default: %1]", "160", 160, 4096); IntOption & argHeight = parser.add (0x0, "height", "Height of the captured image [default: %1]", "160", 160, 4096); BooleanOption & argScreenshot = parser.add(0x0, "screenshot", "Take a single screenshot, save it to file and quit"); @@ -55,7 +54,7 @@ int main(int argc, char ** argv) parser.showHelp(0); } - AmlogicWrapper amlWrapper(argWidth.getInt(parser), argHeight.getInt(parser), 1000 / argFps.getInt(parser)); + AmlogicWrapper amlWrapper(argWidth.getInt(parser), argHeight.getInt(parser)); if (parser.isSet(argScreenshot)) { diff --git a/src/hyperiond/hyperiond.cpp b/src/hyperiond/hyperiond.cpp index d3cfd85c..e5ae1351 100644 --- a/src/hyperiond/hyperiond.cpp +++ b/src/hyperiond/hyperiond.cpp @@ -457,7 +457,7 @@ void HyperionDaemon::createGrabberDispmanx() void HyperionDaemon::createGrabberAmlogic() { #ifdef ENABLE_AMLOGIC - _amlGrabber = new AmlogicWrapper(_grabber_width, _grabber_height, _grabber_frequency); + _amlGrabber = new AmlogicWrapper(_grabber_width, _grabber_height); _amlGrabber->setCropping(_grabber_cropLeft, _grabber_cropRight, _grabber_cropTop, _grabber_cropBottom); // connect to HyperionDaemon signal