mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
V4L2/MF changes
This commit is contained in:
@@ -7,25 +7,26 @@
|
||||
#include <utils/PixelFormat.h>
|
||||
#include <utils/ImageResampler.h>
|
||||
|
||||
// TurboJPEG decoder
|
||||
// Determine the cmake options
|
||||
#include <HyperionConfig.h>
|
||||
|
||||
// Turbo JPEG decoder
|
||||
#ifdef HAVE_TURBO_JPEG
|
||||
#include <QImage>
|
||||
#include <QColor>
|
||||
#include <turbojpeg.h>
|
||||
#endif
|
||||
|
||||
/// Encoder thread for USB devices
|
||||
class MFThread : public QObject
|
||||
class EncoderThread : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MFThread();
|
||||
~MFThread();
|
||||
explicit EncoderThread();
|
||||
~EncoderThread();
|
||||
|
||||
void setup(
|
||||
PixelFormat pixelFormat, uint8_t* sharedData,
|
||||
int size, int width, int height, int lineLength,
|
||||
int subsamp, unsigned cropLeft, unsigned cropTop, unsigned cropBottom, unsigned cropRight,
|
||||
unsigned cropLeft, unsigned cropTop, unsigned cropBottom, unsigned cropRight,
|
||||
VideoMode videoMode, FlipMode flipMode, int pixelDecimation);
|
||||
|
||||
void process();
|
||||
@@ -37,15 +38,6 @@ signals:
|
||||
void newFrame(const Image<ColorRgb>& data);
|
||||
|
||||
private:
|
||||
void processImageMjpeg();
|
||||
|
||||
#ifdef HAVE_TURBO_JPEG
|
||||
tjhandle _transform,
|
||||
_decompress;
|
||||
tjscalingfactor* _scalingFactors;
|
||||
tjtransform* _xform;
|
||||
#endif
|
||||
|
||||
PixelFormat _pixelFormat;
|
||||
uint8_t* _localData,
|
||||
*_flipBuffer;
|
||||
@@ -53,7 +45,6 @@ private:
|
||||
_width,
|
||||
_height,
|
||||
_lineLength,
|
||||
_subsamp,
|
||||
_currentFrame,
|
||||
_pixelDecimation;
|
||||
unsigned long _size;
|
||||
@@ -63,6 +54,14 @@ private:
|
||||
_cropRight;
|
||||
FlipMode _flipMode;
|
||||
ImageResampler _imageResampler;
|
||||
|
||||
#ifdef HAVE_TURBO_JPEG
|
||||
tjhandle _transform, _decompress;
|
||||
tjscalingfactor* _scalingFactors;
|
||||
tjtransform* _xform;
|
||||
|
||||
void processImageMjpeg();
|
||||
#endif
|
||||
};
|
||||
|
||||
template <typename TThread> class Thread : public QThread
|
||||
@@ -83,36 +82,36 @@ public:
|
||||
wait();
|
||||
}
|
||||
|
||||
MFThread* thread() const { return qobject_cast<MFThread*>(_thread); }
|
||||
EncoderThread* thread() const { return qobject_cast<EncoderThread*>(_thread); }
|
||||
|
||||
void setup(
|
||||
PixelFormat pixelFormat, uint8_t* sharedData,
|
||||
int size, int width, int height, int lineLength,
|
||||
int subsamp, unsigned cropLeft, unsigned cropTop, unsigned cropBottom, unsigned cropRight,
|
||||
unsigned cropLeft, unsigned cropTop, unsigned cropBottom, unsigned cropRight,
|
||||
VideoMode videoMode, FlipMode flipMode, int pixelDecimation)
|
||||
{
|
||||
auto mfthread = qobject_cast<MFThread*>(_thread);
|
||||
if (mfthread != nullptr)
|
||||
mfthread->setup(pixelFormat, sharedData,
|
||||
auto encThread = qobject_cast<EncoderThread*>(_thread);
|
||||
if (encThread != nullptr)
|
||||
encThread->setup(pixelFormat, sharedData,
|
||||
size, width, height, lineLength,
|
||||
subsamp, cropLeft, cropTop, cropBottom, cropRight,
|
||||
cropLeft, cropTop, cropBottom, cropRight,
|
||||
videoMode, flipMode, pixelDecimation);
|
||||
}
|
||||
|
||||
bool isBusy()
|
||||
{
|
||||
auto mfthread = qobject_cast<MFThread*>(_thread);
|
||||
if (mfthread != nullptr)
|
||||
return mfthread->isBusy();
|
||||
auto encThread = qobject_cast<EncoderThread*>(_thread);
|
||||
if (encThread != nullptr)
|
||||
return encThread->isBusy();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void process()
|
||||
{
|
||||
auto mfthread = qobject_cast<MFThread*>(_thread);
|
||||
if (mfthread != nullptr)
|
||||
mfthread->process();
|
||||
auto encThread = qobject_cast<EncoderThread*>(_thread);
|
||||
if (encThread != nullptr)
|
||||
encThread->process();
|
||||
}
|
||||
|
||||
protected:
|
||||
@@ -123,24 +122,24 @@ protected:
|
||||
}
|
||||
};
|
||||
|
||||
class MFThreadManager : public QObject
|
||||
class EncoderThreadManager : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit MFThreadManager(QObject *parent = nullptr)
|
||||
explicit EncoderThreadManager(QObject *parent = nullptr)
|
||||
: QObject(parent)
|
||||
, _threadCount(qMax(QThread::idealThreadCount(), 1))
|
||||
, _threads(nullptr)
|
||||
{
|
||||
_threads = new Thread<MFThread>*[_threadCount];
|
||||
_threads = new Thread<EncoderThread>*[_threadCount];
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
{
|
||||
_threads[i] = new Thread<MFThread>(new MFThread, this);
|
||||
_threads[i]->setObjectName("MFThread " + i);
|
||||
_threads[i] = new Thread<EncoderThread>(new EncoderThread, this);
|
||||
_threads[i]->setObjectName("Encoder " + i);
|
||||
}
|
||||
}
|
||||
|
||||
~MFThreadManager()
|
||||
~EncoderThreadManager()
|
||||
{
|
||||
if (_threads != nullptr)
|
||||
{
|
||||
@@ -159,7 +158,7 @@ public:
|
||||
{
|
||||
if (_threads != nullptr)
|
||||
for (int i = 0; i < _threadCount; i++)
|
||||
connect(_threads[i]->thread(), &MFThread::newFrame, this, &MFThreadManager::newFrame);
|
||||
connect(_threads[i]->thread(), &EncoderThread::newFrame, this, &EncoderThreadManager::newFrame);
|
||||
}
|
||||
|
||||
void stop()
|
||||
@@ -170,7 +169,7 @@ public:
|
||||
}
|
||||
|
||||
int _threadCount;
|
||||
Thread<MFThread>** _threads;
|
||||
Thread<EncoderThread>** _threads;
|
||||
|
||||
signals:
|
||||
void newFrame(const Image<ColorRgb>& data);
|
@@ -21,12 +21,7 @@
|
||||
#include <hyperion/Grabber.h>
|
||||
|
||||
// decoder thread includes
|
||||
#include <grabber/MFThread.h>
|
||||
|
||||
// TurboJPEG decoder
|
||||
#ifdef HAVE_TURBO_JPEG
|
||||
#include <turbojpeg.h>
|
||||
#endif
|
||||
#include <grabber/EncoderThread.h>
|
||||
|
||||
/// Forward class declaration
|
||||
class SourceReaderCB;
|
||||
@@ -99,7 +94,7 @@ private:
|
||||
HRESULT _hr;
|
||||
IMFSourceReader* _sourceReader;
|
||||
SourceReaderCB* _sourceReaderCB;
|
||||
MFThreadManager* _threadManager;
|
||||
EncoderThreadManager* _threadManager;
|
||||
PixelFormat _pixelFormat,
|
||||
_pixelFormatConfig;
|
||||
int _lineLength,
|
||||
@@ -120,8 +115,4 @@ private:
|
||||
_y_frac_min,
|
||||
_x_frac_max,
|
||||
_y_frac_max;
|
||||
|
||||
#ifdef HAVE_TURBO_JPEG
|
||||
int _subsamp;
|
||||
#endif
|
||||
};
|
||||
|
@@ -17,29 +17,16 @@
|
||||
#include <utils/VideoStandard.h>
|
||||
#include <utils/Components.h>
|
||||
|
||||
#include <HyperionConfig.h> // Required to determine the cmake options
|
||||
// decoder thread includes
|
||||
#include <grabber/EncoderThread.h>
|
||||
|
||||
// Determine the cmake options
|
||||
#include <HyperionConfig.h>
|
||||
|
||||
#if defined(ENABLE_CEC)
|
||||
#include <cec/CECEvent.h>
|
||||
#endif
|
||||
|
||||
// general JPEG decoder includes
|
||||
#ifdef HAVE_JPEG_DECODER
|
||||
#include <QImage>
|
||||
#include <QColor>
|
||||
#endif
|
||||
|
||||
// System JPEG decoder
|
||||
#ifdef HAVE_JPEG
|
||||
#include <jpeglib.h>
|
||||
#include <csetjmp>
|
||||
#endif
|
||||
|
||||
// TurboJPEG decoder
|
||||
#ifdef HAVE_TURBO_JPEG
|
||||
#include <turbojpeg.h>
|
||||
#endif
|
||||
|
||||
///
|
||||
/// Capture class for V4L2 devices
|
||||
///
|
||||
@@ -71,7 +58,7 @@ public:
|
||||
~V4L2Grabber() override;
|
||||
|
||||
int grabFrame(Image<ColorRgb> &);
|
||||
void setDevice(const QString& device);
|
||||
void setDevice(const QString& devicePath, const QString& deviceName);
|
||||
bool setInput(int input) override;
|
||||
bool setWidthHeight(int width, int height) override;
|
||||
void setEncoding(QString enc);
|
||||
@@ -94,9 +81,10 @@ public:
|
||||
QJsonArray discover(const QJsonObject& params);
|
||||
|
||||
public slots:
|
||||
bool prepare() { return true; }
|
||||
bool prepare();
|
||||
bool start();
|
||||
void stop();
|
||||
void newThreadFrame(Image<ColorRgb> image);
|
||||
|
||||
#if defined(ENABLE_CEC)
|
||||
void handleCecEvent(CECEvent event);
|
||||
@@ -110,7 +98,6 @@ private slots:
|
||||
int read_frame();
|
||||
|
||||
private:
|
||||
void enumVideoCaptureDevices();
|
||||
bool init();
|
||||
void uninit();
|
||||
bool open_device();
|
||||
@@ -123,7 +110,6 @@ private:
|
||||
void start_capturing();
|
||||
void stop_capturing();
|
||||
bool process_image(const void *p, int size);
|
||||
void process_image(const uint8_t *p, int size);
|
||||
int xioctl(int request, void *arg);
|
||||
int xioctl(int fileDescriptor, int request, void *arg);
|
||||
|
||||
@@ -151,35 +137,9 @@ private:
|
||||
size_t length;
|
||||
};
|
||||
|
||||
#ifdef HAVE_JPEG
|
||||
struct errorManager
|
||||
{
|
||||
jpeg_error_mgr pub;
|
||||
jmp_buf setjmp_buffer;
|
||||
};
|
||||
|
||||
static void errorHandler(j_common_ptr cInfo)
|
||||
{
|
||||
errorManager* mgr = reinterpret_cast<errorManager*>(cInfo->err);
|
||||
longjmp(mgr->setjmp_buffer, 1);
|
||||
}
|
||||
|
||||
static void outputHandler(j_common_ptr cInfo)
|
||||
{
|
||||
// Suppress fprintf warnings.
|
||||
}
|
||||
|
||||
jpeg_decompress_struct* _decompress;
|
||||
errorManager* _error;
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_TURBO_JPEG
|
||||
tjhandle _decompress = nullptr;
|
||||
int _subsamp;
|
||||
#endif
|
||||
|
||||
private:
|
||||
QString _currentDeviceName, _newDeviceName;
|
||||
QString _currentDevicePath, _currentDeviceName;
|
||||
EncoderThreadManager* _threadManager;
|
||||
QMap<QString, V4L2Grabber::DeviceProperties> _deviceProperties;
|
||||
|
||||
io_method _ioMethod;
|
||||
@@ -187,10 +147,11 @@ private:
|
||||
std::vector<buffer> _buffers;
|
||||
|
||||
PixelFormat _pixelFormat, _pixelFormatConfig;
|
||||
int _pixelDecimation;
|
||||
int _lineLength;
|
||||
int _frameByteSize;
|
||||
|
||||
QAtomicInt _currentFrame;
|
||||
|
||||
// signal detection
|
||||
int _noSignalCounterThreshold;
|
||||
ColorRgb _noSignalThresholdColor;
|
||||
@@ -206,5 +167,6 @@ private:
|
||||
bool _initialized, _reload;
|
||||
|
||||
protected:
|
||||
void enumVideoCaptureDevices();
|
||||
void enumFrameIntervals(QList<int> &framerates, int fileDescriptor, int pixelformat, int width, int height);
|
||||
};
|
||||
|
Reference in New Issue
Block a user