Skip to content

Commit

Permalink
feat: SchemaChecker & V4L2 enhancement (#734)
Browse files Browse the repository at this point in the history
* libjpeg-turbo, QJsonSchemaChecker, V4L2 width/height/fps

Signed-off-by: Paulchen-Panther <Paulchen-Panter@protonmail.com>

* Implement hyperion-v4l cli args

* Apply v4l2 settings during runtime

* feat: Provide minimum values for input restriction

* fix: merge mess

Co-authored-by: brindosch <edeltraud70@gmx.de>
  • Loading branch information
Paulchen-Panther and brindosch authored Mar 27, 2020
1 parent 20a5e5d commit 662872d
Show file tree
Hide file tree
Showing 26 changed files with 363 additions and 121 deletions.
33 changes: 21 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -298,23 +298,32 @@ find_package(libusb-1.0 REQUIRED)
find_package(Threads REQUIRED)
add_definitions(${QT_DEFINITIONS})

# Add jpeg library
# Add JPEG library
if (ENABLE_V4L2)
find_package(JPEG)
if (JPEG_FOUND)
add_definitions(-DHAVE_JPEG)
message( STATUS "Using JPEG library: ${JPEG_LIBRARIES}")
include_directories(${JPEG_INCLUDE_DIR})
# Turbo JPEG
find_package(TurboJPEG)
if (TURBOJPEG_FOUND)
add_definitions(-DHAVE_TURBO_JPEG)
message( STATUS "Using Turbo JPEG library: ${TurboJPEG_LIBRARY}")
include_directories(${TurboJPEG_INCLUDE_DIRS})
else()
message( STATUS "JPEG library not found, MJPEG camera format won't work in V4L2 grabber.")
# System JPEG
find_package(JPEG)
if (JPEG_FOUND)
add_definitions(-DHAVE_JPEG)
message( STATUS "Using system JPEG library: ${JPEG_LIBRARIES}")
include_directories(${JPEG_INCLUDE_DIR})
else()
message( STATUS "JPEG library not found, MJPEG camera format won't work in V4L2 grabber.")
endif()
endif (TurboJPEG_FOUND)


if (TURBOJPEG_FOUND OR JPEG_FOUND)
add_definitions(-DHAVE_JPEG_DECODER)
endif()
endif()

# TODO[TvdZ]: This linking directory should only be added if we are cross compiling
#if(NOT APPLE)
# link_directories(${CMAKE_FIND_ROOT_PATH}/lib/arm-linux-gnueabihf)
#endif()

if(APPLE)
set(CMAKE_EXE_LINKER_FLAGS "-framework CoreGraphics")
endif()
Expand Down
2 changes: 1 addition & 1 deletion CompileHowto.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ wget -qN https://raw.github.com/hyperion-project/hyperion.ng/master/bin/scripts/

```
sudo apt-get update
sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libjpeg-dev libqt5sql5-sqlite libssl-dev
sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libjpeg-dev libturbojpeg0-dev libqt5sql5-sqlite libssl-dev
```

**on RPI you need the videocore IV headers**
Expand Down
4 changes: 2 additions & 2 deletions CrossCompileHowto.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,14 @@ Use a clean Raspbian Stretch Lite (on target) and Ubuntu 18/19 (on host) to exec
## On the Target system (here Raspberry Pi)
Install required additional packages.
```
sudo apt-get install qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libjpeg-dev libqt5sql5-sqlite aptitude show qt5-default rsync
sudo apt-get install qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libjpeg-dev libturbojpeg0-dev libqt5sql5-sqlite aptitude show qt5-default rsync
```
## On the Host system (here Ubuntu)
Update the Ubuntu environment to the latest stage and install required additional packages.
```
sudo apt-get update
sudo apt-get upgrade
sudo apt-get -qq -y install git rsync cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libjpeg-dev libqt5sql5-sqlite
sudo apt-get -qq -y install git rsync cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libjpeg-dev libturbojpeg0-dev libqt5sql5-sqlite
```

Refine the target IP or hostname, plus userID as required and set-up cross-compilation environment:
Expand Down
2 changes: 1 addition & 1 deletion bin/compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ CFG="${2:-Release}"
INST="$( [ "${3:-}" = "install" ] && echo true || echo false )"

sudo apt-get update
sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libssl-dev || exit 1
sudo apt-get install git cmake build-essential qtbase5-dev libqt5serialport5-dev libusb-1.0-0-dev libturbojpeg0-dev python3-dev libxrender-dev libavahi-core-dev libavahi-compat-libdnssd-dev libssl-dev || exit 1

if [ -e /dev/vc-cma -a -e /dev/vc-mem ]
then
Expand Down
33 changes: 33 additions & 0 deletions cmake/FindTurboJPEG.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# FindTurboJPEG.cmake
# TURBOJPEG_FOUND
# TurboJPEG_INCLUDE_DIRS
# TurboJPEG_LIBRARY

find_path(TurboJPEG_INCLUDE_DIRS
NAMES turbojpeg.h
PATH_SUFFIXES include
)

find_library(TurboJPEG_LIBRARY
NAMES turbojpeg turbojpeg-static
PATH_SUFFIXES bin lib
)

if(TurboJPEG_INCLUDE_DIRS AND TurboJPEG_LIBRARY)
include(CheckCSourceCompiles)
include(CMakePushCheckState)

cmake_push_check_state(RESET)
list(APPEND CMAKE_REQUIRED_INCLUDES ${TurboJPEG_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${TurboJPEG_LIBRARY})

check_c_source_compiles("#include <turbojpeg.h>\nint main(void) { tjhandle h=tjInitCompress(); return 0; }" TURBOJPEG_WORKS)
cmake_pop_check_state()
endif()

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(TurboJpeg
FOUND_VAR TURBOJPEG_FOUND
REQUIRED_VARS TurboJPEG_LIBRARY TurboJPEG_INCLUDE_DIRS TURBOJPEG_WORKS
TurboJPEG_INCLUDE_DIRS TurboJPEG_LIBRARY
)
4 changes: 4 additions & 0 deletions config/hyperion.config.json.commented
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,8 @@

/// Configuration for the embedded V4L2 grabber
/// * device : V4L2 Device to use [default="auto"] (Auto detection)
/// * width : The width of the grabbed frames (pixels) [default=0]
/// * height : The height of the grabbed frames (pixels) [default=0]
/// * standard : Video standard (PAL/NTSC/SECAM/NO_CHANGE) [default="NO_CHANGE"]
/// * sizeDecimation : Size decimation factor [default=8]
/// * cropLeft : Cropping from the left [default=0]
Expand All @@ -118,6 +120,8 @@
"grabberV4L2" :
{
"device" : "auto",
"width" : 0,
"height" : 0,
"standard" : "NO_CHANGE",
"sizeDecimation" : 8,
"priority" : 240,
Expand Down
33 changes: 18 additions & 15 deletions config/hyperion.config.json.default
Original file line number Diff line number Diff line change
Expand Up @@ -59,21 +59,24 @@

"grabberV4L2" :
{
"device" : "auto",
"standard" : "NO_CHANGE",
"sizeDecimation" : 8,
"cropLeft" : 0,
"cropRight" : 0,
"cropTop" : 0,
"cropBottom" : 0,
"redSignalThreshold" : 5,
"greenSignalThreshold" : 5,
"blueSignalThreshold" : 5,
"signalDetection" : false,
"sDVOffsetMin" : 0.25,
"sDHOffsetMin" : 0.25,
"sDVOffsetMax" : 0.75,
"sDHOffsetMax" : 0.75
"device" : "auto",
"width" : 0,
"height" : 0,
"fps" : 15,
"standard" : "NO_CHANGE",
"sizeDecimation" : 8,
"cropLeft" : 0,
"cropRight" : 0,
"cropTop" : 0,
"cropBottom" : 0,
"redSignalThreshold" : 5,
"greenSignalThreshold" : 5,
"blueSignalThreshold" : 5,
"signalDetection" : false,
"sDVOffsetMin" : 0.25,
"sDHOffsetMin" : 0.25,
"sDVOffsetMax" : 0.75,
"sDHOffsetMax" : 0.75
},

"framegrabber" :
Expand Down
35 changes: 29 additions & 6 deletions include/grabber/V4L2Grabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,23 @@
#include <grabber/VideoStandard.h>
#include <utils/Components.h>

#ifdef HAVE_JPEG
// 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
///
/// @see http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html
Expand All @@ -31,6 +41,9 @@ class V4L2Grabber : public Grabber

public:
V4L2Grabber(const QString & device,
const unsigned width,
const unsigned height,
const unsigned fps,
VideoStandard videoStandard,
PixelFormat pixelFormat,
int pixelDecimation
Expand All @@ -46,11 +59,6 @@ class V4L2Grabber : public Grabber

int grabFrame(Image<ColorRgb> &);

///
/// @brief overwrite Grabber.h implementation, as v4l doesn't use width/height
///
virtual void setWidthHeight(){};

///
/// @brief set new PixelDecimation value to ImageResampler
/// @param pixelDecimation The new pixelDecimation value
Expand Down Expand Up @@ -84,6 +92,16 @@ class V4L2Grabber : public Grabber
///
virtual void setDeviceVideoStandard(QString device, VideoStandard videoStandard);

///
/// @brief overwrite Grabber.h implementation
///
virtual bool setFramerate(int fps);

///
/// @brief overwrite Grabber.h implementation
///
virtual bool setWidthHeight(int width, int height);

public slots:

bool start();
Expand Down Expand Up @@ -173,6 +191,11 @@ private slots:
errorManager* _error;
#endif

#ifdef HAVE_TURBO_JPEG
tjhandle _decompress = nullptr;
int _subsamp;
#endif

private:
QString _deviceName;
std::map<QString,QString> _v4lDevices;
Expand Down
3 changes: 3 additions & 0 deletions include/grabber/V4L2Wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ class V4L2Wrapper : public GrabberWrapper

public:
V4L2Wrapper(const QString & device,
const unsigned grabWidth,
const unsigned grabHeight,
const unsigned fps,
VideoStandard videoStandard,
PixelFormat pixelFormat,
int pixelDecimation );
Expand Down
8 changes: 8 additions & 0 deletions include/hyperion/Grabber.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ class Grabber : public QObject
///
virtual bool setWidthHeight(int width, int height);

///
/// @brief Apply new framerate (used from v4l)
/// @param fps framesPerSecond
///
virtual bool setFramerate(int fps);

///
/// @brief Apply new pixelDecimation (used from x11 and qt)
///
Expand Down Expand Up @@ -111,6 +117,8 @@ class Grabber : public QObject
/// Height of the captured snapshot [pixels]
int _height;

int _fps;

// number of pixels to crop after capturing
int _cropLeft, _cropRight, _cropTop, _cropBottom;

Expand Down
4 changes: 2 additions & 2 deletions include/utils/PixelFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ enum PixelFormat {
PIXELFORMAT_BGR24,
PIXELFORMAT_RGB32,
PIXELFORMAT_BGR32,
#ifdef HAVE_JPEG
#ifdef HAVE_JPEG_DECODER
PIXELFORMAT_MJPEG,
#endif
PIXELFORMAT_NO_CHANGE
Expand Down Expand Up @@ -47,7 +47,7 @@ inline PixelFormat parsePixelFormat(QString pixelFormat)
{
return PIXELFORMAT_BGR32;
}
#ifdef HAVE_JPEG
#ifdef HAVE_JPEG_DECODER
else if (pixelFormat == "mjpeg")
{
return PIXELFORMAT_MJPEG;
Expand Down
8 changes: 8 additions & 0 deletions include/utils/jsonschema/QJsonSchemaChecker.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,14 @@ class QJsonSchemaChecker
///
void checkEnum(const QJsonValue & value, const QJsonValue & schema, const QJsonValue & defaultValue);

///
/// @brief Return the "default" value as string. If not found, an empty string is output
///
/// @param value The JSON value to search
/// @return The "default" value as string
///
QString getDefaultValue(const QJsonValue & value);

private:
/// The schema of the entire json-configuration
QJsonObject _qSchema;
Expand Down
31 changes: 31 additions & 0 deletions include/utils/jsonschema/QJsonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,37 @@ class QJsonUtils
return createValue(schema, ignoreRequired);
}

static QString getDefaultValue(const QJsonValue & value)
{
QString ret;
switch (value.type())
{
case QJsonValue::Array:
{
for (const QJsonValue &v : value.toArray())
{
ret = getDefaultValue(v);
if (!ret.isEmpty())
break;
}
break;
}
case QJsonValue::Object:
ret = getDefaultValue(value.toObject().find("default").value());
break;
case QJsonValue::Bool:
return value.toBool() ? "True" : "False";
case QJsonValue::Double:
return QString::number(value.toDouble());
case QJsonValue::String:
return value.toString();
case QJsonValue::Null:
case QJsonValue::Undefined:
break;
}
return ret;
}

private:

static QJsonValue createValue(QJsonValue schema, bool ignoreRequired)
Expand Down
8 changes: 5 additions & 3 deletions libsrc/grabber/v4l2/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ target_link_libraries(v4l2-grabber
${QT_LIBRARIES}
)

if (JPEG_FOUND)
target_link_libraries(v4l2-grabber ${JPEG_LIBRARY})
endif()
if(TURBOJPEG_FOUND)
target_link_libraries(v4l2-grabber ${TurboJPEG_LIBRARY})
elseif (JPEG_FOUND)
target_link_libraries(v4l2-grabber ${JPEG_LIBRARY})
endif(TURBOJPEG_FOUND)
Loading

0 comments on commit 662872d

Please sign in to comment.