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
This commit is contained in:
Portisch 2019-03-27 09:07:20 +01:00
parent 101855fe4f
commit f2eef4ecea
9 changed files with 32 additions and 30 deletions

View File

@ -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.

View File

@ -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();

View File

@ -109,6 +109,8 @@ int AmlogicGrabber::grabFrame(Image<ColorRgb> & image)
_lastError = 0;
}
_fbGrabber.grabFrame(image);
usleep(50 * 1000);
}
return 0;
@ -129,11 +131,11 @@ int AmlogicGrabber::grabFrame_amvideocap(Image<ColorRgb> & 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<ColorRgb> & 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<ColorRgb> & 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;
}

View File

@ -1,7 +1,7 @@
#include <grabber/AmlogicWrapper.h>
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)
{}

View File

@ -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)

View File

@ -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 <unistd.h>
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<ColorRgb> & AmlogicWrapper::getScreenshot()
@ -21,16 +21,20 @@ const Image<ColorRgb> & AmlogicWrapper::getScreenshot()
void AmlogicWrapper::start()
{
_timer.start();
_thread.start();
}
void AmlogicWrapper::stop()
{
_timer.stop();
_thread.quit();
}
void AmlogicWrapper::capture()
{
while (_thread.isRunning())
{
_grabber.grabFrame(_screenshot);
emit sig_screenshot(_screenshot);
usleep(1 * 1000);
}
}

View File

@ -1,6 +1,6 @@
// QT includes
#include <QTimer>
#include <QThread>
// Hyperion-Dispmanx includes
#include <grabber/AmlogicGrabber.h>
@ -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<ColorRgb> & 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<ColorRgb> _screenshot;
};

View File

@ -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<IntOption> ('f', "framerate", "Capture frame rate [default: %1]", "10", 1, 25);
IntOption & argWidth = parser.add<IntOption> (0x0, "width", "Width of the captured image [default: %1]", "160", 160, 4096);
IntOption & argHeight = parser.add<IntOption> (0x0, "height", "Height of the captured image [default: %1]", "160", 160, 4096);
BooleanOption & argScreenshot = parser.add<BooleanOption>(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))
{

View File

@ -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