mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
big code cleanup. mostly line endings and indentions (#659)
No functional changes - except protobuffer is mandatory and not optional now. Former-commit-id: 1e6347e708707cc388cdedb8d0352a9f017030b8
This commit is contained in:
parent
667ee80ef6
commit
945f3d1c5b
@ -51,8 +51,7 @@ message(STATUS "ENABLE_FB = " ${ENABLE_FB})
|
|||||||
option(ENABLE_OSX "Enable the osx grabber" ${DEFAULT_OSX} )
|
option(ENABLE_OSX "Enable the osx grabber" ${DEFAULT_OSX} )
|
||||||
message(STATUS "ENABLE_OSX = " ${ENABLE_OSX})
|
message(STATUS "ENABLE_OSX = " ${ENABLE_OSX})
|
||||||
|
|
||||||
option(ENABLE_PROTOBUF "Enable PROTOBUF server" ON)
|
set(ENABLE_PROTOBUF ON)
|
||||||
message(STATUS "ENABLE_PROTOBUF = " ${ENABLE_PROTOBUF})
|
|
||||||
|
|
||||||
option(ENABLE_SPIDEV "Enable the SPIDEV device" ${DEFAULT_SPIDEV} )
|
option(ENABLE_SPIDEV "Enable the SPIDEV device" ${DEFAULT_SPIDEV} )
|
||||||
message(STATUS "ENABLE_SPIDEV = " ${ENABLE_SPIDEV})
|
message(STATUS "ENABLE_SPIDEV = " ${ENABLE_SPIDEV})
|
||||||
@ -78,9 +77,6 @@ message(STATUS "ENABLE_QT5 = " ${ENABLE_QT5})
|
|||||||
option(ENABLE_TESTS "Compile additional test applications" OFF)
|
option(ENABLE_TESTS "Compile additional test applications" OFF)
|
||||||
message(STATUS "ENABLE_TESTS = " ${ENABLE_TESTS})
|
message(STATUS "ENABLE_TESTS = " ${ENABLE_TESTS})
|
||||||
|
|
||||||
if(ENABLE_V4L2 AND NOT ENABLE_PROTOBUF)
|
|
||||||
message(FATAL_ERROR "V4L2 grabber requires PROTOBUF. Disable V4L2 or enable PROTOBUF")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_FB AND ENABLE_DISPMANX)
|
if(ENABLE_FB AND ENABLE_DISPMANX)
|
||||||
message(FATAL_ERROR "dispmanx grabber and framebuffer grabber cannot be used at the same time")
|
message(FATAL_ERROR "dispmanx grabber and framebuffer grabber cannot be used at the same time")
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
if [ "$#" -ne 2 ] || ! [ -d "$1" ] || ! [ -d "$2" ]; then
|
if [ "$#" -ne 2 ] || ! [ -d "$1" ] || ! [ -d "$2" ]; then
|
||||||
echo "Usage: $0 <BUILD-DIR> <REPO-DIR>" >&2
|
echo "Usage: $0 <BUILD-DIR> <REPO-DIR>" >&2
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
builddir="$1"
|
builddir="$1"
|
||||||
|
@ -6,15 +6,15 @@ PATH="/sbin:$PATH"
|
|||||||
|
|
||||||
#Check if HyperCon is logged in as root
|
#Check if HyperCon is logged in as root
|
||||||
if [ $(id -u) != 0 ] && [ "$1" = "HyperConRemove" ]; then
|
if [ $(id -u) != 0 ] && [ "$1" = "HyperConRemove" ]; then
|
||||||
echo '---> Critical Error: Please connect as user "root" through HyperCon'
|
echo '---> Critical Error: Please connect as user "root" through HyperCon'
|
||||||
echo '---> We need admin privileges to remove your Hyperion! -> abort'
|
echo '---> We need admin privileges to remove your Hyperion! -> abort'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#Check, if script is running as root
|
#Check, if script is running as root
|
||||||
if [ $(id -u) != 0 ]; then
|
if [ $(id -u) != 0 ]; then
|
||||||
echo '---> Critical Error: Please run the script as root (sudo sh ./remove_hyperion.sh)'
|
echo '---> Critical Error: Please run the script as root (sudo sh ./remove_hyperion.sh)'
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
#Welcome message
|
#Welcome message
|
||||||
@ -26,21 +26,22 @@ echo '**************************************************************************
|
|||||||
|
|
||||||
#Skip the prompt if HyperCon Remove
|
#Skip the prompt if HyperCon Remove
|
||||||
if [ "$1" = "" ]; then
|
if [ "$1" = "" ]; then
|
||||||
#Prompt for confirmation to proceed
|
#Prompt for confirmation to proceed
|
||||||
while true
|
while true
|
||||||
do
|
do
|
||||||
echo -n "---> Do you really want to remove Hyperion and it´s services? (y or n) :"
|
echo -n "---> Do you really want to remove Hyperion and it´s services? (y or n) :"
|
||||||
read CONFIRM
|
read CONFIRM
|
||||||
case $CONFIRM in
|
case $CONFIRM in
|
||||||
y|Y|YES|yes|Yes) break ;;
|
y|Y|YES|yes|Yes) break ;;
|
||||||
n|N|no|NO|No)
|
n|N|no|NO|No)
|
||||||
echo "---> Aborting - you entered \"$CONFIRM\""
|
echo "---> Aborting - you entered \"$CONFIRM\""
|
||||||
exit
|
exit
|
||||||
;;
|
;;
|
||||||
*) echo "-> Please enter only y or n"
|
*) echo "-> Please enter only y or n"
|
||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
echo "---> You entered \"$CONFIRM\". Remove Hyperion!"
|
|
||||||
|
echo "---> You entered \"$CONFIRM\". Remove Hyperion!"
|
||||||
fi
|
fi
|
||||||
# Find out if we are on OpenElec or RasPlex
|
# Find out if we are on OpenElec or RasPlex
|
||||||
OS_OPENELEC=`grep -m1 -c 'OpenELEC\|RasPlex\|LibreELEC' /etc/issue`
|
OS_OPENELEC=`grep -m1 -c 'OpenELEC\|RasPlex\|LibreELEC' /etc/issue`
|
||||||
@ -124,4 +125,3 @@ echo '**************************************************************************
|
|||||||
echo 'Hyperion successful removed!'
|
echo 'Hyperion successful removed!'
|
||||||
echo '*******************************************************************************'
|
echo '*******************************************************************************'
|
||||||
exit 0
|
exit 0
|
||||||
|
|
@ -8,16 +8,16 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
FIND_PATH(BCM_INCLUDE_DIR
|
FIND_PATH(BCM_INCLUDE_DIR
|
||||||
bcm_host.h
|
bcm_host.h
|
||||||
/usr/include
|
/usr/include
|
||||||
/usr/local/include
|
/usr/local/include
|
||||||
/opt/vc/include)
|
/opt/vc/include)
|
||||||
|
|
||||||
SET(BCM_INCLUDE_DIRS
|
SET(BCM_INCLUDE_DIRS
|
||||||
${BCM_INCLUDE_DIR}
|
${BCM_INCLUDE_DIR}
|
||||||
${BCM_INCLUDE_DIR}/interface/vcos/pthreads
|
${BCM_INCLUDE_DIR}/interface/vcos/pthreads
|
||||||
${BCM_INCLUDE_DIR}/interface/vmcs_host/linux)
|
${BCM_INCLUDE_DIR}/interface/vmcs_host/linux)
|
||||||
|
|
||||||
FIND_LIBRARY(BCM_LIBRARIES
|
FIND_LIBRARY(BCM_LIBRARIES
|
||||||
NAMES bcm_host
|
NAMES bcm_host
|
||||||
PATHS /usr/lib /usr/local/lib /opt/vc/lib)
|
PATHS /usr/lib /usr/local/lib /opt/vc/lib)
|
||||||
|
@ -17,5 +17,5 @@ if(APPLE)
|
|||||||
set(CoreFoundation_FOUND true)
|
set(CoreFoundation_FOUND true)
|
||||||
set(CoreFoundation_INCLUDE_DIR ${CoreFoundation})
|
set(CoreFoundation_INCLUDE_DIR ${CoreFoundation})
|
||||||
set(CoreFoundation_LIBRARY ${CoreFoundation})
|
set(CoreFoundation_LIBRARY ${CoreFoundation})
|
||||||
endif(CoreFoundation)
|
endif()
|
||||||
endif(APPLE)
|
endif()
|
||||||
|
@ -13,9 +13,9 @@ set(IOKit_LIBRARY)
|
|||||||
if(APPLE)
|
if(APPLE)
|
||||||
# The only platform it makes sense to check for IOKit
|
# The only platform it makes sense to check for IOKit
|
||||||
find_library(IOKit IOKit)
|
find_library(IOKit IOKit)
|
||||||
if(IOKit)
|
if(IOKit)
|
||||||
set(IOKit_FOUND true)
|
set(IOKit_FOUND true)
|
||||||
set(IOKit_INCLUDE_DIR ${IOKit})
|
set(IOKit_INCLUDE_DIR ${IOKit})
|
||||||
set(IOKit_LIBRARY ${IOKit})
|
set(IOKit_LIBRARY ${IOKit})
|
||||||
endif(IOKit)
|
endif(IOKit)
|
||||||
endif(APPLE)
|
endif(APPLE)
|
||||||
|
@ -10,44 +10,44 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
FIND_PATH(
|
FIND_PATH(
|
||||||
UDEV_INCLUDE_DIR
|
UDEV_INCLUDE_DIR
|
||||||
libudev.h
|
libudev.h
|
||||||
/usr/include
|
/usr/include
|
||||||
/usr/local/include
|
/usr/local/include
|
||||||
${UDEV_PATH_INCLUDES}
|
${UDEV_PATH_INCLUDES}
|
||||||
)
|
)
|
||||||
|
|
||||||
FIND_LIBRARY(
|
FIND_LIBRARY(
|
||||||
UDEV_LIBRARIES
|
UDEV_LIBRARIES
|
||||||
NAMES udev libudev
|
NAMES udev libudev
|
||||||
PATHS
|
PATHS
|
||||||
/usr/lib${LIB_SUFFIX}
|
/usr/lib${LIB_SUFFIX}
|
||||||
/usr/local/lib${LIB_SUFFIX}
|
/usr/local/lib${LIB_SUFFIX}
|
||||||
${UDEV_PATH_LIB}
|
${UDEV_PATH_LIB}
|
||||||
)
|
)
|
||||||
|
|
||||||
IF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
|
IF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
|
||||||
SET(UDEV_FOUND "YES")
|
SET(UDEV_FOUND "YES")
|
||||||
execute_process(COMMAND pkg-config --atleast-version=143 libudev RESULT_VARIABLE UDEV_STABLE)
|
execute_process(COMMAND pkg-config --atleast-version=143 libudev RESULT_VARIABLE UDEV_STABLE)
|
||||||
# retvale is 0 of the condition is "true" so we need to negate the value...
|
# retvale is 0 of the condition is "true" so we need to negate the value...
|
||||||
if (UDEV_STABLE)
|
if (UDEV_STABLE)
|
||||||
set(UDEV_STABLE 0)
|
set(UDEV_STABLE 0)
|
||||||
else (UDEV_STABLE)
|
else ()
|
||||||
set(UDEV_STABLE 1)
|
set(UDEV_STABLE 1)
|
||||||
endif (UDEV_STABLE)
|
endif ()
|
||||||
message(STATUS "libudev stable: ${UDEV_STABLE}")
|
message(STATUS "libudev stable: ${UDEV_STABLE}")
|
||||||
ENDIF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
|
ENDIF ()
|
||||||
|
|
||||||
IF (UDEV_FOUND)
|
IF (UDEV_FOUND)
|
||||||
MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}")
|
MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}")
|
||||||
MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}")
|
MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}")
|
||||||
ELSE (UDEV_FOUND)
|
ELSE ()
|
||||||
MESSAGE(STATUS "UDev not found.")
|
MESSAGE(STATUS "UDev not found.")
|
||||||
MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include")
|
MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include")
|
||||||
MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}")
|
MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}")
|
||||||
MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib")
|
MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib")
|
||||||
MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}")
|
MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}")
|
||||||
IF (UDev_FIND_REQUIRED)
|
IF (UDev_FIND_REQUIRED)
|
||||||
MESSAGE(FATAL_ERROR "Could not find UDev library")
|
MESSAGE(FATAL_ERROR "Could not find UDev library")
|
||||||
ENDIF (UDev_FIND_REQUIRED)
|
ENDIF ()
|
||||||
ENDIF (UDEV_FOUND)
|
ENDIF ()
|
||||||
|
@ -44,56 +44,52 @@
|
|||||||
|
|
||||||
|
|
||||||
if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||||
# in cache already
|
# in cache already
|
||||||
set(LIBUSB_FOUND TRUE)
|
set(LIBUSB_FOUND TRUE)
|
||||||
else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
else (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||||
find_path(LIBUSB_1_INCLUDE_DIR
|
find_path(LIBUSB_1_INCLUDE_DIR
|
||||||
|
NAMES
|
||||||
|
libusb.h
|
||||||
|
PATHS
|
||||||
|
/usr/include
|
||||||
|
/usr/local/include
|
||||||
|
/opt/local/include
|
||||||
|
/sw/include
|
||||||
|
PATH_SUFFIXES
|
||||||
|
libusb-1.0
|
||||||
|
)
|
||||||
|
|
||||||
|
find_library(LIBUSB_1_LIBRARY
|
||||||
NAMES
|
NAMES
|
||||||
libusb.h
|
usb-1.0 usb
|
||||||
PATHS
|
PATHS
|
||||||
/usr/include
|
/usr/lib
|
||||||
/usr/local/include
|
/usr/local/lib
|
||||||
/opt/local/include
|
/opt/local/lib
|
||||||
/sw/include
|
/sw/lib
|
||||||
PATH_SUFFIXES
|
)
|
||||||
libusb-1.0
|
|
||||||
)
|
|
||||||
|
|
||||||
find_library(LIBUSB_1_LIBRARY
|
set(LIBUSB_1_INCLUDE_DIRS ${LIBUSB_1_INCLUDE_DIR} )
|
||||||
NAMES
|
set(LIBUSB_1_LIBRARIES ${LIBUSB_1_LIBRARY} )
|
||||||
usb-1.0 usb
|
|
||||||
PATHS
|
|
||||||
/usr/lib
|
|
||||||
/usr/local/lib
|
|
||||||
/opt/local/lib
|
|
||||||
/sw/lib
|
|
||||||
)
|
|
||||||
|
|
||||||
set(LIBUSB_1_INCLUDE_DIRS
|
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||||
${LIBUSB_1_INCLUDE_DIR}
|
set(LIBUSB_1_FOUND TRUE)
|
||||||
)
|
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
||||||
set(LIBUSB_1_LIBRARIES
|
|
||||||
${LIBUSB_1_LIBRARY}
|
|
||||||
)
|
|
||||||
|
|
||||||
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
if (LIBUSB_1_FOUND)
|
||||||
set(LIBUSB_1_FOUND TRUE)
|
if (NOT libusb_1_FIND_QUIETLY)
|
||||||
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
|
message(STATUS "Found libusb-1.0:")
|
||||||
|
message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}")
|
||||||
|
message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}")
|
||||||
|
endif (NOT libusb_1_FIND_QUIETLY)
|
||||||
|
else (LIBUSB_1_FOUND)
|
||||||
|
unset(LIBUSB_1_LIBRARY CACHE)
|
||||||
|
if (libusb_1_FIND_REQUIRED)
|
||||||
|
message(FATAL_ERROR "Could not find libusb")
|
||||||
|
endif (libusb_1_FIND_REQUIRED)
|
||||||
|
endif (LIBUSB_1_FOUND)
|
||||||
|
|
||||||
if (LIBUSB_1_FOUND)
|
# show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view
|
||||||
if (NOT libusb_1_FIND_QUIETLY)
|
mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES)
|
||||||
message(STATUS "Found libusb-1.0:")
|
|
||||||
message(STATUS " - Includes: ${LIBUSB_1_INCLUDE_DIRS}")
|
|
||||||
message(STATUS " - Libraries: ${LIBUSB_1_LIBRARIES}")
|
|
||||||
endif (NOT libusb_1_FIND_QUIETLY)
|
|
||||||
else (LIBUSB_1_FOUND)
|
|
||||||
unset(LIBUSB_1_LIBRARY CACHE)
|
|
||||||
if (libusb_1_FIND_REQUIRED)
|
|
||||||
message(FATAL_ERROR "Could not find libusb")
|
|
||||||
endif (libusb_1_FIND_REQUIRED)
|
|
||||||
endif (LIBUSB_1_FOUND)
|
|
||||||
|
|
||||||
# show the LIBUSB_1_INCLUDE_DIRS and LIBUSB_1_LIBRARIES variables only in the advanced view
|
|
||||||
mark_as_advanced(LIBUSB_1_INCLUDE_DIRS LIBUSB_1_LIBRARIES)
|
|
||||||
|
|
||||||
endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
endif (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||||
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||||
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt")
|
||||||
|
|
||||||
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
|
||||||
string(REGEX REPLACE "\n" ";" files "${files}")
|
string(REGEX REPLACE "\n" ";" files "${files}")
|
||||||
foreach(file ${files})
|
foreach(file ${files})
|
||||||
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
|
||||||
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||||
exec_program(
|
exec_program(
|
||||||
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
|
||||||
OUTPUT_VARIABLE rm_out
|
OUTPUT_VARIABLE rm_out
|
||||||
RETURN_VALUE rm_retval
|
RETURN_VALUE rm_retval
|
||||||
)
|
)
|
||||||
if(NOT "${rm_retval}" STREQUAL 0)
|
if(NOT "${rm_retval}" STREQUAL 0)
|
||||||
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
|
||||||
endif(NOT "${rm_retval}" STREQUAL 0)
|
endif(NOT "${rm_retval}" STREQUAL 0)
|
||||||
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||||
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
|
||||||
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
|
||||||
endforeach(file)
|
endforeach(file)
|
||||||
|
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name" : "Knight rider",
|
"name" : "Knight rider",
|
||||||
"script" : "knight-rider.py",
|
"script" : "knight-rider.py",
|
||||||
"args" :
|
"args" :
|
||||||
{
|
{
|
||||||
"speed" : 1.0,
|
"speed" : 1.0,
|
||||||
"fadeFactor" : 0.7,
|
"fadeFactor" : 0.7,
|
||||||
"color" : [255,0,0]
|
"color" : [255,0,0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name" : "Blue mood blobs",
|
"name" : "Blue mood blobs",
|
||||||
"script" : "mood-blobs.py",
|
"script" : "mood-blobs.py",
|
||||||
"args" :
|
"args" :
|
||||||
{
|
{
|
||||||
"rotationTime" : 60.0,
|
"rotationTime" : 60.0,
|
||||||
"color" : [0,0,255],
|
"color" : [0,0,255],
|
||||||
"hueChange" : 60.0,
|
"hueChange" : 60.0,
|
||||||
"blobs" : 5,
|
"blobs" : 5,
|
||||||
"reverse" : false
|
"reverse" : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name" : "Green mood blobs",
|
"name" : "Green mood blobs",
|
||||||
"script" : "mood-blobs.py",
|
"script" : "mood-blobs.py",
|
||||||
"args" :
|
"args" :
|
||||||
{
|
{
|
||||||
"rotationTime" : 60.0,
|
"rotationTime" : 60.0,
|
||||||
"color" : [0,255,0],
|
"color" : [0,255,0],
|
||||||
"hueChange" : 60.0,
|
"hueChange" : 60.0,
|
||||||
"blobs" : 5,
|
"blobs" : 5,
|
||||||
"reverse" : false
|
"reverse" : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name" : "Red mood blobs",
|
"name" : "Red mood blobs",
|
||||||
"script" : "mood-blobs.py",
|
"script" : "mood-blobs.py",
|
||||||
"args" :
|
"args" :
|
||||||
{
|
{
|
||||||
"rotationTime" : 60.0,
|
"rotationTime" : 60.0,
|
||||||
"color" : [255,0,0],
|
"color" : [255,0,0],
|
||||||
"hueChange" : 60.0,
|
"hueChange" : 60.0,
|
||||||
"blobs" : 5,
|
"blobs" : 5,
|
||||||
"reverse" : false
|
"reverse" : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name" : "Rainbow mood",
|
"name" : "Rainbow mood",
|
||||||
"script" : "rainbow-mood.py",
|
"script" : "rainbow-mood.py",
|
||||||
"args" :
|
"args" :
|
||||||
{
|
{
|
||||||
"rotation-time" : 60.0,
|
"rotation-time" : 60.0,
|
||||||
"brightness" : 1.0,
|
"brightness" : 1.0,
|
||||||
"reverse" : false
|
"reverse" : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name" : "Rainbow swirl fast",
|
"name" : "Rainbow swirl fast",
|
||||||
"script" : "rainbow-swirl.py",
|
"script" : "rainbow-swirl.py",
|
||||||
"args" :
|
"args" :
|
||||||
{
|
{
|
||||||
"rotation-time" : 3.0,
|
"rotation-time" : 3.0,
|
||||||
"brightness" : 1.0,
|
"brightness" : 1.0,
|
||||||
"reverse" : false
|
"reverse" : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name" : "Rainbow swirl",
|
"name" : "Rainbow swirl",
|
||||||
"script" : "rainbow-swirl.py",
|
"script" : "rainbow-swirl.py",
|
||||||
"args" :
|
"args" :
|
||||||
{
|
{
|
||||||
"rotation-time" : 20.0,
|
"rotation-time" : 20.0,
|
||||||
"brightness" : 1.0,
|
"brightness" : 1.0,
|
||||||
"reverse" : false
|
"reverse" : false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"name" : "Snake",
|
"name" : "Snake",
|
||||||
"script" : "snake.py",
|
"script" : "snake.py",
|
||||||
"args" :
|
"args" :
|
||||||
{
|
{
|
||||||
"rotation-time" : 12.0,
|
"rotation-time" : 12.0,
|
||||||
"color" : [255, 0, 0],
|
"color" : [255, 0, 0],
|
||||||
"percentage" : 10
|
"percentage" : 10
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,103 +23,103 @@
|
|||||||
/// @see http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html
|
/// @see http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html
|
||||||
class V4L2Grabber : public QObject
|
class V4L2Grabber : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
V4L2Grabber(const std::string & device,
|
V4L2Grabber(const std::string & device,
|
||||||
int input,
|
int input,
|
||||||
VideoStandard videoStandard, PixelFormat pixelFormat,
|
VideoStandard videoStandard, PixelFormat pixelFormat,
|
||||||
int width,
|
int width,
|
||||||
int height,
|
int height,
|
||||||
int frameDecimation,
|
int frameDecimation,
|
||||||
int horizontalPixelDecimation,
|
int horizontalPixelDecimation,
|
||||||
int verticalPixelDecimation);
|
int verticalPixelDecimation);
|
||||||
virtual ~V4L2Grabber();
|
virtual ~V4L2Grabber();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setCropping(int cropLeft,
|
void setCropping(int cropLeft,
|
||||||
int cropRight,
|
int cropRight,
|
||||||
int cropTop,
|
int cropTop,
|
||||||
int cropBottom);
|
int cropBottom);
|
||||||
|
|
||||||
void set3D(VideoMode mode);
|
void set3D(VideoMode mode);
|
||||||
|
|
||||||
void setSignalThreshold(double redSignalThreshold,
|
void setSignalThreshold(double redSignalThreshold,
|
||||||
double greenSignalThreshold,
|
double greenSignalThreshold,
|
||||||
double blueSignalThreshold,
|
double blueSignalThreshold,
|
||||||
int noSignalCounterThreshold);
|
int noSignalCounterThreshold);
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void newFrame(const Image<ColorRgb> & image);
|
void newFrame(const Image<ColorRgb> & image);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
int read_frame();
|
int read_frame();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void open_device();
|
void open_device();
|
||||||
|
|
||||||
void close_device();
|
void close_device();
|
||||||
|
|
||||||
void init_read(unsigned int buffer_size);
|
void init_read(unsigned int buffer_size);
|
||||||
|
|
||||||
void init_mmap();
|
void init_mmap();
|
||||||
|
|
||||||
void init_userp(unsigned int buffer_size);
|
void init_userp(unsigned int buffer_size);
|
||||||
|
|
||||||
void init_device(VideoStandard videoStandard, int input);
|
void init_device(VideoStandard videoStandard, int input);
|
||||||
|
|
||||||
void uninit_device();
|
void uninit_device();
|
||||||
|
|
||||||
void start_capturing();
|
void start_capturing();
|
||||||
|
|
||||||
void stop_capturing();
|
void stop_capturing();
|
||||||
|
|
||||||
bool process_image(const void *p, int size);
|
bool process_image(const void *p, int size);
|
||||||
|
|
||||||
void process_image(const uint8_t *p);
|
void process_image(const uint8_t *p);
|
||||||
|
|
||||||
int xioctl(int request, void *arg);
|
int xioctl(int request, void *arg);
|
||||||
|
|
||||||
void throw_exception(const std::string &error);
|
void throw_exception(const std::string &error);
|
||||||
|
|
||||||
void throw_errno_exception(const std::string &error);
|
void throw_errno_exception(const std::string &error);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum io_method {
|
enum io_method {
|
||||||
IO_METHOD_READ,
|
IO_METHOD_READ,
|
||||||
IO_METHOD_MMAP,
|
IO_METHOD_MMAP,
|
||||||
IO_METHOD_USERPTR
|
IO_METHOD_USERPTR
|
||||||
};
|
};
|
||||||
|
|
||||||
struct buffer {
|
struct buffer {
|
||||||
void *start;
|
void *start;
|
||||||
size_t length;
|
size_t length;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const std::string _deviceName;
|
const std::string _deviceName;
|
||||||
const io_method _ioMethod;
|
const io_method _ioMethod;
|
||||||
int _fileDescriptor;
|
int _fileDescriptor;
|
||||||
std::vector<buffer> _buffers;
|
std::vector<buffer> _buffers;
|
||||||
|
|
||||||
PixelFormat _pixelFormat;
|
PixelFormat _pixelFormat;
|
||||||
int _width;
|
int _width;
|
||||||
int _height;
|
int _height;
|
||||||
int _lineLength;
|
int _lineLength;
|
||||||
int _frameByteSize;
|
int _frameByteSize;
|
||||||
int _frameDecimation;
|
int _frameDecimation;
|
||||||
int _noSignalCounterThreshold;
|
int _noSignalCounterThreshold;
|
||||||
|
|
||||||
ColorRgb _noSignalThresholdColor;
|
ColorRgb _noSignalThresholdColor;
|
||||||
|
|
||||||
int _currentFrame;
|
int _currentFrame;
|
||||||
int _noSignalCounter;
|
int _noSignalCounter;
|
||||||
|
|
||||||
QSocketNotifier * _streamNotifier;
|
QSocketNotifier * _streamNotifier;
|
||||||
|
|
||||||
ImageResampler _imageResampler;
|
ImageResampler _imageResampler;
|
||||||
};
|
};
|
||||||
|
@ -15,7 +15,7 @@ class X11Grabber
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation);
|
X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation);
|
||||||
|
|
||||||
virtual ~X11Grabber();
|
virtual ~X11Grabber();
|
||||||
|
|
||||||
@ -26,16 +26,16 @@ public:
|
|||||||
Image<ColorRgb> & grab();
|
Image<ColorRgb> & grab();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ImageResampler _imageResampler;
|
ImageResampler _imageResampler;
|
||||||
|
|
||||||
bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
|
bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
|
||||||
int _cropLeft;
|
int _cropLeft;
|
||||||
int _cropRight;
|
int _cropRight;
|
||||||
int _cropTop;
|
int _cropTop;
|
||||||
int _cropBottom;
|
int _cropBottom;
|
||||||
|
|
||||||
XImage* _xImage;
|
XImage* _xImage;
|
||||||
XShmSegmentInfo _shminfo;
|
XShmSegmentInfo _shminfo;
|
||||||
|
|
||||||
/// Reference to the X11 display (nullptr if not opened)
|
/// Reference to the X11 display (nullptr if not opened)
|
||||||
Display* _x11Display;
|
Display* _x11Display;
|
||||||
|
@ -23,90 +23,90 @@
|
|||||||
class ProtoConnection : public QObject
|
class ProtoConnection : public QObject
|
||||||
{
|
{
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
/// Constructor
|
/// Constructor
|
||||||
///
|
///
|
||||||
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
|
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
|
||||||
///
|
///
|
||||||
ProtoConnection(const std::string & address);
|
ProtoConnection(const std::string & address);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Destructor
|
/// Destructor
|
||||||
///
|
///
|
||||||
~ProtoConnection();
|
~ProtoConnection();
|
||||||
|
|
||||||
/// Do not read reply messages from Hyperion if set to true
|
/// Do not read reply messages from Hyperion if set to true
|
||||||
void setSkipReply(bool skip);
|
void setSkipReply(bool skip);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set all leds to the specified color
|
/// Set all leds to the specified color
|
||||||
///
|
///
|
||||||
/// @param color The color
|
/// @param color The color
|
||||||
/// @param priority The priority
|
/// @param priority The priority
|
||||||
/// @param duration The duration in milliseconds
|
/// @param duration The duration in milliseconds
|
||||||
///
|
///
|
||||||
void setColor(const ColorRgb & color, int priority, int duration = 1);
|
void setColor(const ColorRgb & color, int priority, int duration = 1);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set the leds according to the given image (assume the image is stretched to the display size)
|
/// Set the leds according to the given image (assume the image is stretched to the display size)
|
||||||
///
|
///
|
||||||
/// @param image The image
|
/// @param image The image
|
||||||
/// @param priority The priority
|
/// @param priority The priority
|
||||||
/// @param duration The duration in milliseconds
|
/// @param duration The duration in milliseconds
|
||||||
///
|
///
|
||||||
void setImage(const Image<ColorRgb> & image, int priority, int duration = -1);
|
void setImage(const Image<ColorRgb> & image, int priority, int duration = -1);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Clear the given priority channel
|
/// Clear the given priority channel
|
||||||
///
|
///
|
||||||
/// @param priority The priority
|
/// @param priority The priority
|
||||||
///
|
///
|
||||||
void clear(int priority);
|
void clear(int priority);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Clear all priority channels
|
/// Clear all priority channels
|
||||||
///
|
///
|
||||||
void clearAll();
|
void clearAll();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Send a command message and receive its reply
|
/// Send a command message and receive its reply
|
||||||
///
|
///
|
||||||
/// @param message The message to send
|
/// @param message The message to send
|
||||||
///
|
///
|
||||||
void sendMessage(const proto::HyperionRequest & message);
|
void sendMessage(const proto::HyperionRequest & message);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/// Try to connect to the Hyperion host
|
/// Try to connect to the Hyperion host
|
||||||
void connectToHost();
|
void connectToHost();
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Parse a reply message
|
/// Parse a reply message
|
||||||
///
|
///
|
||||||
/// @param reply The received reply
|
/// @param reply The received reply
|
||||||
///
|
///
|
||||||
/// @return true if the reply indicates success
|
/// @return true if the reply indicates success
|
||||||
///
|
///
|
||||||
bool parseReply(const proto::HyperionReply & reply);
|
bool parseReply(const proto::HyperionReply & reply);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The TCP-Socket with the connection to the server
|
/// The TCP-Socket with the connection to the server
|
||||||
QTcpSocket _socket;
|
QTcpSocket _socket;
|
||||||
|
|
||||||
/// Host address
|
/// Host address
|
||||||
QString _host;
|
QString _host;
|
||||||
|
|
||||||
/// Host port
|
/// Host port
|
||||||
uint16_t _port;
|
uint16_t _port;
|
||||||
|
|
||||||
/// Skip receiving reply messages from Hyperion if set
|
/// Skip receiving reply messages from Hyperion if set
|
||||||
bool _skipReply;
|
bool _skipReply;
|
||||||
|
|
||||||
QTimer _timer;
|
QTimer _timer;
|
||||||
QAbstractSocket::SocketState _prevSocketState;
|
QAbstractSocket::SocketState _prevSocketState;
|
||||||
};
|
};
|
||||||
|
@ -11,24 +11,24 @@
|
|||||||
/// This class handles callbacks from the V4L2 grabber
|
/// This class handles callbacks from the V4L2 grabber
|
||||||
class ProtoConnectionWrapper : public QObject
|
class ProtoConnectionWrapper : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ProtoConnectionWrapper(const std::string & address, int priority, int duration_ms, bool skipProtoReply);
|
ProtoConnectionWrapper(const std::string & address, int priority, int duration_ms, bool skipProtoReply);
|
||||||
virtual ~ProtoConnectionWrapper();
|
virtual ~ProtoConnectionWrapper();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
/// Handle a single image
|
/// Handle a single image
|
||||||
/// @param image The image to process
|
/// @param image The image to process
|
||||||
void receiveImage(const Image<ColorRgb> & image);
|
void receiveImage(const Image<ColorRgb> & image);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Priority for calls to Hyperion
|
/// Priority for calls to Hyperion
|
||||||
const int _priority;
|
const int _priority;
|
||||||
|
|
||||||
/// Duration for color calls to Hyperion
|
/// Duration for color calls to Hyperion
|
||||||
const int _duration_ms;
|
const int _duration_ms;
|
||||||
|
|
||||||
/// Hyperion proto connection object
|
/// Hyperion proto connection object
|
||||||
ProtoConnection _connection;
|
ProtoConnection _connection;
|
||||||
};
|
};
|
||||||
|
@ -13,221 +13,221 @@ class Image
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
typedef Pixel_T pixel_type;
|
typedef Pixel_T pixel_type;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Default constructor for an image
|
/// Default constructor for an image
|
||||||
///
|
///
|
||||||
Image() :
|
Image() :
|
||||||
_width(1),
|
_width(1),
|
||||||
_height(1),
|
_height(1),
|
||||||
_pixels(new Pixel_T[2]),
|
_pixels(new Pixel_T[2]),
|
||||||
_endOfPixels(_pixels + 1)
|
_endOfPixels(_pixels + 1)
|
||||||
{
|
{
|
||||||
memset(_pixels, 0, 2*sizeof(Pixel_T));
|
memset(_pixels, 0, 2*sizeof(Pixel_T));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructor for an image with specified width and height
|
/// Constructor for an image with specified width and height
|
||||||
///
|
///
|
||||||
/// @param width The width of the image
|
/// @param width The width of the image
|
||||||
/// @param height The height of the image
|
/// @param height The height of the image
|
||||||
///
|
///
|
||||||
Image(const unsigned width, const unsigned height) :
|
Image(const unsigned width, const unsigned height) :
|
||||||
_width(width),
|
_width(width),
|
||||||
_height(height),
|
_height(height),
|
||||||
_pixels(new Pixel_T[width * height + 1]),
|
_pixels(new Pixel_T[width * height + 1]),
|
||||||
_endOfPixels(_pixels + width * height)
|
_endOfPixels(_pixels + width * height)
|
||||||
{
|
{
|
||||||
memset(_pixels, 0, (_width*_height+1)*sizeof(Pixel_T));
|
memset(_pixels, 0, (_width*_height+1)*sizeof(Pixel_T));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructor for an image with specified width and height
|
/// Constructor for an image with specified width and height
|
||||||
///
|
///
|
||||||
/// @param width The width of the image
|
/// @param width The width of the image
|
||||||
/// @param height The height of the image
|
/// @param height The height of the image
|
||||||
/// @param background The color of the image
|
/// @param background The color of the image
|
||||||
///
|
///
|
||||||
Image(const unsigned width, const unsigned height, const Pixel_T background) :
|
Image(const unsigned width, const unsigned height, const Pixel_T background) :
|
||||||
_width(width),
|
_width(width),
|
||||||
_height(height),
|
_height(height),
|
||||||
_pixels(new Pixel_T[width * height + 1]),
|
_pixels(new Pixel_T[width * height + 1]),
|
||||||
_endOfPixels(_pixels + width * height)
|
_endOfPixels(_pixels + width * height)
|
||||||
{
|
{
|
||||||
std::fill(_pixels, _endOfPixels, background);
|
std::fill(_pixels, _endOfPixels, background);
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copy constructor for an image
|
/// Copy constructor for an image
|
||||||
///
|
///
|
||||||
Image(const Image & other) :
|
Image(const Image & other) :
|
||||||
_width(other._width),
|
_width(other._width),
|
||||||
_height(other._height),
|
_height(other._height),
|
||||||
_pixels(new Pixel_T[other._width * other._height + 1]),
|
_pixels(new Pixel_T[other._width * other._height + 1]),
|
||||||
_endOfPixels(_pixels + other._width * other._height)
|
_endOfPixels(_pixels + other._width * other._height)
|
||||||
{
|
{
|
||||||
memcpy(_pixels, other._pixels, other._width * other._height * sizeof(Pixel_T));
|
memcpy(_pixels, other._pixels, other._width * other._height * sizeof(Pixel_T));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Destructor
|
/// Destructor
|
||||||
///
|
///
|
||||||
~Image()
|
~Image()
|
||||||
{
|
{
|
||||||
delete[] _pixels;
|
delete[] _pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the width of the image
|
/// Returns the width of the image
|
||||||
///
|
///
|
||||||
/// @return The width of the image
|
/// @return The width of the image
|
||||||
///
|
///
|
||||||
inline unsigned width() const
|
inline unsigned width() const
|
||||||
{
|
{
|
||||||
return _width;
|
return _width;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns the height of the image
|
/// Returns the height of the image
|
||||||
///
|
///
|
||||||
/// @return The height of the image
|
/// @return The height of the image
|
||||||
///
|
///
|
||||||
inline unsigned height() const
|
inline unsigned height() const
|
||||||
{
|
{
|
||||||
return _height;
|
return _height;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t red(const unsigned pixel) const
|
uint8_t red(const unsigned pixel) const
|
||||||
{
|
{
|
||||||
return (_pixels + pixel)->red;
|
return (_pixels + pixel)->red;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t green(const unsigned pixel) const
|
uint8_t green(const unsigned pixel) const
|
||||||
{
|
{
|
||||||
return (_pixels + pixel)->green;
|
return (_pixels + pixel)->green;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t blue(const unsigned pixel) const
|
uint8_t blue(const unsigned pixel) const
|
||||||
{
|
{
|
||||||
return (_pixels + pixel)->blue;
|
return (_pixels + pixel)->blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a const reference to a specified pixel in the image
|
/// Returns a const reference to a specified pixel in the image
|
||||||
///
|
///
|
||||||
/// @param x The x index
|
/// @param x The x index
|
||||||
/// @param y The y index
|
/// @param y The y index
|
||||||
///
|
///
|
||||||
/// @return const reference to specified pixel
|
/// @return const reference to specified pixel
|
||||||
///
|
///
|
||||||
const Pixel_T& operator()(const unsigned x, const unsigned y) const
|
const Pixel_T& operator()(const unsigned x, const unsigned y) const
|
||||||
{
|
{
|
||||||
return _pixels[toIndex(x,y)];
|
return _pixels[toIndex(x,y)];
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a reference to a specified pixel in the image
|
/// Returns a reference to a specified pixel in the image
|
||||||
///
|
///
|
||||||
/// @param x The x index
|
/// @param x The x index
|
||||||
/// @param y The y index
|
/// @param y The y index
|
||||||
///
|
///
|
||||||
/// @return reference to specified pixel
|
/// @return reference to specified pixel
|
||||||
///
|
///
|
||||||
Pixel_T& operator()(const unsigned x, const unsigned y)
|
Pixel_T& operator()(const unsigned x, const unsigned y)
|
||||||
{
|
{
|
||||||
return _pixels[toIndex(x,y)];
|
return _pixels[toIndex(x,y)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Resize the image
|
/// Resize the image
|
||||||
/// @param width The width of the image
|
/// @param width The width of the image
|
||||||
/// @param height The height of the image
|
/// @param height The height of the image
|
||||||
void resize(const unsigned width, const unsigned height)
|
void resize(const unsigned width, const unsigned height)
|
||||||
{
|
{
|
||||||
if ((width*height) > unsigned((_endOfPixels-_pixels)))
|
if ((width*height) > unsigned((_endOfPixels-_pixels)))
|
||||||
{
|
{
|
||||||
delete[] _pixels;
|
delete[] _pixels;
|
||||||
_pixels = new Pixel_T[width*height + 1];
|
_pixels = new Pixel_T[width*height + 1];
|
||||||
_endOfPixels = _pixels + width*height;
|
_endOfPixels = _pixels + width*height;
|
||||||
}
|
}
|
||||||
|
|
||||||
_width = width;
|
_width = width;
|
||||||
_height = height;
|
_height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Copies another image into this image. The images should have exactly the same size.
|
/// Copies another image into this image. The images should have exactly the same size.
|
||||||
///
|
///
|
||||||
/// @param other The image to copy into this
|
/// @param other The image to copy into this
|
||||||
///
|
///
|
||||||
void copy(const Image<Pixel_T>& other)
|
void copy(const Image<Pixel_T>& other)
|
||||||
{
|
{
|
||||||
assert(other._width == _width);
|
assert(other._width == _width);
|
||||||
assert(other._height == _height);
|
assert(other._height == _height);
|
||||||
|
|
||||||
memcpy(_pixels, other._pixels, _width*_height*sizeof(Pixel_T));
|
memcpy(_pixels, other._pixels, _width*_height*sizeof(Pixel_T));
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a memory pointer to the first pixel in the image
|
/// Returns a memory pointer to the first pixel in the image
|
||||||
/// @return The memory pointer to the first pixel
|
/// @return The memory pointer to the first pixel
|
||||||
///
|
///
|
||||||
Pixel_T* memptr()
|
Pixel_T* memptr()
|
||||||
{
|
{
|
||||||
return _pixels;
|
return _pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Returns a const memory pointer to the first pixel in the image
|
/// Returns a const memory pointer to the first pixel in the image
|
||||||
/// @return The const memory pointer to the first pixel
|
/// @return The const memory pointer to the first pixel
|
||||||
///
|
///
|
||||||
const Pixel_T* memptr() const
|
const Pixel_T* memptr() const
|
||||||
{
|
{
|
||||||
return _pixels;
|
return _pixels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Convert image of any color order to a RGB image.
|
|
||||||
///
|
|
||||||
/// @param[out] image The image that buffers the output
|
|
||||||
///
|
|
||||||
void toRgb(Image<ColorRgb>& image)
|
|
||||||
{
|
|
||||||
image.resize(_width, _height);
|
|
||||||
const unsigned imageSize = _width * _height;
|
|
||||||
|
|
||||||
for (unsigned idx=0; idx<imageSize; idx++)
|
|
||||||
{
|
///
|
||||||
const Pixel_T color = memptr()[idx];
|
/// Convert image of any color order to a RGB image.
|
||||||
image.memptr()[idx] = ColorRgb{color.red, color.green, color.blue};
|
///
|
||||||
}
|
/// @param[out] image The image that buffers the output
|
||||||
}
|
///
|
||||||
|
void toRgb(Image<ColorRgb>& image)
|
||||||
|
{
|
||||||
|
image.resize(_width, _height);
|
||||||
|
const unsigned imageSize = _width * _height;
|
||||||
|
|
||||||
|
for (unsigned idx=0; idx<imageSize; idx++)
|
||||||
|
{
|
||||||
|
const Pixel_T color = memptr()[idx];
|
||||||
|
image.memptr()[idx] = ColorRgb{color.red, color.green, color.blue};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Translate x and y coordinate to index of the underlying vector
|
/// Translate x and y coordinate to index of the underlying vector
|
||||||
///
|
///
|
||||||
/// @param x The x index
|
/// @param x The x index
|
||||||
/// @param y The y index
|
/// @param y The y index
|
||||||
///
|
///
|
||||||
/// @return The index into the underlying data-vector
|
/// @return The index into the underlying data-vector
|
||||||
///
|
///
|
||||||
inline unsigned toIndex(const unsigned x, const unsigned y) const
|
inline unsigned toIndex(const unsigned x, const unsigned y) const
|
||||||
{
|
{
|
||||||
return y*_width + x;
|
return y*_width + x;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The width of the image
|
/// The width of the image
|
||||||
unsigned _width;
|
unsigned _width;
|
||||||
/// The height of the image
|
/// The height of the image
|
||||||
unsigned _height;
|
unsigned _height;
|
||||||
|
|
||||||
/// The pixels of the image
|
/// The pixels of the image
|
||||||
Pixel_T* _pixels;
|
Pixel_T* _pixels;
|
||||||
|
|
||||||
/// Pointer to the last(extra) pixel
|
/// Pointer to the last(extra) pixel
|
||||||
Pixel_T* _endOfPixels;
|
Pixel_T* _endOfPixels;
|
||||||
};
|
};
|
||||||
|
@ -8,22 +8,21 @@
|
|||||||
class ImageResampler
|
class ImageResampler
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ImageResampler();
|
ImageResampler();
|
||||||
~ImageResampler();
|
~ImageResampler();
|
||||||
|
|
||||||
void setHorizontalPixelDecimation(int decimator);
|
void setHorizontalPixelDecimation(int decimator);
|
||||||
|
|
||||||
void setVerticalPixelDecimation(int decimator);
|
void setVerticalPixelDecimation(int decimator);
|
||||||
|
|
||||||
void setCropping(int cropLeft,
|
void setCropping(int cropLeft,
|
||||||
int cropRight,
|
int cropRight,
|
||||||
int cropTop,
|
int cropTop,
|
||||||
int cropBottom);
|
int cropBottom);
|
||||||
|
|
||||||
void set3D(VideoMode mode);
|
void set3D(VideoMode mode);
|
||||||
|
|
||||||
void processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat,
|
void processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat, Image<ColorRgb> & outputImage) const;
|
||||||
Image<ColorRgb> & outputImage) const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static inline uint8_t clamp(int x);
|
static inline uint8_t clamp(int x);
|
||||||
|
@ -11,9 +11,9 @@ enum PixelFormat {
|
|||||||
PIXELFORMAT_UYVY,
|
PIXELFORMAT_UYVY,
|
||||||
PIXELFORMAT_BGR16,
|
PIXELFORMAT_BGR16,
|
||||||
PIXELFORMAT_BGR24,
|
PIXELFORMAT_BGR24,
|
||||||
PIXELFORMAT_RGB32,
|
PIXELFORMAT_RGB32,
|
||||||
PIXELFORMAT_BGR32,
|
PIXELFORMAT_BGR32,
|
||||||
PIXELFORMAT_NO_CHANGE
|
PIXELFORMAT_NO_CHANGE
|
||||||
};
|
};
|
||||||
|
|
||||||
inline PixelFormat parsePixelFormat(std::string pixelFormat)
|
inline PixelFormat parsePixelFormat(std::string pixelFormat)
|
||||||
@ -29,22 +29,22 @@ inline PixelFormat parsePixelFormat(std::string pixelFormat)
|
|||||||
{
|
{
|
||||||
return PIXELFORMAT_UYVY;
|
return PIXELFORMAT_UYVY;
|
||||||
}
|
}
|
||||||
else if (pixelFormat == "bgr16")
|
else if (pixelFormat == "bgr16")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_BGR16;
|
return PIXELFORMAT_BGR16;
|
||||||
}
|
}
|
||||||
else if (pixelFormat == "bgr24")
|
else if (pixelFormat == "bgr24")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_BGR24;
|
return PIXELFORMAT_BGR24;
|
||||||
}
|
}
|
||||||
else if (pixelFormat == "rgb32")
|
else if (pixelFormat == "rgb32")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_RGB32;
|
return PIXELFORMAT_RGB32;
|
||||||
}
|
}
|
||||||
else if (pixelFormat == "bgr32")
|
else if (pixelFormat == "bgr32")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_BGR32;
|
return PIXELFORMAT_BGR32;
|
||||||
}
|
}
|
||||||
|
|
||||||
// return the default NO_CHANGE
|
// return the default NO_CHANGE
|
||||||
return PIXELFORMAT_NO_CHANGE;
|
return PIXELFORMAT_NO_CHANGE;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
|
|
||||||
class Sleep : protected QThread {
|
class Sleep : protected QThread {
|
||||||
public:
|
public:
|
||||||
static inline void msleep(unsigned long msecs) {
|
static inline void msleep(unsigned long msecs) {
|
||||||
QThread::msleep(msecs);
|
QThread::msleep(msecs);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,192 +1,192 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// stl includes
|
// stl includes
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <list>
|
#include <list>
|
||||||
|
|
||||||
// jsoncpp includes
|
// jsoncpp includes
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
|
|
||||||
/// JsonSchemaChecker is a very basic implementation of json schema.
|
/// JsonSchemaChecker is a very basic implementation of json schema.
|
||||||
/// The json schema definition draft can be found at
|
/// The json schema definition draft can be found at
|
||||||
/// http://tools.ietf.org/html/draft-zyp-json-schema-03
|
/// http://tools.ietf.org/html/draft-zyp-json-schema-03
|
||||||
///
|
///
|
||||||
/// The following keywords are supported:
|
/// The following keywords are supported:
|
||||||
/// - type
|
/// - type
|
||||||
/// - required
|
/// - required
|
||||||
/// - properties
|
/// - properties
|
||||||
/// - items
|
/// - items
|
||||||
/// - enum
|
/// - enum
|
||||||
/// - minimum
|
/// - minimum
|
||||||
/// - maximum
|
/// - maximum
|
||||||
/// - addtionalProperties
|
/// - addtionalProperties
|
||||||
/// - minItems
|
/// - minItems
|
||||||
/// - maxItems
|
/// - maxItems
|
||||||
///
|
///
|
||||||
/// And the non-standard:
|
/// And the non-standard:
|
||||||
/// - dependencies
|
/// - dependencies
|
||||||
class JsonSchemaChecker
|
class JsonSchemaChecker
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
JsonSchemaChecker();
|
JsonSchemaChecker();
|
||||||
virtual ~JsonSchemaChecker();
|
virtual ~JsonSchemaChecker();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @param schema The schema to use
|
/// @param schema The schema to use
|
||||||
/// @return true upon succes
|
/// @return true upon succes
|
||||||
///
|
///
|
||||||
bool setSchema(const Json::Value & schema);
|
bool setSchema(const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @brief Validate a JSON structure
|
/// @brief Validate a JSON structure
|
||||||
/// @param value The JSON value to check
|
/// @param value The JSON value to check
|
||||||
/// @return true when the arguments is valid according to the schema
|
/// @return true when the arguments is valid according to the schema
|
||||||
///
|
///
|
||||||
bool validate(const Json::Value & value);
|
bool validate(const Json::Value & value);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @return A list of error messages
|
/// @return A list of error messages
|
||||||
///
|
///
|
||||||
const std::list<std::string> & getMessages() const;
|
const std::list<std::string> & getMessages() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
///
|
///
|
||||||
/// Validates a json-value against a given schema. Results are stored in the members of this
|
/// Validates a json-value against a given schema. Results are stored in the members of this
|
||||||
/// class (_error & _messages)
|
/// class (_error & _messages)
|
||||||
///
|
///
|
||||||
/// @param[in] value The value to validate
|
/// @param[in] value The value to validate
|
||||||
/// @param[in] schema The schema against which the value is validated
|
/// @param[in] schema The schema against which the value is validated
|
||||||
///
|
///
|
||||||
void validate(const Json::Value &value, const Json::Value & schema);
|
void validate(const Json::Value &value, const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Adds the given message to the message-queue (with reference to current line-number)
|
/// Adds the given message to the message-queue (with reference to current line-number)
|
||||||
///
|
///
|
||||||
/// @param[in] message The message to add to the queue
|
/// @param[in] message The message to add to the queue
|
||||||
///
|
///
|
||||||
void setMessage(const std::string & message);
|
void setMessage(const std::string & message);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Retrieves all references from the json-value as specified by the schema
|
/// Retrieves all references from the json-value as specified by the schema
|
||||||
///
|
///
|
||||||
/// @param[in] value The json-value
|
/// @param[in] value The json-value
|
||||||
/// @param[in] schema The schema
|
/// @param[in] schema The schema
|
||||||
///
|
///
|
||||||
void collectDependencies(const Json::Value & value, const Json::Value &schema);
|
void collectDependencies(const Json::Value & value, const Json::Value &schema);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// attribute check functions
|
// attribute check functions
|
||||||
///
|
///
|
||||||
/// Checks if the given value is of the specified type. If the type does not match _error is set
|
/// Checks if the given value is of the specified type. If the type does not match _error is set
|
||||||
/// to true and an error-message is added to the message-queue
|
/// to true and an error-message is added to the message-queue
|
||||||
///
|
///
|
||||||
/// @param[in] value The given value
|
/// @param[in] value The given value
|
||||||
/// @param[in] schema The specified type (as json-value)
|
/// @param[in] schema The specified type (as json-value)
|
||||||
///
|
///
|
||||||
void checkType(const Json::Value & value, const Json::Value & schema);
|
void checkType(const Json::Value & value, const Json::Value & schema);
|
||||||
///
|
///
|
||||||
/// Checks is required properties of an json-object exist and if all properties are of the
|
/// Checks is required properties of an json-object exist and if all properties are of the
|
||||||
/// correct format. If this is not the case _error is set to true and an error-message is added
|
/// correct format. If this is not the case _error is set to true and an error-message is added
|
||||||
/// to the message-queue.
|
/// to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param[in] value The given json-object
|
/// @param[in] value The given json-object
|
||||||
/// @param[in] schema The schema of the json-object
|
/// @param[in] schema The schema of the json-object
|
||||||
///
|
///
|
||||||
void checkProperties(const Json::Value & value, const Json::Value & schema);
|
void checkProperties(const Json::Value & value, const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Verifies the additional configured properties of an json-object. If this is not the case
|
/// Verifies the additional configured properties of an json-object. If this is not the case
|
||||||
/// _error is set to true and an error-message is added to the message-queue.
|
/// _error is set to true and an error-message is added to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param value The given json-object
|
/// @param value The given json-object
|
||||||
/// @param schema The schema for the json-object
|
/// @param schema The schema for the json-object
|
||||||
/// @param ignoredProperties The properties that were ignored
|
/// @param ignoredProperties The properties that were ignored
|
||||||
///
|
///
|
||||||
void checkAdditionalProperties(const Json::Value & value, const Json::Value & schema, const Json::Value::Members & ignoredProperties);
|
void checkAdditionalProperties(const Json::Value & value, const Json::Value & schema, const Json::Value::Members & ignoredProperties);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Checks if references are configued and used correctly. If this is not the case _error is set
|
/// Checks if references are configued and used correctly. If this is not the case _error is set
|
||||||
/// to true and an error-message is added to the message-queue.
|
/// to true and an error-message is added to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param value The given json-object
|
/// @param value The given json-object
|
||||||
/// @param schemaLink The schema of the json-object
|
/// @param schemaLink The schema of the json-object
|
||||||
///
|
///
|
||||||
void checkDependencies(const Json::Value & value, const Json::Value & schemaLink);
|
void checkDependencies(const Json::Value & value, const Json::Value & schemaLink);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Checks if the given value is larger or equal to the specified value. If this is not the case
|
/// Checks if the given value is larger or equal to the specified value. If this is not the case
|
||||||
/// _error is set to true and an error-message is added to the message-queue.
|
/// _error is set to true and an error-message is added to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param[in] value The given value
|
/// @param[in] value The given value
|
||||||
/// @param[in] schema The minimum value (as json-value)
|
/// @param[in] schema The minimum value (as json-value)
|
||||||
///
|
///
|
||||||
void checkMinimum(const Json::Value & value, const Json::Value & schema);
|
void checkMinimum(const Json::Value & value, const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Checks if the given value is smaller or equal to the specified value. If this is not the
|
/// Checks if the given value is smaller or equal to the specified value. If this is not the
|
||||||
/// case _error is set to true and an error-message is added to the message-queue.
|
/// case _error is set to true and an error-message is added to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param[in] value The given value
|
/// @param[in] value The given value
|
||||||
/// @param[in] schema The maximum value (as json-value)
|
/// @param[in] schema The maximum value (as json-value)
|
||||||
///
|
///
|
||||||
void checkMaximum(const Json::Value & value, const Json::Value & schema);
|
void checkMaximum(const Json::Value & value, const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Validates all the items of an array.
|
/// Validates all the items of an array.
|
||||||
///
|
///
|
||||||
/// @param value The json-array
|
/// @param value The json-array
|
||||||
/// @param schema The schema for the items in the array
|
/// @param schema The schema for the items in the array
|
||||||
///
|
///
|
||||||
void checkItems(const Json::Value & value, const Json::Value & schema);
|
void checkItems(const Json::Value & value, const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Checks if a given array has at least a minimum number of items. If this is not the case
|
/// Checks if a given array has at least a minimum number of items. If this is not the case
|
||||||
/// _error is set to true and an error-message is added to the message-queue.
|
/// _error is set to true and an error-message is added to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param value The json-array
|
/// @param value The json-array
|
||||||
/// @param schema The minimum size specification (as json-value)
|
/// @param schema The minimum size specification (as json-value)
|
||||||
///
|
///
|
||||||
void checkMinItems(const Json::Value & value, const Json::Value & schema);
|
void checkMinItems(const Json::Value & value, const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Checks if a given array has at most a maximum number of items. If this is not the case
|
/// Checks if a given array has at most a maximum number of items. If this is not the case
|
||||||
/// _error is set to true and an error-message is added to the message-queue.
|
/// _error is set to true and an error-message is added to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param value The json-array
|
/// @param value The json-array
|
||||||
/// @param schema The maximum size specification (as json-value)
|
/// @param schema The maximum size specification (as json-value)
|
||||||
///
|
///
|
||||||
void checkMaxItems(const Json::Value & value, const Json::Value & schema);
|
void checkMaxItems(const Json::Value & value, const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Checks if a given array contains only unique items. If this is not the case
|
/// Checks if a given array contains only unique items. If this is not the case
|
||||||
/// _error is set to true and an error-message is added to the message-queue.
|
/// _error is set to true and an error-message is added to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param value The json-array
|
/// @param value The json-array
|
||||||
/// @param schema Bool to enable the check (as json-value)
|
/// @param schema Bool to enable the check (as json-value)
|
||||||
///
|
///
|
||||||
void checkUniqueItems(const Json::Value & value, const Json::Value & schema);
|
void checkUniqueItems(const Json::Value & value, const Json::Value & schema);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Checks if an enum value is actually a valid value for that enum. If this is not the case
|
/// Checks if an enum value is actually a valid value for that enum. If this is not the case
|
||||||
/// _error is set to true and an error-message is added to the message-queue.
|
/// _error is set to true and an error-message is added to the message-queue.
|
||||||
///
|
///
|
||||||
/// @param value The enum value
|
/// @param value The enum value
|
||||||
/// @param schema The enum schema definition
|
/// @param schema The enum schema definition
|
||||||
///
|
///
|
||||||
void checkEnum(const Json::Value & value, const Json::Value & schema);
|
void checkEnum(const Json::Value & value, const Json::Value & schema);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The schema of the entire json-configuration
|
/// The schema of the entire json-configuration
|
||||||
Json::Value _schema;
|
Json::Value _schema;
|
||||||
|
|
||||||
/// The current location into a json-configuration structure being checked
|
/// The current location into a json-configuration structure being checked
|
||||||
std::list<std::string> _currentPath;
|
std::list<std::string> _currentPath;
|
||||||
/// The result messages collected during the schema verification
|
/// The result messages collected during the schema verification
|
||||||
std::list<std::string> _messages;
|
std::list<std::string> _messages;
|
||||||
/// Flag indicating an error occured during validation
|
/// Flag indicating an error occured during validation
|
||||||
bool _error;
|
bool _error;
|
||||||
|
|
||||||
/// A list with references (string => json-value)
|
/// A list with references (string => json-value)
|
||||||
std::map<std::string, const Json::Value *> _references; // ref 2 value
|
std::map<std::string, const Json::Value *> _references; // ref 2 value
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ add_subdirectory(jsonserver)
|
|||||||
|
|
||||||
if (ENABLE_PROTOBUF)
|
if (ENABLE_PROTOBUF)
|
||||||
add_subdirectory(protoserver)
|
add_subdirectory(protoserver)
|
||||||
endif (ENABLE_PROTOBUF)
|
endif ()
|
||||||
|
|
||||||
add_subdirectory(boblightserver)
|
add_subdirectory(boblightserver)
|
||||||
add_subdirectory(leddevice)
|
add_subdirectory(leddevice)
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/blackborder)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/blackborder)
|
||||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/blackborder)
|
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/blackborder)
|
||||||
|
|
||||||
SET(Blackborder_HEADERS
|
SET(Blackborder_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/BlackBorderDetector.h
|
${CURRENT_HEADER_DIR}/BlackBorderDetector.h
|
||||||
${CURRENT_HEADER_DIR}/BlackBorderProcessor.h
|
${CURRENT_HEADER_DIR}/BlackBorderProcessor.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(Blackborder_SOURCES
|
SET(Blackborder_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp
|
${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp
|
||||||
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp
|
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
add_library(blackborder
|
add_library(blackborder
|
||||||
${Blackborder_HEADERS}
|
${Blackborder_HEADERS}
|
||||||
${Blackborder_SOURCES}
|
${Blackborder_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(blackborder
|
target_link_libraries(blackborder
|
||||||
hyperion-utils
|
hyperion-utils
|
||||||
)
|
)
|
||||||
|
@ -1,40 +1,40 @@
|
|||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/boblightserver)
|
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/boblightserver)
|
||||||
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/boblightserver)
|
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/boblightserver)
|
||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
set(BoblightServer_QT_HEADERS
|
set(BoblightServer_QT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/BoblightServer.h
|
${CURRENT_HEADER_DIR}/BoblightServer.h
|
||||||
${CURRENT_SOURCE_DIR}/BoblightClientConnection.h
|
${CURRENT_SOURCE_DIR}/BoblightClientConnection.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(BoblightServer_HEADERS
|
set(BoblightServer_HEADERS
|
||||||
)
|
)
|
||||||
|
|
||||||
set(BoblightServer_SOURCES
|
set(BoblightServer_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/BoblightServer.cpp
|
${CURRENT_SOURCE_DIR}/BoblightServer.cpp
|
||||||
${CURRENT_SOURCE_DIR}/BoblightClientConnection.cpp
|
${CURRENT_SOURCE_DIR}/BoblightClientConnection.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS})
|
qt5_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
qt4_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS})
|
qt4_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(boblightserver
|
add_library(boblightserver
|
||||||
${BoblightServer_HEADERS}
|
${BoblightServer_HEADERS}
|
||||||
${BoblightServer_QT_HEADERS}
|
${BoblightServer_QT_HEADERS}
|
||||||
${BoblightServer_SOURCES}
|
${BoblightServer_SOURCES}
|
||||||
${BoblightServer_HEADERS_MOC}
|
${BoblightServer_HEADERS_MOC}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_use_modules(boblightserver Widgets)
|
qt5_use_modules(boblightserver Widgets)
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
target_link_libraries(boblightserver
|
target_link_libraries(boblightserver
|
||||||
hyperion
|
hyperion
|
||||||
hyperion-utils
|
hyperion-utils
|
||||||
${QT_LIBRARIES})
|
${QT_LIBRARIES})
|
||||||
|
@ -13,8 +13,8 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/effectengine)
|
|||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
SET(EffectEngineQT_HEADERS
|
SET(EffectEngineQT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/EffectEngine.h
|
${CURRENT_HEADER_DIR}/EffectEngine.h
|
||||||
${CURRENT_SOURCE_DIR}/Effect.h
|
${CURRENT_SOURCE_DIR}/Effect.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(EffectEngineHEADERS
|
SET(EffectEngineHEADERS
|
||||||
@ -22,35 +22,34 @@ SET(EffectEngineHEADERS
|
|||||||
)
|
)
|
||||||
|
|
||||||
SET(EffectEngineSOURCES
|
SET(EffectEngineSOURCES
|
||||||
${CURRENT_SOURCE_DIR}/EffectEngine.cpp
|
${CURRENT_SOURCE_DIR}/EffectEngine.cpp
|
||||||
${CURRENT_SOURCE_DIR}/Effect.cpp
|
${CURRENT_SOURCE_DIR}/Effect.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
set(EffectEngine_RESOURCES ${CURRENT_SOURCE_DIR}/EffectEngine.qrc)
|
set(EffectEngine_RESOURCES ${CURRENT_SOURCE_DIR}/EffectEngine.qrc)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
|
QT5_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
|
||||||
qt5_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
|
qt5_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
QT4_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
|
QT4_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
|
||||||
qt4_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
|
qt4_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(effectengine
|
add_library(effectengine
|
||||||
${EffectEngineHEADERS}
|
${EffectEngineHEADERS}
|
||||||
${EffectEngineQT_HEADERS}
|
${EffectEngineQT_HEADERS}
|
||||||
${EffectEngineHEADERS_MOC}
|
${EffectEngineHEADERS_MOC}
|
||||||
${EffectEngine_RESOURCES_RCC}
|
${EffectEngine_RESOURCES_RCC}
|
||||||
${EffectEngineSOURCES}
|
${EffectEngineSOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_use_modules(effectengine Widgets)
|
qt5_use_modules(effectengine Widgets)
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
target_link_libraries(effectengine
|
target_link_libraries(effectengine
|
||||||
hyperion
|
hyperion
|
||||||
jsoncpp
|
jsoncpp
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
${PYTHON_LIBRARIES})
|
${PYTHON_LIBRARIES})
|
||||||
|
@ -1,342 +1,342 @@
|
|||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"device" : {
|
"device" : {
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"name" : {
|
"name" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"type" : {
|
"type" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"output" : {
|
"output" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"rate" : {
|
"rate" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"minimum" : 0
|
"minimum" : 0
|
||||||
},
|
},
|
||||||
"colorOrder" : {
|
"colorOrder" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : false
|
"required" : false
|
||||||
},
|
},
|
||||||
"bgr-output" : { // deprecated
|
"bgr-output" : { // deprecated
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : false
|
"required" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"color": {
|
"color": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":false,
|
"required":false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"hsv" : {
|
"hsv" : {
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"saturationGain" : {
|
"saturationGain" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.0
|
"minimum" : 0.0
|
||||||
},
|
},
|
||||||
"valueGain" : {
|
"valueGain" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.0
|
"minimum" : 0.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"red": {
|
"red": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":false,
|
"required":false,
|
||||||
"properties":{
|
"properties":{
|
||||||
"gamma": {
|
"gamma": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"whitelevel": {
|
"whitelevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"threshold": {
|
"threshold": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false,
|
"required":false,
|
||||||
"minimum" : 0.0,
|
"minimum" : 0.0,
|
||||||
"maximum" : 1.0
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"green": {
|
"green": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":false,
|
"required":false,
|
||||||
"properties":{
|
"properties":{
|
||||||
"gamma": {
|
"gamma": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"whitelevel": {
|
"whitelevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"threshold": {
|
"threshold": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false,
|
"required":false,
|
||||||
"minimum" : 0.0,
|
"minimum" : 0.0,
|
||||||
"maximum" : 1.0
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"blue": {
|
"blue": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":false,
|
"required":false,
|
||||||
"properties":{
|
"properties":{
|
||||||
"gamma": {
|
"gamma": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"whitelevel": {
|
"whitelevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"threshold": {
|
"threshold": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false,
|
"required":false,
|
||||||
"minimum" : 0.0,
|
"minimum" : 0.0,
|
||||||
"maximum" : 1.0
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"smoothing" : {
|
"smoothing" : {
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"type" : {
|
"type" : {
|
||||||
"type" : "enum",
|
"type" : "enum",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"values" : ["none", "linear"]
|
"values" : ["none", "linear"]
|
||||||
},
|
},
|
||||||
"time_ms" : {
|
"time_ms" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 10
|
"minimum" : 10
|
||||||
},
|
},
|
||||||
"updateFrequency" : {
|
"updateFrequency" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.001
|
"minimum" : 0.001
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"leds": {
|
"leds": {
|
||||||
"type":"array",
|
"type":"array",
|
||||||
"required":true,
|
"required":true,
|
||||||
"items": {
|
"items": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"index": {
|
"index": {
|
||||||
"type":"integer",
|
"type":"integer",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"hscan": {
|
"hscan": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":true,
|
"required":true,
|
||||||
"properties": {
|
"properties": {
|
||||||
"minimum": {
|
"minimum": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"maximum": {
|
"maximum": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"vscan": {
|
"vscan": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":true,
|
"required":true,
|
||||||
"properties": {
|
"properties": {
|
||||||
"minimum": {
|
"minimum": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"maximum": {
|
"maximum": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects" :
|
"effects" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"paths" : {
|
"paths" : {
|
||||||
"type" : "array",
|
"type" : "array",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"items" : {
|
"items" : {
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"blackborderdetector" :
|
"blackborderdetector" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"enable" : {
|
"enable" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"xbmcVideoChecker" :
|
"xbmcVideoChecker" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"xbmcAddress" : {
|
"xbmcAddress" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"xbmcTcpPort" : {
|
"xbmcTcpPort" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabVideo" : {
|
"grabVideo" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabPictures" : {
|
"grabPictures" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabAudio" : {
|
"grabAudio" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabMenu" : {
|
"grabMenu" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"bootsequence" :
|
"bootsequence" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"path" : {
|
"path" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"effect" : {
|
"effect" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"framegrabber" :
|
"framegrabber" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"width" : {
|
"width" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"height" : {
|
"height" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"frequency_Hz" : {
|
"frequency_Hz" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"jsonServer" :
|
"jsonServer" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"port" : {
|
"port" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"minimum" : 0,
|
"minimum" : 0,
|
||||||
"maximum" : 65535
|
"maximum" : 65535
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"protoServer" :
|
"protoServer" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"port" : {
|
"port" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"minimum" : 0,
|
"minimum" : 0,
|
||||||
"maximum" : 65535
|
"maximum" : 65535
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"boblightServer" :
|
"boblightServer" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"port" : {
|
"port" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"minimum" : 0,
|
"minimum" : 0,
|
||||||
"maximum" : 65535
|
"maximum" : 65535
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
|
@ -1,23 +1,23 @@
|
|||||||
if (ENABLE_AMLOGIC)
|
if (ENABLE_AMLOGIC)
|
||||||
add_subdirectory(amlogic)
|
add_subdirectory(amlogic)
|
||||||
endif (ENABLE_AMLOGIC)
|
endif (ENABLE_AMLOGIC)
|
||||||
|
|
||||||
if (ENABLE_DISPMANX)
|
if (ENABLE_DISPMANX)
|
||||||
add_subdirectory(dispmanx)
|
add_subdirectory(dispmanx)
|
||||||
endif (ENABLE_DISPMANX)
|
endif (ENABLE_DISPMANX)
|
||||||
|
|
||||||
if (ENABLE_FB)
|
if (ENABLE_FB)
|
||||||
add_subdirectory(framebuffer)
|
add_subdirectory(framebuffer)
|
||||||
endif (ENABLE_FB)
|
endif (ENABLE_FB)
|
||||||
|
|
||||||
if (ENABLE_OSX)
|
if (ENABLE_OSX)
|
||||||
add_subdirectory(osx)
|
add_subdirectory(osx)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_V4L2)
|
if (ENABLE_V4L2)
|
||||||
add_subdirectory(v4l2)
|
add_subdirectory(v4l2)
|
||||||
endif (ENABLE_V4L2)
|
endif (ENABLE_V4L2)
|
||||||
|
|
||||||
if (ENABLE_X11)
|
if (ENABLE_X11)
|
||||||
add_subdirectory(x11)
|
add_subdirectory(x11)
|
||||||
endif()
|
endif()
|
||||||
|
@ -1,33 +1,33 @@
|
|||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
||||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/amlogic)
|
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/amlogic)
|
||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
SET(AmlogicQT_HEADERS ${CURRENT_HEADER_DIR}/AmlogicWrapper.h)
|
SET(AmlogicQT_HEADERS ${CURRENT_HEADER_DIR}/AmlogicWrapper.h)
|
||||||
|
|
||||||
SET(AmlogicHEADERS
|
SET(AmlogicHEADERS
|
||||||
${CURRENT_HEADER_DIR}/AmlogicGrabber.h
|
${CURRENT_HEADER_DIR}/AmlogicGrabber.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(AmlogicSOURCES
|
SET(AmlogicSOURCES
|
||||||
${CURRENT_SOURCE_DIR}/AmlogicWrapper.cpp
|
${CURRENT_SOURCE_DIR}/AmlogicWrapper.cpp
|
||||||
${CURRENT_SOURCE_DIR}/AmlogicGrabber.cpp
|
${CURRENT_SOURCE_DIR}/AmlogicGrabber.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
|
QT5_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else(ENABLE_QT5)
|
||||||
QT4_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
|
QT4_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif(ENABLE_QT5)
|
||||||
|
|
||||||
add_library(amlogic-grabber
|
add_library(amlogic-grabber
|
||||||
${AmlogicHEADERS}
|
${AmlogicHEADERS}
|
||||||
${AmlogicQT_HEADERS}
|
${AmlogicQT_HEADERS}
|
||||||
${AmlogicHEADERS_MOC}
|
${AmlogicHEADERS_MOC}
|
||||||
${AmlogicSOURCES}
|
${AmlogicSOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(amlogic-grabber
|
target_link_libraries(amlogic-grabber
|
||||||
hyperion
|
hyperion
|
||||||
${QT_LIBRARIES})
|
${QT_LIBRARIES})
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
|
|
||||||
# Find the BCM-package (VC control)
|
# Find the BCM-package (VC control)
|
||||||
find_package(BCM REQUIRED)
|
find_package(BCM REQUIRED)
|
||||||
include_directories(${BCM_INCLUDE_DIRS})
|
include_directories(${BCM_INCLUDE_DIRS})
|
||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
||||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/dispmanx)
|
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/dispmanx)
|
||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
SET(DispmanxGrabberQT_HEADERS
|
SET(DispmanxGrabberQT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/DispmanxWrapper.h
|
${CURRENT_HEADER_DIR}/DispmanxWrapper.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(DispmanxGrabberHEADERS
|
SET(DispmanxGrabberHEADERS
|
||||||
${CURRENT_HEADER_DIR}/DispmanxFrameGrabber.h
|
${CURRENT_HEADER_DIR}/DispmanxFrameGrabber.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(DispmanxGrabberSOURCES
|
SET(DispmanxGrabberSOURCES
|
||||||
${CURRENT_SOURCE_DIR}/DispmanxWrapper.cpp
|
${CURRENT_SOURCE_DIR}/DispmanxWrapper.cpp
|
||||||
${CURRENT_SOURCE_DIR}/DispmanxFrameGrabber.cpp
|
${CURRENT_SOURCE_DIR}/DispmanxFrameGrabber.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS})
|
QT5_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
QT4_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS})
|
QT4_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(dispmanx-grabber
|
add_library(dispmanx-grabber
|
||||||
${DispmanxGrabberHEADERS}
|
${DispmanxGrabberHEADERS}
|
||||||
${DispmanxGrabberQT_HEADERS}
|
${DispmanxGrabberQT_HEADERS}
|
||||||
${DispmanxGrabberHEADERS_MOC}
|
${DispmanxGrabberHEADERS_MOC}
|
||||||
${DispmanxGrabberSOURCES}
|
${DispmanxGrabberSOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(dispmanx-grabber
|
target_link_libraries(dispmanx-grabber
|
||||||
hyperion
|
hyperion
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
${BCM_LIBRARIES}
|
${BCM_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
@ -9,31 +9,31 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/framebuffer)
|
|||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
SET(FramebufferGrabberQT_HEADERS
|
SET(FramebufferGrabberQT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/FramebufferWrapper.h
|
${CURRENT_HEADER_DIR}/FramebufferWrapper.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(FramebufferGrabberHEADERS
|
SET(FramebufferGrabberHEADERS
|
||||||
${CURRENT_HEADER_DIR}/FramebufferFrameGrabber.h
|
${CURRENT_HEADER_DIR}/FramebufferFrameGrabber.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(FramebufferGrabberSOURCES
|
SET(FramebufferGrabberSOURCES
|
||||||
${CURRENT_SOURCE_DIR}/FramebufferWrapper.cpp
|
${CURRENT_SOURCE_DIR}/FramebufferWrapper.cpp
|
||||||
${CURRENT_SOURCE_DIR}/FramebufferFrameGrabber.cpp
|
${CURRENT_SOURCE_DIR}/FramebufferFrameGrabber.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(FramebufferGrabberHEADERS_MOC ${FramebufferGrabberQT_HEADERS})
|
QT5_WRAP_CPP(FramebufferGrabberHEADERS_MOC ${FramebufferGrabberQT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
QT4_WRAP_CPP(FramebufferGrabberHEADERS_MOC ${FramebufferGrabberQT_HEADERS})
|
QT4_WRAP_CPP(FramebufferGrabberHEADERS_MOC ${FramebufferGrabberQT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(framebuffer-grabber
|
add_library(framebuffer-grabber
|
||||||
${FramebufferGrabberHEADERS}
|
${FramebufferGrabberHEADERS}
|
||||||
${FramebufferGrabberQT_HEADERS}
|
${FramebufferGrabberQT_HEADERS}
|
||||||
${FramebufferGrabberHEADERS_MOC}
|
${FramebufferGrabberHEADERS_MOC}
|
||||||
${FramebufferGrabberSOURCES}
|
${FramebufferGrabberSOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(framebuffer-grabber
|
target_link_libraries(framebuffer-grabber
|
||||||
hyperion
|
hyperion
|
||||||
${QT_LIBRARIES})
|
${QT_LIBRARIES})
|
||||||
|
@ -4,31 +4,31 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/osx)
|
|||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
SET(OsxGrabberQT_HEADERS
|
SET(OsxGrabberQT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/OsxWrapper.h
|
${CURRENT_HEADER_DIR}/OsxWrapper.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(OsxGrabberHEADERS
|
SET(OsxGrabberHEADERS
|
||||||
${CURRENT_HEADER_DIR}/OsxFrameGrabber.h
|
${CURRENT_HEADER_DIR}/OsxFrameGrabber.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(OsxGrabberSOURCES
|
SET(OsxGrabberSOURCES
|
||||||
${CURRENT_SOURCE_DIR}/OsxWrapper.cpp
|
${CURRENT_SOURCE_DIR}/OsxWrapper.cpp
|
||||||
${CURRENT_SOURCE_DIR}/OsxFrameGrabber.cpp
|
${CURRENT_SOURCE_DIR}/OsxFrameGrabber.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(OsxGrabberHEADERS_MOC ${OsxGrabberQT_HEADERS})
|
QT5_WRAP_CPP(OsxGrabberHEADERS_MOC ${OsxGrabberQT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
QT4_WRAP_CPP(OsxGrabberHEADERS_MOC ${OsxGrabberQT_HEADERS})
|
QT4_WRAP_CPP(OsxGrabberHEADERS_MOC ${OsxGrabberQT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(osx-grabber
|
add_library(osx-grabber
|
||||||
${OsxGrabberHEADERS}
|
${OsxGrabberHEADERS}
|
||||||
${OsxGrabberQT_HEADERS}
|
${OsxGrabberQT_HEADERS}
|
||||||
${OsxGrabberHEADERS_MOC}
|
${OsxGrabberHEADERS_MOC}
|
||||||
${OsxGrabberSOURCES}
|
${OsxGrabberSOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(osx-grabber
|
target_link_libraries(osx-grabber
|
||||||
hyperion
|
hyperion
|
||||||
${QT_LIBRARIES})
|
${QT_LIBRARIES})
|
||||||
|
@ -1,39 +1,39 @@
|
|||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
|
||||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/v4l2)
|
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/v4l2)
|
||||||
|
|
||||||
SET(V4L2_QT_HEADERS
|
SET(V4L2_QT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/V4L2Grabber.h
|
${CURRENT_HEADER_DIR}/V4L2Grabber.h
|
||||||
${CURRENT_HEADER_DIR}/V4L2Wrapper.h
|
${CURRENT_HEADER_DIR}/V4L2Wrapper.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(V4L2_HEADERS
|
SET(V4L2_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/VideoStandard.h
|
${CURRENT_HEADER_DIR}/VideoStandard.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(V4L2_SOURCES
|
SET(V4L2_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/V4L2Grabber.cpp
|
${CURRENT_SOURCE_DIR}/V4L2Grabber.cpp
|
||||||
${CURRENT_SOURCE_DIR}/V4L2Wrapper.cpp
|
${CURRENT_SOURCE_DIR}/V4L2Wrapper.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS})
|
QT5_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
QT4_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS})
|
QT4_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(v4l2-grabber
|
add_library(v4l2-grabber
|
||||||
${V4L2_HEADERS}
|
${V4L2_HEADERS}
|
||||||
${V4L2_SOURCES}
|
${V4L2_SOURCES}
|
||||||
${V4L2_QT_HEADERS}
|
${V4L2_QT_HEADERS}
|
||||||
${V4L2_HEADERS_MOC}
|
${V4L2_HEADERS_MOC}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_use_modules(v4l2-grabber Widgets)
|
qt5_use_modules(v4l2-grabber Widgets)
|
||||||
endif(ENABLE_QT5)
|
endif(ENABLE_QT5)
|
||||||
|
|
||||||
target_link_libraries(v4l2-grabber
|
target_link_libraries(v4l2-grabber
|
||||||
hyperion
|
hyperion
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -19,20 +19,20 @@ SET(X11_HEADERS
|
|||||||
)
|
)
|
||||||
|
|
||||||
SET(X11_SOURCES
|
SET(X11_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/X11Grabber.cpp
|
${CURRENT_SOURCE_DIR}/X11Grabber.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
|
QT5_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
QT4_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
|
QT4_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(x11-grabber
|
add_library(x11-grabber
|
||||||
${X11_HEADERS}
|
${X11_HEADERS}
|
||||||
${X11_SOURCES}
|
${X11_SOURCES}
|
||||||
${X11_QT_HEADERS}
|
${X11_QT_HEADERS}
|
||||||
${X11_HEADERS_MOC}
|
${X11_HEADERS_MOC}
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(x11-grabber
|
target_link_libraries(x11-grabber
|
||||||
|
@ -6,107 +6,108 @@
|
|||||||
#include <grabber/X11Grabber.h>
|
#include <grabber/X11Grabber.h>
|
||||||
|
|
||||||
X11Grabber::X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation) :
|
X11Grabber::X11Grabber(bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation) :
|
||||||
_imageResampler(),
|
_imageResampler(),
|
||||||
_useXGetImage(useXGetImage),
|
_useXGetImage(useXGetImage),
|
||||||
_cropLeft(cropLeft),
|
_cropLeft(cropLeft),
|
||||||
_cropRight(cropRight),
|
_cropRight(cropRight),
|
||||||
_cropTop(cropTop),
|
_cropTop(cropTop),
|
||||||
_cropBottom(cropBottom),
|
_cropBottom(cropBottom),
|
||||||
_x11Display(nullptr),
|
_x11Display(nullptr),
|
||||||
_pixmap(None),
|
_pixmap(None),
|
||||||
_srcFormat(nullptr),
|
_srcFormat(nullptr),
|
||||||
_dstFormat(nullptr),
|
_dstFormat(nullptr),
|
||||||
_srcPicture(None),
|
_srcPicture(None),
|
||||||
_dstPicture(None),
|
_dstPicture(None),
|
||||||
_screenWidth(0),
|
_screenWidth(0),
|
||||||
_screenHeight(0),
|
_screenHeight(0),
|
||||||
_croppedWidth(0),
|
_croppedWidth(0),
|
||||||
_croppedHeight(0),
|
_croppedHeight(0),
|
||||||
_image(0,0)
|
_image(0,0)
|
||||||
{
|
{
|
||||||
_imageResampler.setHorizontalPixelDecimation(horizontalPixelDecimation);
|
_imageResampler.setHorizontalPixelDecimation(horizontalPixelDecimation);
|
||||||
_imageResampler.setVerticalPixelDecimation(verticalPixelDecimation);
|
_imageResampler.setVerticalPixelDecimation(verticalPixelDecimation);
|
||||||
_imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XShmGetImage or XGetImage
|
_imageResampler.setCropping(0, 0, 0, 0); // cropping is performed by XShmGetImage or XGetImage
|
||||||
memset(&_pictAttr, 0, sizeof(_pictAttr));
|
memset(&_pictAttr, 0, sizeof(_pictAttr));
|
||||||
_pictAttr.repeat = RepeatNone;
|
_pictAttr.repeat = RepeatNone;
|
||||||
}
|
}
|
||||||
|
|
||||||
X11Grabber::~X11Grabber()
|
X11Grabber::~X11Grabber()
|
||||||
{
|
{
|
||||||
if (_x11Display != nullptr)
|
if (_x11Display != nullptr)
|
||||||
{
|
{
|
||||||
freeResources();
|
freeResources();
|
||||||
XCloseDisplay(_x11Display);
|
XCloseDisplay(_x11Display);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Grabber::freeResources()
|
void X11Grabber::freeResources()
|
||||||
{
|
{
|
||||||
// Cleanup allocated resources of the X11 grab
|
// Cleanup allocated resources of the X11 grab
|
||||||
XDestroyImage(_xImage);
|
XDestroyImage(_xImage);
|
||||||
if(_XShmAvailable && !_useXGetImage) {
|
if(_XShmAvailable && !_useXGetImage) {
|
||||||
XShmDetach(_x11Display, &_shminfo);
|
XShmDetach(_x11Display, &_shminfo);
|
||||||
shmdt(_shminfo.shmaddr);
|
shmdt(_shminfo.shmaddr);
|
||||||
shmctl(_shminfo.shmid, IPC_RMID, 0);
|
shmctl(_shminfo.shmid, IPC_RMID, 0);
|
||||||
}
|
}
|
||||||
if (_XRenderAvailable && !_useXGetImage) {
|
if (_XRenderAvailable && !_useXGetImage) {
|
||||||
XRenderFreePicture(_x11Display, _srcPicture);
|
XRenderFreePicture(_x11Display, _srcPicture);
|
||||||
XRenderFreePicture(_x11Display, _dstPicture);
|
XRenderFreePicture(_x11Display, _dstPicture);
|
||||||
XFreePixmap(_x11Display, _pixmap);
|
XFreePixmap(_x11Display, _pixmap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Grabber::setupResources()
|
void X11Grabber::setupResources()
|
||||||
{
|
{
|
||||||
if(_XShmAvailable && !_useXGetImage) {
|
if(_XShmAvailable && !_useXGetImage) {
|
||||||
_xImage = XShmCreateImage(_x11Display, _windowAttr.visual,
|
_xImage = XShmCreateImage(_x11Display, _windowAttr.visual,
|
||||||
_windowAttr.depth, ZPixmap, NULL, &_shminfo,
|
_windowAttr.depth, ZPixmap, NULL, &_shminfo,
|
||||||
_croppedWidth, _croppedHeight);
|
_croppedWidth, _croppedHeight);
|
||||||
|
|
||||||
_shminfo.shmid = shmget(IPC_PRIVATE, _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777);
|
_shminfo.shmid = shmget(IPC_PRIVATE, _xImage->bytes_per_line * _xImage->height, IPC_CREAT|0777);
|
||||||
_xImage->data = (char*)shmat(_shminfo.shmid,0,0);
|
_xImage->data = (char*)shmat(_shminfo.shmid,0,0);
|
||||||
_shminfo.shmaddr = _xImage->data;
|
_shminfo.shmaddr = _xImage->data;
|
||||||
_shminfo.readOnly = False;
|
_shminfo.readOnly = False;
|
||||||
|
|
||||||
XShmAttach(_x11Display, &_shminfo);
|
XShmAttach(_x11Display, &_shminfo);
|
||||||
}
|
|
||||||
if (_XRenderAvailable && !_useXGetImage) {
|
|
||||||
if(_XShmPixmapAvailable) {
|
|
||||||
_pixmap = XShmCreatePixmap(_x11Display, _window, _xImage->data, &_shminfo, _croppedWidth, _croppedHeight, _windowAttr.depth);
|
|
||||||
} else {
|
|
||||||
_pixmap = XCreatePixmap(_x11Display, _window, _croppedWidth, _croppedHeight, _windowAttr.depth);
|
|
||||||
}
|
}
|
||||||
_srcFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual);
|
if (_XRenderAvailable && !_useXGetImage) {
|
||||||
_dstFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual);
|
if(_XShmPixmapAvailable) {
|
||||||
_srcPicture = XRenderCreatePicture(_x11Display, _window, _srcFormat, CPRepeat, &_pictAttr);
|
_pixmap = XShmCreatePixmap(_x11Display, _window, _xImage->data, &_shminfo, _croppedWidth, _croppedHeight, _windowAttr.depth);
|
||||||
_dstPicture = XRenderCreatePicture(_x11Display, _pixmap, _dstFormat, CPRepeat, &_pictAttr);
|
} else {
|
||||||
XRenderSetPictureFilter(_x11Display, _srcPicture, "bilinear", NULL, 0);
|
_pixmap = XCreatePixmap(_x11Display, _window, _croppedWidth, _croppedHeight, _windowAttr.depth);
|
||||||
}
|
}
|
||||||
|
_srcFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual);
|
||||||
|
_dstFormat = XRenderFindVisualFormat(_x11Display, _windowAttr.visual);
|
||||||
|
_srcPicture = XRenderCreatePicture(_x11Display, _window, _srcFormat, CPRepeat, &_pictAttr);
|
||||||
|
_dstPicture = XRenderCreatePicture(_x11Display, _pixmap, _dstFormat, CPRepeat, &_pictAttr);
|
||||||
|
XRenderSetPictureFilter(_x11Display, _srcPicture, "bilinear", NULL, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X11Grabber::Setup()
|
bool X11Grabber::Setup()
|
||||||
{
|
{
|
||||||
_x11Display = XOpenDisplay(NULL);
|
_x11Display = XOpenDisplay(NULL);
|
||||||
if (_x11Display == nullptr)
|
if (_x11Display == nullptr)
|
||||||
{
|
{
|
||||||
std::cerr << "X11GRABBER ERROR: Unable to open display";
|
std::cerr << "X11GRABBER ERROR: Unable to open display";
|
||||||
if (getenv("DISPLAY"))
|
if (getenv("DISPLAY")) {
|
||||||
std::cerr << " " << std::string(getenv("DISPLAY")) << std::endl;
|
std::cerr << " " << std::string(getenv("DISPLAY")) << std::endl;
|
||||||
else
|
} else {
|
||||||
std::cerr << ". DISPLAY environment variable not set" << std::endl;
|
std::cerr << ". DISPLAY environment variable not set" << std::endl;
|
||||||
return false;
|
}
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
_window = DefaultRootWindow(_x11Display);
|
|
||||||
|
_window = DefaultRootWindow(_x11Display);
|
||||||
|
|
||||||
int dummy, pixmaps_supported;
|
int dummy, pixmaps_supported;
|
||||||
|
|
||||||
_XRenderAvailable = XRenderQueryExtension(_x11Display, &dummy, &dummy);
|
_XRenderAvailable = XRenderQueryExtension(_x11Display, &dummy, &dummy);
|
||||||
_XShmAvailable = XShmQueryExtension(_x11Display);
|
_XShmAvailable = XShmQueryExtension(_x11Display);
|
||||||
XShmQueryVersion(_x11Display, &dummy, &dummy, &pixmaps_supported);
|
XShmQueryVersion(_x11Display, &dummy, &dummy, &pixmaps_supported);
|
||||||
_XShmPixmapAvailable = pixmaps_supported && XShmPixmapFormat(_x11Display) == ZPixmap;
|
_XShmPixmapAvailable = pixmaps_supported && XShmPixmapFormat(_x11Display) == ZPixmap;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Image<ColorRgb> & X11Grabber::grab()
|
Image<ColorRgb> & X11Grabber::grab()
|
||||||
@ -129,75 +130,74 @@ Image<ColorRgb> & X11Grabber::grab()
|
|||||||
_croppedHeight); // height
|
_croppedHeight); // height
|
||||||
|
|
||||||
XSync(_x11Display, False);
|
XSync(_x11Display, False);
|
||||||
|
|
||||||
if (_XShmAvailable) {
|
|
||||||
XShmGetImage(_x11Display, _pixmap, _xImage, 0, 0, AllPlanes);
|
|
||||||
} else {
|
|
||||||
_xImage = XGetImage(_x11Display, _pixmap, 0, 0, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (_XShmAvailable && !_useXGetImage) {
|
|
||||||
XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes);
|
|
||||||
} else {
|
|
||||||
_xImage = XGetImage(_x11Display, _window, _cropLeft, _cropTop, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_xImage == nullptr)
|
|
||||||
{
|
|
||||||
std::cerr << "X11GRABBER ERROR: Grab failed" << std::endl;
|
|
||||||
return _image;
|
|
||||||
}
|
|
||||||
|
|
||||||
_imageResampler.processImage(reinterpret_cast<const uint8_t *>(_xImage->data), _xImage->width, _xImage->height, _xImage->bytes_per_line, PIXELFORMAT_BGR32, _image);
|
if (_XShmAvailable) {
|
||||||
|
XShmGetImage(_x11Display, _pixmap, _xImage, 0, 0, AllPlanes);
|
||||||
|
} else {
|
||||||
|
_xImage = XGetImage(_x11Display, _pixmap, 0, 0, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_XShmAvailable && !_useXGetImage) {
|
||||||
|
XShmGetImage(_x11Display, _window, _xImage, _cropLeft, _cropTop, AllPlanes);
|
||||||
|
} else {
|
||||||
|
_xImage = XGetImage(_x11Display, _window, _cropLeft, _cropTop, _croppedWidth, _croppedHeight, AllPlanes, ZPixmap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return _image;
|
if (_xImage == nullptr)
|
||||||
|
{
|
||||||
|
std::cerr << "X11GRABBER ERROR: Grab failed" << std::endl;
|
||||||
|
return _image;
|
||||||
|
}
|
||||||
|
|
||||||
|
_imageResampler.processImage(reinterpret_cast<const uint8_t *>(_xImage->data), _xImage->width, _xImage->height, _xImage->bytes_per_line, PIXELFORMAT_BGR32, _image);
|
||||||
|
|
||||||
|
return _image;
|
||||||
}
|
}
|
||||||
|
|
||||||
int X11Grabber::updateScreenDimensions()
|
int X11Grabber::updateScreenDimensions()
|
||||||
{
|
{
|
||||||
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
|
const Status status = XGetWindowAttributes(_x11Display, _window, &_windowAttr);
|
||||||
if (status == 0)
|
if (status == 0)
|
||||||
{
|
{
|
||||||
std::cerr << "X11GRABBER ERROR: Failed to obtain window attributes" << std::endl;
|
std::cerr << "X11GRABBER ERROR: Failed to obtain window attributes" << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_screenWidth == unsigned(_windowAttr.width) && _screenHeight == unsigned(_windowAttr.height))
|
if (_screenWidth == unsigned(_windowAttr.width) && _screenHeight == unsigned(_windowAttr.height))
|
||||||
{
|
{
|
||||||
// No update required
|
// No update required
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "X11GRABBER INFO: Update of screen resolution: [" << _screenWidth << "x" << _screenHeight <<"] => ";
|
std::cout << "X11GRABBER INFO: Update of screen resolution: [" << _screenWidth << "x" << _screenHeight <<"] => ";
|
||||||
|
|
||||||
if (_screenWidth || _screenHeight)
|
if (_screenWidth || _screenHeight) {
|
||||||
freeResources();
|
freeResources();
|
||||||
|
}
|
||||||
_screenWidth = _windowAttr.width;
|
|
||||||
_screenHeight = _windowAttr.height;
|
|
||||||
|
|
||||||
std::cout << "[" << _screenWidth << "x" << _screenHeight <<"]" << std::endl;
|
|
||||||
|
|
||||||
if (_screenWidth > unsigned(_cropLeft + _cropRight))
|
|
||||||
_croppedWidth = _screenWidth - _cropLeft - _cropRight;
|
|
||||||
else
|
|
||||||
_croppedWidth = _screenWidth;
|
|
||||||
|
|
||||||
if (_screenHeight > unsigned(_cropTop + _cropBottom))
|
|
||||||
_croppedHeight = _screenHeight - _cropTop - _cropBottom;
|
|
||||||
else
|
|
||||||
_croppedHeight = _screenHeight;
|
|
||||||
|
|
||||||
std::cout << "X11GRABBER INFO: Using ";
|
|
||||||
|
|
||||||
if (_XRenderAvailable && !_useXGetImage) {
|
|
||||||
std::cout << "XRender for grabbing" << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << "XGetImage for grabbing" << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
setupResources();
|
|
||||||
|
|
||||||
return 0;
|
_screenWidth = _windowAttr.width;
|
||||||
|
_screenHeight = _windowAttr.height;
|
||||||
|
|
||||||
|
std::cout << "[" << _screenWidth << "x" << _screenHeight <<"]" << std::endl;
|
||||||
|
|
||||||
|
_croppedWidth = (_screenWidth > unsigned(_cropLeft + _cropRight))
|
||||||
|
? (_screenWidth - _cropLeft - _cropRight)
|
||||||
|
: _screenWidth;
|
||||||
|
|
||||||
|
_croppedHeight = (_screenHeight > unsigned(_cropTop + _cropBottom))
|
||||||
|
? (_screenHeight - _cropTop - _cropBottom)
|
||||||
|
: (_croppedHeight = _screenHeight);
|
||||||
|
|
||||||
|
std::cout << "X11GRABBER INFO: Using ";
|
||||||
|
|
||||||
|
if (_XRenderAvailable && !_useXGetImage) {
|
||||||
|
std::cout << "XRender for grabbing" << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cout << "XGetImage for grabbing" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
setupResources();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,72 +1,72 @@
|
|||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/hyperion)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/hyperion)
|
||||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/hyperion)
|
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/hyperion)
|
||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
SET(Hyperion_QT_HEADERS
|
SET(Hyperion_QT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/Hyperion.h
|
${CURRENT_HEADER_DIR}/Hyperion.h
|
||||||
|
|
||||||
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.h
|
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(Hyperion_HEADERS
|
SET(Hyperion_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/ImageProcessor.h
|
${CURRENT_HEADER_DIR}/ImageProcessor.h
|
||||||
${CURRENT_HEADER_DIR}/ImageProcessorFactory.h
|
${CURRENT_HEADER_DIR}/ImageProcessorFactory.h
|
||||||
${CURRENT_HEADER_DIR}/ImageToLedsMap.h
|
${CURRENT_HEADER_DIR}/ImageToLedsMap.h
|
||||||
${CURRENT_HEADER_DIR}/LedString.h
|
${CURRENT_HEADER_DIR}/LedString.h
|
||||||
${CURRENT_HEADER_DIR}/PriorityMuxer.h
|
${CURRENT_HEADER_DIR}/PriorityMuxer.h
|
||||||
|
|
||||||
${CURRENT_SOURCE_DIR}/MultiColorTransform.h
|
${CURRENT_SOURCE_DIR}/MultiColorTransform.h
|
||||||
${CURRENT_SOURCE_DIR}/MultiColorCorrection.h
|
${CURRENT_SOURCE_DIR}/MultiColorCorrection.h
|
||||||
${CURRENT_SOURCE_DIR}/MultiColorAdjustment.h
|
${CURRENT_SOURCE_DIR}/MultiColorAdjustment.h
|
||||||
${CURRENT_HEADER_DIR}/MessageForwarder.h
|
${CURRENT_HEADER_DIR}/MessageForwarder.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(Hyperion_SOURCES
|
SET(Hyperion_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/Hyperion.cpp
|
${CURRENT_SOURCE_DIR}/Hyperion.cpp
|
||||||
${CURRENT_SOURCE_DIR}/ImageProcessor.cpp
|
${CURRENT_SOURCE_DIR}/ImageProcessor.cpp
|
||||||
${CURRENT_SOURCE_DIR}/ImageProcessorFactory.cpp
|
${CURRENT_SOURCE_DIR}/ImageProcessorFactory.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedString.cpp
|
${CURRENT_SOURCE_DIR}/LedString.cpp
|
||||||
${CURRENT_SOURCE_DIR}/PriorityMuxer.cpp
|
${CURRENT_SOURCE_DIR}/PriorityMuxer.cpp
|
||||||
|
|
||||||
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
|
${CURRENT_SOURCE_DIR}/ImageToLedsMap.cpp
|
||||||
${CURRENT_SOURCE_DIR}/MultiColorTransform.cpp
|
${CURRENT_SOURCE_DIR}/MultiColorTransform.cpp
|
||||||
${CURRENT_SOURCE_DIR}/MultiColorCorrection.cpp
|
${CURRENT_SOURCE_DIR}/MultiColorCorrection.cpp
|
||||||
${CURRENT_SOURCE_DIR}/MultiColorAdjustment.cpp
|
${CURRENT_SOURCE_DIR}/MultiColorAdjustment.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp
|
${CURRENT_SOURCE_DIR}/LinearColorSmoothing.cpp
|
||||||
${CURRENT_SOURCE_DIR}/MessageForwarder.cpp
|
${CURRENT_SOURCE_DIR}/MessageForwarder.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(Hyperion_RESOURCES
|
SET(Hyperion_RESOURCES
|
||||||
${CURRENT_SOURCE_DIR}/resource.qrc
|
${CURRENT_SOURCE_DIR}/resource.qrc
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS})
|
QT5_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS})
|
||||||
QT5_ADD_RESOURCES(Hyperion_RESOURCES_RCC ${Hyperion_RESOURCES} OPTIONS "-no-compress")
|
QT5_ADD_RESOURCES(Hyperion_RESOURCES_RCC ${Hyperion_RESOURCES} OPTIONS "-no-compress")
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
QT4_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS})
|
QT4_WRAP_CPP(Hyperion_HEADERS_MOC ${Hyperion_QT_HEADERS})
|
||||||
QT4_ADD_RESOURCES(Hyperion_RESOURCES_RCC ${Hyperion_RESOURCES} OPTIONS "-no-compress")
|
QT4_ADD_RESOURCES(Hyperion_RESOURCES_RCC ${Hyperion_RESOURCES} OPTIONS "-no-compress")
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(hyperion
|
add_library(hyperion
|
||||||
${Hyperion_HEADERS}
|
${Hyperion_HEADERS}
|
||||||
${Hyperion_QT_HEADERS}
|
${Hyperion_QT_HEADERS}
|
||||||
${Hyperion_HEADERS_MOC}
|
${Hyperion_HEADERS_MOC}
|
||||||
${Hyperion_SOURCES}
|
${Hyperion_SOURCES}
|
||||||
${Hyperion_RESOURCES_RCC}
|
${Hyperion_RESOURCES_RCC}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_use_modules(hyperion Widgets)
|
qt5_use_modules(hyperion Widgets)
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
target_link_libraries(hyperion
|
target_link_libraries(hyperion
|
||||||
blackborder
|
blackborder
|
||||||
hyperion-utils
|
hyperion-utils
|
||||||
leddevice
|
leddevice
|
||||||
effectengine
|
effectengine
|
||||||
serialport
|
serialport
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
@ -1,382 +1,382 @@
|
|||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"device" : {
|
"device" : {
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"name" : {
|
"name" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"type" : {
|
"type" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"output" : {
|
"output" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"rate" : {
|
"rate" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"minimum" : 0
|
"minimum" : 0
|
||||||
},
|
},
|
||||||
"colorOrder" : {
|
"colorOrder" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : false
|
"required" : false
|
||||||
},
|
},
|
||||||
"bgr-output" : { // deprecated
|
"bgr-output" : { // deprecated
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : false
|
"required" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"color": {
|
"color": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":false,
|
"required":false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"hsv" : {
|
"hsv" : {
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"saturationGain" : {
|
"saturationGain" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.0
|
"minimum" : 0.0
|
||||||
},
|
},
|
||||||
"valueGain" : {
|
"valueGain" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.0
|
"minimum" : 0.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"hsl" : {
|
"hsl" : {
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"saturationGain" : {
|
"saturationGain" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.0
|
"minimum" : 0.0
|
||||||
},
|
},
|
||||||
"luminanceGain" : {
|
"luminanceGain" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.0
|
"minimum" : 0.0
|
||||||
},
|
},
|
||||||
"luminanceMinimum" : {
|
"luminanceMinimum" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.0
|
"minimum" : 0.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"red": {
|
"red": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":false,
|
"required":false,
|
||||||
"properties":{
|
"properties":{
|
||||||
"gamma": {
|
"gamma": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"whitelevel": {
|
"whitelevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"threshold": {
|
"threshold": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false,
|
"required":false,
|
||||||
"minimum" : 0.0,
|
"minimum" : 0.0,
|
||||||
"maximum" : 1.0
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"green": {
|
"green": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":false,
|
"required":false,
|
||||||
"properties":{
|
"properties":{
|
||||||
"gamma": {
|
"gamma": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"whitelevel": {
|
"whitelevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"threshold": {
|
"threshold": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false,
|
"required":false,
|
||||||
"minimum" : 0.0,
|
"minimum" : 0.0,
|
||||||
"maximum" : 1.0
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"blue": {
|
"blue": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":false,
|
"required":false,
|
||||||
"properties":{
|
"properties":{
|
||||||
"gamma": {
|
"gamma": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"whitelevel": {
|
"whitelevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"blacklevel": {
|
"blacklevel": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false
|
"required":false
|
||||||
},
|
},
|
||||||
"threshold": {
|
"threshold": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":false,
|
"required":false,
|
||||||
"minimum" : 0.0,
|
"minimum" : 0.0,
|
||||||
"maximum" : 1.0
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"smoothing" : {
|
"smoothing" : {
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"type" : {
|
"type" : {
|
||||||
"type" : "enum",
|
"type" : "enum",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"values" : ["none", "linear"]
|
"values" : ["none", "linear"]
|
||||||
},
|
},
|
||||||
"time_ms" : {
|
"time_ms" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 10
|
"minimum" : 10
|
||||||
},
|
},
|
||||||
"updateFrequency" : {
|
"updateFrequency" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.001
|
"minimum" : 0.001
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
|
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"leds": {
|
"leds": {
|
||||||
"type":"array",
|
"type":"array",
|
||||||
"required":true,
|
"required":true,
|
||||||
"items": {
|
"items": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"index": {
|
"index": {
|
||||||
"type":"integer",
|
"type":"integer",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"hscan": {
|
"hscan": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":true,
|
"required":true,
|
||||||
"properties": {
|
"properties": {
|
||||||
"minimum": {
|
"minimum": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"maximum": {
|
"maximum": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"vscan": {
|
"vscan": {
|
||||||
"type":"object",
|
"type":"object",
|
||||||
"required":true,
|
"required":true,
|
||||||
"properties": {
|
"properties": {
|
||||||
"minimum": {
|
"minimum": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
},
|
},
|
||||||
"maximum": {
|
"maximum": {
|
||||||
"type":"number",
|
"type":"number",
|
||||||
"required":true
|
"required":true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"colorOrder" : {
|
"colorOrder" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : false
|
"required" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"effects" :
|
"effects" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"paths" : {
|
"paths" : {
|
||||||
"type" : "array",
|
"type" : "array",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"items" : {
|
"items" : {
|
||||||
"type" : "string"
|
"type" : "string"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"blackborderdetector" :
|
"blackborderdetector" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"enable" : {
|
"enable" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"threshold" : {
|
"threshold" : {
|
||||||
"type" : "number",
|
"type" : "number",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"minimum" : 0.0,
|
"minimum" : 0.0,
|
||||||
"maximum" : 1.0
|
"maximum" : 1.0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"xbmcVideoChecker" :
|
"xbmcVideoChecker" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"xbmcAddress" : {
|
"xbmcAddress" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"xbmcTcpPort" : {
|
"xbmcTcpPort" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabVideo" : {
|
"grabVideo" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabPictures" : {
|
"grabPictures" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabAudio" : {
|
"grabAudio" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabMenu" : {
|
"grabMenu" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"grabScreensaver" : {
|
"grabScreensaver" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : false
|
"required" : false
|
||||||
},
|
},
|
||||||
"enable3DDetection" : {
|
"enable3DDetection" : {
|
||||||
"type" : "boolean",
|
"type" : "boolean",
|
||||||
"required" : false
|
"required" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"bootsequence" :
|
"bootsequence" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"path" : {
|
"path" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"effect" : {
|
"effect" : {
|
||||||
"type" : "string",
|
"type" : "string",
|
||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"framegrabber" :
|
"framegrabber" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"width" : {
|
"width" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"height" : {
|
"height" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : true
|
||||||
},
|
},
|
||||||
"frequency_Hz" : {
|
"frequency_Hz" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true
|
"required" : true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"jsonServer" :
|
"jsonServer" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"port" : {
|
"port" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"minimum" : 0,
|
"minimum" : 0,
|
||||||
"maximum" : 65535
|
"maximum" : 65535
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"protoServer" :
|
"protoServer" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"port" : {
|
"port" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"minimum" : 0,
|
"minimum" : 0,
|
||||||
"maximum" : 65535
|
"maximum" : 65535
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
},
|
},
|
||||||
"boblightServer" :
|
"boblightServer" :
|
||||||
{
|
{
|
||||||
"type" : "object",
|
"type" : "object",
|
||||||
"required" : false,
|
"required" : false,
|
||||||
"properties" : {
|
"properties" : {
|
||||||
"port" : {
|
"port" : {
|
||||||
"type" : "integer",
|
"type" : "integer",
|
||||||
"required" : true,
|
"required" : true,
|
||||||
"minimum" : 0,
|
"minimum" : 0,
|
||||||
"maximum" : 65535
|
"maximum" : 65535
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"additionalProperties" : false
|
"additionalProperties" : false
|
||||||
}
|
}
|
||||||
|
@ -1,48 +1,48 @@
|
|||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/jsonserver)
|
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/jsonserver)
|
||||||
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/jsonserver)
|
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/jsonserver)
|
||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
set(JsonServer_QT_HEADERS
|
set(JsonServer_QT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/JsonServer.h
|
${CURRENT_HEADER_DIR}/JsonServer.h
|
||||||
${CURRENT_SOURCE_DIR}/JsonClientConnection.h
|
${CURRENT_SOURCE_DIR}/JsonClientConnection.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(JsonServer_HEADERS
|
set(JsonServer_HEADERS
|
||||||
)
|
)
|
||||||
|
|
||||||
set(JsonServer_SOURCES
|
set(JsonServer_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/JsonServer.cpp
|
${CURRENT_SOURCE_DIR}/JsonServer.cpp
|
||||||
${CURRENT_SOURCE_DIR}/JsonClientConnection.cpp
|
${CURRENT_SOURCE_DIR}/JsonClientConnection.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(JsonServer_RESOURCES
|
set(JsonServer_RESOURCES
|
||||||
${CURRENT_SOURCE_DIR}/JsonSchemas.qrc
|
${CURRENT_SOURCE_DIR}/JsonSchemas.qrc
|
||||||
)
|
)
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_wrap_cpp(JsonServer_HEADERS_MOC ${JsonServer_QT_HEADERS})
|
qt5_wrap_cpp(JsonServer_HEADERS_MOC ${JsonServer_QT_HEADERS})
|
||||||
qt5_add_resources(JsonServer_RESOURCES_RCC ${JsonServer_RESOURCES} OPTIONS "-no-compress")
|
qt5_add_resources(JsonServer_RESOURCES_RCC ${JsonServer_RESOURCES} OPTIONS "-no-compress")
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
qt4_wrap_cpp(JsonServer_HEADERS_MOC ${JsonServer_QT_HEADERS})
|
qt4_wrap_cpp(JsonServer_HEADERS_MOC ${JsonServer_QT_HEADERS})
|
||||||
qt4_add_resources(JsonServer_RESOURCES_RCC ${JsonServer_RESOURCES} OPTIONS "-no-compress")
|
qt4_add_resources(JsonServer_RESOURCES_RCC ${JsonServer_RESOURCES} OPTIONS "-no-compress")
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(jsonserver
|
add_library(jsonserver
|
||||||
${JsonServer_HEADERS}
|
${JsonServer_HEADERS}
|
||||||
${JsonServer_QT_HEADERS}
|
${JsonServer_QT_HEADERS}
|
||||||
${JsonServer_SOURCES}
|
${JsonServer_SOURCES}
|
||||||
${JsonServer_RESOURCES}
|
${JsonServer_RESOURCES}
|
||||||
${JsonServer_HEADERS_MOC}
|
${JsonServer_HEADERS_MOC}
|
||||||
${JsonServer_RESOURCES_RCC}
|
${JsonServer_RESOURCES_RCC}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_use_modules(jsonserver Widgets Network)
|
qt5_use_modules(jsonserver Widgets Network)
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
target_link_libraries(jsonserver
|
target_link_libraries(jsonserver
|
||||||
hyperion
|
hyperion
|
||||||
hyperion-utils
|
hyperion-utils
|
||||||
jsoncpp
|
jsoncpp
|
||||||
${QT_LIBRARIES})
|
${QT_LIBRARIES})
|
||||||
|
@ -1,165 +1,166 @@
|
|||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/leddevice)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/leddevice)
|
||||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/leddevice)
|
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/leddevice)
|
||||||
|
|
||||||
#add libusb and pthreads (required for the Lighpack usb device)
|
#add libusb and pthreads (required for the Lighpack usb device)
|
||||||
find_package(libusb-1.0 REQUIRED)
|
find_package(libusb-1.0 REQUIRED)
|
||||||
find_package(Threads REQUIRED)
|
find_package(Threads REQUIRED)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
../../include/hidapi
|
../../include/hidapi
|
||||||
${LIBUSB_1_INCLUDE_DIRS}) # for Lightpack device
|
${LIBUSB_1_INCLUDE_DIRS}
|
||||||
|
) # for Lightpack device
|
||||||
# Group the headers that go through the MOC compiler
|
|
||||||
SET(Leddevice_QT_HEADERS
|
# Group the headers that go through the MOC compiler
|
||||||
${CURRENT_SOURCE_DIR}/LedRs232Device.h
|
SET(Leddevice_QT_HEADERS
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAdalight.h
|
${CURRENT_SOURCE_DIR}/LedRs232Device.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAdalightApa102.h
|
${CURRENT_SOURCE_DIR}/LedDeviceAdalight.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAmbiLed.h
|
${CURRENT_SOURCE_DIR}/LedDeviceAdalightApa102.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAtmoOrb.h
|
${CURRENT_SOURCE_DIR}/LedDeviceAmbiLed.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.h
|
${CURRENT_SOURCE_DIR}/LedDeviceAtmoOrb.h
|
||||||
${CURRENT_SOURCE_DIR}/LedHIDDevice.h
|
${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceRawHID.h
|
${CURRENT_SOURCE_DIR}/LedHIDDevice.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceFile.h
|
${CURRENT_SOURCE_DIR}/LedDeviceRawHID.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h
|
${CURRENT_SOURCE_DIR}/LedDeviceFile.h
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h
|
||||||
|
)
|
||||||
SET(Leddevice_HEADERS
|
|
||||||
${CURRENT_HEADER_DIR}/LedDevice.h
|
SET(Leddevice_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/LedDeviceFactory.h
|
${CURRENT_HEADER_DIR}/LedDevice.h
|
||||||
|
${CURRENT_HEADER_DIR}/LedDeviceFactory.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceLightpack.h
|
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.h
|
${CURRENT_SOURCE_DIR}/LedDeviceLightpack.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.h
|
${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.h
|
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceSedu.h
|
${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceFile.h
|
${CURRENT_SOURCE_DIR}/LedDeviceSedu.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h
|
${CURRENT_SOURCE_DIR}/LedDeviceFile.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceUdp.h
|
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.h
|
${CURRENT_SOURCE_DIR}/LedDeviceUdp.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceTpm2.h
|
${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAtmo.h
|
${CURRENT_SOURCE_DIR}/LedDeviceTpm2.h
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceAtmo.h
|
||||||
|
)
|
||||||
SET(Leddevice_SOURCES
|
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceFactory.cpp
|
SET(Leddevice_SOURCES
|
||||||
|
${CURRENT_SOURCE_DIR}/LedDeviceFactory.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedRs232Device.cpp
|
|
||||||
${CURRENT_SOURCE_DIR}/LedHIDDevice.cpp
|
${CURRENT_SOURCE_DIR}/LedRs232Device.cpp
|
||||||
|
${CURRENT_SOURCE_DIR}/LedHIDDevice.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAdalight.cpp
|
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAdalightApa102.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceAdalight.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAmbiLed.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceAdalightApa102.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAtmoOrb.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceAmbiLed.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceRawHID.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceAtmoOrb.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceLightpack.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceRawHID.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceLightpack.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceMultiLightpack.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.cpp
|
${CURRENT_SOURCE_DIR}/LedDevicePaintpack.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceSedu.cpp
|
${CURRENT_SOURCE_DIR}/LedDevicePiBlaster.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceFile.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceSedu.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceFile.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceUdp.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceFadeCandy.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceUdp.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceHyperionUsbasp.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceTpm2.cpp
|
${CURRENT_SOURCE_DIR}/LedDevicePhilipsHue.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAtmo.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceTpm2.cpp
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceAtmo.cpp
|
||||||
|
)
|
||||||
if(ENABLE_SPIDEV)
|
|
||||||
SET(Leddevice_HEADERS
|
if(ENABLE_SPIDEV)
|
||||||
${Leddevice_HEADERS}
|
SET(Leddevice_HEADERS
|
||||||
${CURRENT_SOURCE_DIR}/LedSpiDevice.h
|
${Leddevice_HEADERS}
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.h
|
${CURRENT_SOURCE_DIR}/LedSpiDevice.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.h
|
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceP9813.h
|
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
|
${CURRENT_SOURCE_DIR}/LedDeviceP9813.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.h
|
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.h
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAPA102.h
|
${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.h
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceAPA102.h
|
||||||
SET(Leddevice_SOURCES
|
)
|
||||||
${Leddevice_SOURCES}
|
SET(Leddevice_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/LedSpiDevice.cpp
|
${Leddevice_SOURCES}
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.cpp
|
${CURRENT_SOURCE_DIR}/LedSpiDevice.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceLpd6803.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceP9813.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceLpd8806.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceP9813.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceWs2801.cpp
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceAPA102.cpp
|
${CURRENT_SOURCE_DIR}/LedDeviceWs2812SPI.cpp
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceAPA102.cpp
|
||||||
endif(ENABLE_SPIDEV)
|
)
|
||||||
|
endif()
|
||||||
if(ENABLE_WS2812BPWM)
|
|
||||||
SET(Leddevice_HEADERS
|
if(ENABLE_WS2812BPWM)
|
||||||
${Leddevice_HEADERS}
|
SET(Leddevice_HEADERS
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceWS2812b.h
|
${Leddevice_HEADERS}
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceWS2812b.h
|
||||||
SET(Leddevice_SOURCES
|
)
|
||||||
${Leddevice_SOURCES}
|
SET(Leddevice_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceWS2812b.cpp
|
${Leddevice_SOURCES}
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceWS2812b.cpp
|
||||||
endif(ENABLE_WS2812BPWM)
|
)
|
||||||
|
endif()
|
||||||
if(ENABLE_WS281XPWM)
|
|
||||||
include_directories(../../dependencies/external/rpi_ws281x)
|
if(ENABLE_WS281XPWM)
|
||||||
SET(Leddevice_HEADERS
|
include_directories(../../dependencies/external/rpi_ws281x)
|
||||||
${Leddevice_HEADERS}
|
SET(Leddevice_HEADERS
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceWS281x.h
|
${Leddevice_HEADERS}
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceWS281x.h
|
||||||
SET(Leddevice_SOURCES
|
)
|
||||||
${Leddevice_SOURCES}
|
SET(Leddevice_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceWS281x.cpp
|
${Leddevice_SOURCES}
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceWS281x.cpp
|
||||||
endif(ENABLE_WS281XPWM)
|
)
|
||||||
|
endif()
|
||||||
if(ENABLE_TINKERFORGE)
|
|
||||||
SET(Leddevice_HEADERS
|
if(ENABLE_TINKERFORGE)
|
||||||
${Leddevice_HEADERS}
|
SET(Leddevice_HEADERS
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceTinkerforge.h
|
${Leddevice_HEADERS}
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceTinkerforge.h
|
||||||
SET(Leddevice_SOURCES
|
)
|
||||||
${Leddevice_SOURCES}
|
SET(Leddevice_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/LedDeviceTinkerforge.cpp
|
${Leddevice_SOURCES}
|
||||||
)
|
${CURRENT_SOURCE_DIR}/LedDeviceTinkerforge.cpp
|
||||||
endif(ENABLE_TINKERFORGE)
|
)
|
||||||
|
endif()
|
||||||
if(ENABLE_QT5)
|
|
||||||
QT5_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS})
|
if(ENABLE_QT5)
|
||||||
else(ENABLE_QT5)
|
QT5_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS})
|
||||||
QT4_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS})
|
else()
|
||||||
endif(ENABLE_QT5)
|
QT4_WRAP_CPP(Leddevice_HEADERS_MOC ${Leddevice_QT_HEADERS})
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(leddevice
|
|
||||||
${Leddevice_HEADERS}
|
add_library(leddevice
|
||||||
${Leddevice_QT_HEADERS}
|
${Leddevice_HEADERS}
|
||||||
${Leddevice_HEADERS_MOC}
|
${Leddevice_QT_HEADERS}
|
||||||
${Leddevice_SOURCES}
|
${Leddevice_HEADERS_MOC}
|
||||||
)
|
${Leddevice_SOURCES}
|
||||||
|
)
|
||||||
if(ENABLE_QT5)
|
|
||||||
qt5_use_modules(leddevice Widgets Network)
|
if(ENABLE_QT5)
|
||||||
endif(ENABLE_QT5)
|
qt5_use_modules(leddevice Widgets Network)
|
||||||
|
endif()
|
||||||
target_link_libraries(leddevice
|
|
||||||
hyperion-utils
|
target_link_libraries(leddevice
|
||||||
serialport
|
hyperion-utils
|
||||||
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev
|
serialport
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev
|
||||||
${QT_LIBRARIES}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
)
|
${QT_LIBRARIES}
|
||||||
|
)
|
||||||
if(ENABLE_TINKERFORGE)
|
|
||||||
target_link_libraries(leddevice tinkerforge)
|
if(ENABLE_TINKERFORGE)
|
||||||
endif()
|
target_link_libraries(leddevice tinkerforge)
|
||||||
|
endif()
|
||||||
if(ENABLE_WS281XPWM)
|
|
||||||
target_link_libraries(leddevice ws281x)
|
if(ENABLE_WS281XPWM)
|
||||||
endif()
|
target_link_libraries(leddevice ws281x)
|
||||||
|
endif()
|
||||||
if(APPLE)
|
|
||||||
target_link_libraries(leddevice hidapi-mac)
|
if(APPLE)
|
||||||
else()
|
target_link_libraries(leddevice hidapi-mac)
|
||||||
target_link_libraries(leddevice hidapi-libusb)
|
else()
|
||||||
endif()
|
target_link_libraries(leddevice hidapi-libusb)
|
||||||
|
endif()
|
||||||
|
@ -1,152 +1,158 @@
|
|||||||
// Local-Hyperion includes
|
// Local-Hyperion includes
|
||||||
#include "LedDeviceAtmoOrb.h"
|
#include "LedDeviceAtmoOrb.h"
|
||||||
|
|
||||||
// qt includes
|
// qt includes
|
||||||
#include <QtCore/qmath.h>
|
#include <QtCore/qmath.h>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
#include <QtNetwork>
|
#include <QtNetwork>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
AtmoOrbLight::AtmoOrbLight(unsigned int id) {
|
AtmoOrbLight::AtmoOrbLight(unsigned int id) {
|
||||||
// Not implemented
|
// Not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
LedDeviceAtmoOrb::LedDeviceAtmoOrb(const std::string &output, bool useOrbSmoothing,
|
LedDeviceAtmoOrb::LedDeviceAtmoOrb(
|
||||||
int transitiontime, int skipSmoothingDiff, int port, int numLeds, std::vector<unsigned int> orbIds) :
|
const std::string &output,
|
||||||
multicastGroup(output.c_str()), useOrbSmoothing(useOrbSmoothing), transitiontime(transitiontime), skipSmoothingDiff(skipSmoothingDiff),
|
bool useOrbSmoothing,
|
||||||
multiCastGroupPort(port), numLeds(numLeds), orbIds(orbIds) {
|
int transitiontime,
|
||||||
manager = new QNetworkAccessManager();
|
int skipSmoothingDiff,
|
||||||
groupAddress = QHostAddress(multicastGroup);
|
int port,
|
||||||
|
int numLeds,
|
||||||
udpSocket = new QUdpSocket(this);
|
std::vector<unsigned int> orbIds) :
|
||||||
udpSocket->bind(multiCastGroupPort, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
|
multicastGroup(output.c_str()), useOrbSmoothing(useOrbSmoothing), transitiontime(transitiontime), skipSmoothingDiff(skipSmoothingDiff),
|
||||||
|
multiCastGroupPort(port), numLeds(numLeds), orbIds(orbIds)
|
||||||
joinedMulticastgroup = udpSocket->joinMulticastGroup(groupAddress);
|
{
|
||||||
}
|
manager = new QNetworkAccessManager();
|
||||||
|
groupAddress = QHostAddress(multicastGroup);
|
||||||
int LedDeviceAtmoOrb::write(const std::vector <ColorRgb> &ledValues) {
|
|
||||||
|
udpSocket = new QUdpSocket(this);
|
||||||
// If not in multicast group return
|
udpSocket->bind(multiCastGroupPort, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint);
|
||||||
if (!joinedMulticastgroup) {
|
|
||||||
return 0;
|
joinedMulticastgroup = udpSocket->joinMulticastGroup(groupAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Command options:
|
int LedDeviceAtmoOrb::write(const std::vector <ColorRgb> &ledValues) {
|
||||||
//
|
// If not in multicast group return
|
||||||
// 1 = force off
|
if (!joinedMulticastgroup) {
|
||||||
// 2 = use lamp smoothing and validate by Orb ID
|
return 0;
|
||||||
// 4 = validate by Orb ID
|
}
|
||||||
|
|
||||||
// When setting useOrbSmoothing = true it's recommended to disable Hyperion's own smoothing as it will conflict (double smoothing)
|
// Command options:
|
||||||
int commandType = 4;
|
//
|
||||||
if(useOrbSmoothing)
|
// 1 = force off
|
||||||
{
|
// 2 = use lamp smoothing and validate by Orb ID
|
||||||
commandType = 2;
|
// 4 = validate by Orb ID
|
||||||
}
|
|
||||||
|
// When setting useOrbSmoothing = true it's recommended to disable Hyperion's own smoothing as it will conflict (double smoothing)
|
||||||
// Iterate through colors and set Orb color
|
int commandType = 4;
|
||||||
// Start off with idx 1 as 0 is reserved for controlling all orbs at once
|
if(useOrbSmoothing)
|
||||||
unsigned int idx = 1;
|
{
|
||||||
|
commandType = 2;
|
||||||
for (const ColorRgb &color : ledValues) {
|
}
|
||||||
// Retrieve last send colors
|
|
||||||
int lastRed = lastColorRedMap[idx];
|
// Iterate through colors and set Orb color
|
||||||
int lastGreen = lastColorGreenMap[idx];
|
// Start off with idx 1 as 0 is reserved for controlling all orbs at once
|
||||||
int lastBlue = lastColorBlueMap[idx];
|
unsigned int idx = 1;
|
||||||
|
|
||||||
// If color difference is higher than skipSmoothingDiff than we skip Orb smoothing (if enabled) and send it right away
|
for (const ColorRgb &color : ledValues) {
|
||||||
if ((skipSmoothingDiff != 0 && useOrbSmoothing) && (abs(color.red - lastRed) >= skipSmoothingDiff || abs(color.blue - lastBlue) >= skipSmoothingDiff ||
|
// Retrieve last send colors
|
||||||
abs(color.green - lastGreen) >= skipSmoothingDiff))
|
int lastRed = lastColorRedMap[idx];
|
||||||
{
|
int lastGreen = lastColorGreenMap[idx];
|
||||||
// Skip Orb smoothing when using (command type 4)
|
int lastBlue = lastColorBlueMap[idx];
|
||||||
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
|
||||||
if (orbIds[i] == idx) {
|
// If color difference is higher than skipSmoothingDiff than we skip Orb smoothing (if enabled) and send it right away
|
||||||
setColor(idx, color, 4);
|
if ((skipSmoothingDiff != 0 && useOrbSmoothing) && (abs(color.red - lastRed) >= skipSmoothingDiff || abs(color.blue - lastBlue) >= skipSmoothingDiff ||
|
||||||
}
|
abs(color.green - lastGreen) >= skipSmoothingDiff))
|
||||||
}
|
{
|
||||||
}
|
// Skip Orb smoothing when using (command type 4)
|
||||||
else {
|
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
||||||
// Send color
|
if (orbIds[i] == idx) {
|
||||||
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
setColor(idx, color, 4);
|
||||||
if (orbIds[i] == idx) {
|
}
|
||||||
setColor(idx, color, commandType);
|
}
|
||||||
}
|
}
|
||||||
}
|
else {
|
||||||
}
|
// Send color
|
||||||
|
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
||||||
// Store last colors send for light id
|
if (orbIds[i] == idx) {
|
||||||
lastColorRedMap[idx] = color.red;
|
setColor(idx, color, commandType);
|
||||||
lastColorGreenMap[idx] = color.green;
|
}
|
||||||
lastColorBlueMap[idx] = color.blue;
|
}
|
||||||
|
}
|
||||||
// Next light id.
|
|
||||||
idx++;
|
// Store last colors send for light id
|
||||||
}
|
lastColorRedMap[idx] = color.red;
|
||||||
|
lastColorGreenMap[idx] = color.green;
|
||||||
return 0;
|
lastColorBlueMap[idx] = color.blue;
|
||||||
}
|
|
||||||
|
// Next light id.
|
||||||
void LedDeviceAtmoOrb::setColor(unsigned int orbId, const ColorRgb &color, int commandType) {
|
idx++;
|
||||||
QByteArray bytes;
|
}
|
||||||
bytes.resize(5 + numLeds * 3);
|
|
||||||
bytes.fill('\0');
|
return 0;
|
||||||
|
}
|
||||||
// Command identifier: C0FFEE
|
|
||||||
bytes[0] = 0xC0;
|
void LedDeviceAtmoOrb::setColor(unsigned int orbId, const ColorRgb &color, int commandType) {
|
||||||
bytes[1] = 0xFF;
|
QByteArray bytes;
|
||||||
bytes[2] = 0xEE;
|
bytes.resize(5 + numLeds * 3);
|
||||||
|
bytes.fill('\0');
|
||||||
// Command type
|
|
||||||
bytes[3] = commandType;
|
// Command identifier: C0FFEE
|
||||||
|
bytes[0] = 0xC0;
|
||||||
// Orb ID
|
bytes[1] = 0xFF;
|
||||||
bytes[4] = orbId;
|
bytes[2] = 0xEE;
|
||||||
|
|
||||||
// RED / GREEN / BLUE
|
// Command type
|
||||||
bytes[5] = color.red;
|
bytes[3] = commandType;
|
||||||
bytes[6] = color.green;
|
|
||||||
bytes[7] = color.blue;
|
// Orb ID
|
||||||
|
bytes[4] = orbId;
|
||||||
sendCommand(bytes);
|
|
||||||
}
|
// RED / GREEN / BLUE
|
||||||
|
bytes[5] = color.red;
|
||||||
void LedDeviceAtmoOrb::sendCommand(const QByteArray &bytes) {
|
bytes[6] = color.green;
|
||||||
QByteArray datagram = bytes;
|
bytes[7] = color.blue;
|
||||||
udpSocket->writeDatagram(datagram.data(), datagram.size(),
|
|
||||||
groupAddress, multiCastGroupPort);
|
sendCommand(bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceAtmoOrb::switchOff() {
|
void LedDeviceAtmoOrb::sendCommand(const QByteArray &bytes) {
|
||||||
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
QByteArray datagram = bytes;
|
||||||
QByteArray bytes;
|
udpSocket->writeDatagram(datagram.data(), datagram.size(),
|
||||||
bytes.resize(5 + numLeds * 3);
|
groupAddress, multiCastGroupPort);
|
||||||
bytes.fill('\0');
|
}
|
||||||
|
|
||||||
// Command identifier: C0FFEE
|
int LedDeviceAtmoOrb::switchOff() {
|
||||||
bytes[0] = 0xC0;
|
for (unsigned int i = 0; i < orbIds.size(); i++) {
|
||||||
bytes[1] = 0xFF;
|
QByteArray bytes;
|
||||||
bytes[2] = 0xEE;
|
bytes.resize(5 + numLeds * 3);
|
||||||
|
bytes.fill('\0');
|
||||||
// Command type
|
|
||||||
bytes[3] = 1;
|
// Command identifier: C0FFEE
|
||||||
|
bytes[0] = 0xC0;
|
||||||
// Orb ID
|
bytes[1] = 0xFF;
|
||||||
bytes[4] = orbIds[i];
|
bytes[2] = 0xEE;
|
||||||
|
|
||||||
// RED / GREEN / BLUE
|
// Command type
|
||||||
bytes[5] = 0;
|
bytes[3] = 1;
|
||||||
bytes[6] = 0;
|
|
||||||
bytes[7] = 0;
|
// Orb ID
|
||||||
|
bytes[4] = orbIds[i];
|
||||||
sendCommand(bytes);
|
|
||||||
}
|
// RED / GREEN / BLUE
|
||||||
return 0;
|
bytes[5] = 0;
|
||||||
}
|
bytes[6] = 0;
|
||||||
|
bytes[7] = 0;
|
||||||
LedDeviceAtmoOrb::~LedDeviceAtmoOrb() {
|
|
||||||
delete manager;
|
sendCommand(bytes);
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
LedDeviceAtmoOrb::~LedDeviceAtmoOrb() {
|
||||||
|
delete manager;
|
||||||
|
}
|
||||||
|
@ -1,132 +1,132 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// STL includes
|
// STL includes
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Qt includes
|
// Qt includes
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QHostAddress>
|
#include <QHostAddress>
|
||||||
|
|
||||||
// Leddevice includes
|
// Leddevice includes
|
||||||
#include <leddevice/LedDevice.h>
|
#include <leddevice/LedDevice.h>
|
||||||
|
|
||||||
class QUdpSocket;
|
class QUdpSocket;
|
||||||
|
|
||||||
class AtmoOrbLight {
|
class AtmoOrbLight {
|
||||||
public:
|
public:
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs the light.
|
/// Constructs the light.
|
||||||
///
|
///
|
||||||
/// @param id the orb id
|
/// @param id the orb id
|
||||||
AtmoOrbLight(unsigned int id);
|
AtmoOrbLight(unsigned int id);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation for the AtmoOrb
|
* Implementation for the AtmoOrb
|
||||||
*
|
*
|
||||||
* To use set the device to "atmoorb".
|
* To use set the device to "atmoorb".
|
||||||
*
|
*
|
||||||
* @author RickDB (github)
|
* @author RickDB (github)
|
||||||
*/
|
*/
|
||||||
class LedDeviceAtmoOrb : public QObject, public LedDevice {
|
class LedDeviceAtmoOrb : public QObject, public LedDevice {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
// Last send color map
|
// Last send color map
|
||||||
QMap<int, int> lastColorRedMap;
|
QMap<int, int> lastColorRedMap;
|
||||||
QMap<int, int> lastColorGreenMap;
|
QMap<int, int> lastColorGreenMap;
|
||||||
QMap<int, int> lastColorBlueMap;
|
QMap<int, int> lastColorBlueMap;
|
||||||
|
|
||||||
// Multicast status
|
// Multicast status
|
||||||
bool joinedMulticastgroup;
|
bool joinedMulticastgroup;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs the device.
|
/// Constructs the device.
|
||||||
///
|
///
|
||||||
/// @param output is the multicast address of Orbs
|
/// @param output is the multicast address of Orbs
|
||||||
///
|
///
|
||||||
/// @param transitiontime is optional and not used at the moment
|
/// @param transitiontime is optional and not used at the moment
|
||||||
///
|
///
|
||||||
/// @param useOrbSmoothing use Orbs own (external) smoothing algorithm (default: false)
|
/// @param useOrbSmoothing use Orbs own (external) smoothing algorithm (default: false)
|
||||||
///
|
///
|
||||||
/// @param skipSmoothingDiff minimal color (0-255) difference to override smoothing so that if current and previously received colors are higher than set dif we override smoothing
|
/// @param skipSmoothingDiff minimal color (0-255) difference to override smoothing so that if current and previously received colors are higher than set dif we override smoothing
|
||||||
///
|
///
|
||||||
/// @param port is the multicast port.
|
/// @param port is the multicast port.
|
||||||
///
|
///
|
||||||
/// @param numLeds is the total amount of leds per Orb
|
/// @param numLeds is the total amount of leds per Orb
|
||||||
///
|
///
|
||||||
/// @param array containing orb ids
|
/// @param array containing orb ids
|
||||||
///
|
///
|
||||||
LedDeviceAtmoOrb(const std::string &output, bool useOrbSmoothing =
|
LedDeviceAtmoOrb(const std::string &output, bool useOrbSmoothing =
|
||||||
false, int transitiontime = 0, int skipSmoothingDiff = 0, int port = 49692, int numLeds = 24,
|
false, int transitiontime = 0, int skipSmoothingDiff = 0, int port = 49692, int numLeds = 24,
|
||||||
std::vector<unsigned int> orbIds = std::vector < unsigned int>());
|
std::vector<unsigned int> orbIds = std::vector < unsigned int>());
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Destructor of this device
|
/// Destructor of this device
|
||||||
///
|
///
|
||||||
virtual ~LedDeviceAtmoOrb();
|
virtual ~LedDeviceAtmoOrb();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sends the given led-color values to the Orbs
|
/// Sends the given led-color values to the Orbs
|
||||||
///
|
///
|
||||||
/// @param ledValues The color-value per led
|
/// @param ledValues The color-value per led
|
||||||
///
|
///
|
||||||
/// @return Zero on success else negative
|
/// @return Zero on success else negative
|
||||||
///
|
///
|
||||||
virtual int write(const std::vector <ColorRgb> &ledValues);
|
virtual int write(const std::vector <ColorRgb> &ledValues);
|
||||||
|
|
||||||
virtual int switchOff();
|
virtual int switchOff();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// QNetworkAccessManager object for sending requests.
|
/// QNetworkAccessManager object for sending requests.
|
||||||
QNetworkAccessManager *manager;
|
QNetworkAccessManager *manager;
|
||||||
|
|
||||||
/// String containing multicast group IP address
|
/// String containing multicast group IP address
|
||||||
QString multicastGroup;
|
QString multicastGroup;
|
||||||
|
|
||||||
/// use Orbs own (external) smoothing algorithm
|
/// use Orbs own (external) smoothing algorithm
|
||||||
bool useOrbSmoothing;
|
bool useOrbSmoothing;
|
||||||
|
|
||||||
/// Transition time between colors (not implemented)
|
/// Transition time between colors (not implemented)
|
||||||
int transitiontime;
|
int transitiontime;
|
||||||
|
|
||||||
// Maximum allowed color difference, will skip Orb (external) smoothing once reached
|
// Maximum allowed color difference, will skip Orb (external) smoothing once reached
|
||||||
int skipSmoothingDiff;
|
int skipSmoothingDiff;
|
||||||
|
|
||||||
/// Multicast port to send data to
|
/// Multicast port to send data to
|
||||||
int multiCastGroupPort;
|
int multiCastGroupPort;
|
||||||
|
|
||||||
/// Number of leds in Orb, used to determine buffer size
|
/// Number of leds in Orb, used to determine buffer size
|
||||||
int numLeds;
|
int numLeds;
|
||||||
|
|
||||||
/// QHostAddress object of multicast group IP address
|
/// QHostAddress object of multicast group IP address
|
||||||
QHostAddress groupAddress;
|
QHostAddress groupAddress;
|
||||||
|
|
||||||
/// QUdpSocket object used to send data over
|
/// QUdpSocket object used to send data over
|
||||||
QUdpSocket *udpSocket;
|
QUdpSocket *udpSocket;
|
||||||
|
|
||||||
/// Array of the orb ids.
|
/// Array of the orb ids.
|
||||||
std::vector<unsigned int> orbIds;
|
std::vector<unsigned int> orbIds;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Set Orbcolor
|
/// Set Orbcolor
|
||||||
///
|
///
|
||||||
/// @param orbId the orb id
|
/// @param orbId the orb id
|
||||||
///
|
///
|
||||||
/// @param color which color to set
|
/// @param color which color to set
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// @param commandType which type of command to send (off / smoothing / etc..)
|
/// @param commandType which type of command to send (off / smoothing / etc..)
|
||||||
///
|
///
|
||||||
void setColor(unsigned int orbId, const ColorRgb &color, int commandType);
|
void setColor(unsigned int orbId, const ColorRgb &color, int commandType);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Send Orb command
|
/// Send Orb command
|
||||||
///
|
///
|
||||||
/// @param bytes the byte array containing command to send over multicast
|
/// @param bytes the byte array containing command to send over multicast
|
||||||
///
|
///
|
||||||
void sendCommand(const QByteArray &bytes);
|
void sendCommand(const QByteArray &bytes);
|
||||||
};
|
};
|
@ -1,50 +1,50 @@
|
|||||||
// STL includes
|
// STL includes
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// Linux includes
|
// Linux includes
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
// hyperion local includes
|
// hyperion local includes
|
||||||
#include "LedDeviceLpd6803.h"
|
#include "LedDeviceLpd6803.h"
|
||||||
|
|
||||||
LedDeviceLpd6803::LedDeviceLpd6803(const std::string& outputDevice, const unsigned baudrate) :
|
LedDeviceLpd6803::LedDeviceLpd6803(const std::string& outputDevice, const unsigned baudrate) :
|
||||||
LedSpiDevice(outputDevice, baudrate),
|
LedSpiDevice(outputDevice, baudrate),
|
||||||
_ledBuffer(0)
|
_ledBuffer(0)
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceLpd6803::write(const std::vector<ColorRgb> &ledValues)
|
int LedDeviceLpd6803::write(const std::vector<ColorRgb> &ledValues)
|
||||||
{
|
{
|
||||||
unsigned messageLength = 4 + 2*ledValues.size() + ledValues.size()/8 + 1;
|
unsigned messageLength = 4 + 2*ledValues.size() + ledValues.size()/8 + 1;
|
||||||
// Reconfigure if the current connfiguration does not match the required configuration
|
// Reconfigure if the current connfiguration does not match the required configuration
|
||||||
if (messageLength != _ledBuffer.size())
|
if (messageLength != _ledBuffer.size())
|
||||||
{
|
{
|
||||||
// Initialise the buffer
|
// Initialise the buffer
|
||||||
_ledBuffer.resize(messageLength, 0x00);
|
_ledBuffer.resize(messageLength, 0x00);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the colors from the ColorRgb vector to the Ldp6803 data vector
|
// Copy the colors from the ColorRgb vector to the Ldp6803 data vector
|
||||||
for (unsigned iLed=0; iLed<ledValues.size(); ++iLed)
|
for (unsigned iLed=0; iLed<ledValues.size(); ++iLed)
|
||||||
{
|
{
|
||||||
const ColorRgb& rgb = ledValues[iLed];
|
const ColorRgb& rgb = ledValues[iLed];
|
||||||
|
|
||||||
_ledBuffer[4 + 2 * iLed] = 0x80 | ((rgb.red & 0xf8) >> 1) | (rgb.green >> 6);
|
_ledBuffer[4 + 2 * iLed] = 0x80 | ((rgb.red & 0xf8) >> 1) | (rgb.green >> 6);
|
||||||
_ledBuffer[5 + 2 * iLed] = ((rgb.green & 0x38) << 2) | (rgb.blue >> 3);
|
_ledBuffer[5 + 2 * iLed] = ((rgb.green & 0x38) << 2) | (rgb.blue >> 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the data
|
// Write the data
|
||||||
if (writeBytes(_ledBuffer.size(), _ledBuffer.data()) < 0)
|
if (writeBytes(_ledBuffer.size(), _ledBuffer.data()) < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceLpd6803::switchOff()
|
int LedDeviceLpd6803::switchOff()
|
||||||
{
|
{
|
||||||
return write(std::vector<ColorRgb>(_ledBuffer.size(), ColorRgb{0,0,0}));
|
return write(std::vector<ColorRgb>(_ledBuffer.size(), ColorRgb{0,0,0}));
|
||||||
}
|
}
|
||||||
|
@ -1,42 +1,42 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Local hyperion incluse
|
// Local hyperion incluse
|
||||||
#include "LedSpiDevice.h"
|
#include "LedSpiDevice.h"
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Implementation of the LedDevice interface for writing to LDP6803 led device.
|
/// Implementation of the LedDevice interface for writing to LDP6803 led device.
|
||||||
///
|
///
|
||||||
/// 00000000 00000000 00000000 00000000 1RRRRRGG GGGBBBBB 1RRRRRGG GGGBBBBB ...
|
/// 00000000 00000000 00000000 00000000 1RRRRRGG GGGBBBBB 1RRRRRGG GGGBBBBB ...
|
||||||
/// |---------------------------------| |---------------| |---------------|
|
/// |---------------------------------| |---------------| |---------------|
|
||||||
/// 32 zeros to start the frame Led1 Led2 ...
|
/// 32 zeros to start the frame Led1 Led2 ...
|
||||||
///
|
///
|
||||||
/// For each led, the first bit is always 1, and then you have 5 bits each for red, green and blue
|
/// For each led, the first bit is always 1, and then you have 5 bits each for red, green and blue
|
||||||
/// (R, G and B in the above illustration) making 16 bits per led. Total bytes = 4 + (2 x number of
|
/// (R, G and B in the above illustration) making 16 bits per led. Total bytes = 4 + (2 x number of
|
||||||
/// leds)
|
/// leds)
|
||||||
///
|
///
|
||||||
class LedDeviceLpd6803 : public LedSpiDevice
|
class LedDeviceLpd6803 : public LedSpiDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
/// Constructs the LedDevice for a string containing leds of the type LDP6803
|
/// Constructs the LedDevice for a string containing leds of the type LDP6803
|
||||||
///
|
///
|
||||||
/// @param[in] outputDevice The name of the output device (eg '/dev/spidev0.0')
|
/// @param[in] outputDevice The name of the output device (eg '/dev/spidev0.0')
|
||||||
/// @param[in] baudrate The used baudrate for writing to the output device
|
/// @param[in] baudrate The used baudrate for writing to the output device
|
||||||
///
|
///
|
||||||
LedDeviceLpd6803(const std::string& outputDevice, const unsigned baudrate);
|
LedDeviceLpd6803(const std::string& outputDevice, const unsigned baudrate);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes the led color values to the led-device
|
/// Writes the led color values to the led-device
|
||||||
///
|
///
|
||||||
/// @param ledValues The color-value per led
|
/// @param ledValues The color-value per led
|
||||||
/// @return Zero on succes else negative
|
/// @return Zero on succes else negative
|
||||||
///
|
///
|
||||||
virtual int write(const std::vector<ColorRgb> &ledValues);
|
virtual int write(const std::vector<ColorRgb> &ledValues);
|
||||||
|
|
||||||
/// Switch the leds off
|
/// Switch the leds off
|
||||||
virtual int switchOff();
|
virtual int switchOff();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The buffer containing the packed RGB values
|
/// The buffer containing the packed RGB values
|
||||||
std::vector<uint8_t> _ledBuffer;
|
std::vector<uint8_t> _ledBuffer;
|
||||||
};
|
};
|
||||||
|
@ -1,54 +1,54 @@
|
|||||||
// STL includes
|
// STL includes
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
// Linux includes
|
// Linux includes
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
|
||||||
// hyperion local includes
|
// hyperion local includes
|
||||||
#include "LedDeviceLpd8806.h"
|
#include "LedDeviceLpd8806.h"
|
||||||
|
|
||||||
LedDeviceLpd8806::LedDeviceLpd8806(const std::string& outputDevice, const unsigned baudrate) :
|
LedDeviceLpd8806::LedDeviceLpd8806(const std::string& outputDevice, const unsigned baudrate) :
|
||||||
LedSpiDevice(outputDevice, baudrate),
|
LedSpiDevice(outputDevice, baudrate),
|
||||||
_ledBuffer(0)
|
_ledBuffer(0)
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceLpd8806::write(const std::vector<ColorRgb> &ledValues)
|
int LedDeviceLpd8806::write(const std::vector<ColorRgb> &ledValues)
|
||||||
{
|
{
|
||||||
const unsigned clearSize = ledValues.size()/32+1;
|
const unsigned clearSize = ledValues.size()/32+1;
|
||||||
// Reconfigure if the current connfiguration does not match the required configuration
|
// Reconfigure if the current connfiguration does not match the required configuration
|
||||||
if (3*ledValues.size() + clearSize != _ledBuffer.size())
|
if (3*ledValues.size() + clearSize != _ledBuffer.size())
|
||||||
{
|
{
|
||||||
// Initialise the buffer
|
// Initialise the buffer
|
||||||
_ledBuffer.resize(3*ledValues.size() + clearSize, 0x00);
|
_ledBuffer.resize(3*ledValues.size() + clearSize, 0x00);
|
||||||
|
|
||||||
// Perform an initial reset to start accepting data on the first led
|
// Perform an initial reset to start accepting data on the first led
|
||||||
writeBytes(clearSize, _ledBuffer.data());
|
writeBytes(clearSize, _ledBuffer.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy the colors from the ColorRgb vector to the Ldp8806 data vector
|
// Copy the colors from the ColorRgb vector to the Ldp8806 data vector
|
||||||
for (unsigned iLed=0; iLed<ledValues.size(); ++iLed)
|
for (unsigned iLed=0; iLed<ledValues.size(); ++iLed)
|
||||||
{
|
{
|
||||||
const ColorRgb& rgb = ledValues[iLed];
|
const ColorRgb& rgb = ledValues[iLed];
|
||||||
|
|
||||||
_ledBuffer[iLed*3] = 0x80 | (rgb.red >> 1);
|
_ledBuffer[iLed*3] = 0x80 | (rgb.red >> 1);
|
||||||
_ledBuffer[iLed*3+1] = 0x80 | (rgb.green >> 1);
|
_ledBuffer[iLed*3+1] = 0x80 | (rgb.green >> 1);
|
||||||
_ledBuffer[iLed*3+2] = 0x80 | (rgb.blue >> 1);
|
_ledBuffer[iLed*3+2] = 0x80 | (rgb.blue >> 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write the data
|
// Write the data
|
||||||
if (writeBytes(_ledBuffer.size(), _ledBuffer.data()) < 0)
|
if (writeBytes(_ledBuffer.size(), _ledBuffer.data()) < 0)
|
||||||
{
|
{
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDeviceLpd8806::switchOff()
|
int LedDeviceLpd8806::switchOff()
|
||||||
{
|
{
|
||||||
return write(std::vector<ColorRgb>(_ledBuffer.size(), ColorRgb{0,0,0}));
|
return write(std::vector<ColorRgb>(_ledBuffer.size(), ColorRgb{0,0,0}));
|
||||||
}
|
}
|
||||||
|
@ -1,103 +1,103 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// Local hyperion incluse
|
// Local hyperion incluse
|
||||||
#include "LedSpiDevice.h"
|
#include "LedSpiDevice.h"
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Implementation of the LedDevice interface for writing to LPD8806 led device.
|
/// Implementation of the LedDevice interface for writing to LPD8806 led device.
|
||||||
///
|
///
|
||||||
/// The following description is copied from 'adafruit' (github.com/adafruit/LPD8806)
|
/// The following description is copied from 'adafruit' (github.com/adafruit/LPD8806)
|
||||||
///
|
///
|
||||||
/// Clearing up some misconceptions about how the LPD8806 drivers work:
|
/// Clearing up some misconceptions about how the LPD8806 drivers work:
|
||||||
///
|
///
|
||||||
/// The LPD8806 is not a FIFO shift register. The first data out controls the
|
/// The LPD8806 is not a FIFO shift register. The first data out controls the
|
||||||
/// LED *closest* to the processor (unlike a typical shift register, where the
|
/// LED *closest* to the processor (unlike a typical shift register, where the
|
||||||
/// first data out winds up at the *furthest* LED). Each LED driver 'fills up'
|
/// first data out winds up at the *furthest* LED). Each LED driver 'fills up'
|
||||||
/// with data and then passes through all subsequent bytes until a latch
|
/// with data and then passes through all subsequent bytes until a latch
|
||||||
/// condition takes place. This is actually pretty common among LED drivers.
|
/// condition takes place. This is actually pretty common among LED drivers.
|
||||||
///
|
///
|
||||||
/// All color data bytes have the high bit (128) set, with the remaining
|
/// All color data bytes have the high bit (128) set, with the remaining
|
||||||
/// seven bits containing a brightness value (0-127). A byte with the high
|
/// seven bits containing a brightness value (0-127). A byte with the high
|
||||||
/// bit clear has special meaning (explained later).
|
/// bit clear has special meaning (explained later).
|
||||||
///
|
///
|
||||||
/// The rest gets bizarre...
|
/// The rest gets bizarre...
|
||||||
///
|
///
|
||||||
/// The LPD8806 does not perform an in-unison latch (which would display the
|
/// The LPD8806 does not perform an in-unison latch (which would display the
|
||||||
/// newly-transmitted data all at once). Rather, each individual byte (even
|
/// newly-transmitted data all at once). Rather, each individual byte (even
|
||||||
/// the separate G, R, B components of each LED) is latched AS IT ARRIVES...
|
/// the separate G, R, B components of each LED) is latched AS IT ARRIVES...
|
||||||
/// or more accurately, as the first bit of the subsequent byte arrives and
|
/// or more accurately, as the first bit of the subsequent byte arrives and
|
||||||
/// is passed through. So the strip actually refreshes at the speed the data
|
/// is passed through. So the strip actually refreshes at the speed the data
|
||||||
/// is issued, not instantaneously (this can be observed by greatly reducing
|
/// is issued, not instantaneously (this can be observed by greatly reducing
|
||||||
/// the data rate). This has implications for POV displays and light painting
|
/// the data rate). This has implications for POV displays and light painting
|
||||||
/// applications. The 'subsequent' rule also means that at least one extra
|
/// applications. The 'subsequent' rule also means that at least one extra
|
||||||
/// byte must follow the last pixel, in order for the final blue LED to latch.
|
/// byte must follow the last pixel, in order for the final blue LED to latch.
|
||||||
///
|
///
|
||||||
/// To reset the pass-through behavior and begin sending new data to the start
|
/// To reset the pass-through behavior and begin sending new data to the start
|
||||||
/// of the strip, a number of zero bytes must be issued (remember, all color
|
/// of the strip, a number of zero bytes must be issued (remember, all color
|
||||||
/// data bytes have the high bit set, thus are in the range 128 to 255, so the
|
/// data bytes have the high bit set, thus are in the range 128 to 255, so the
|
||||||
/// zero is 'special'). This should be done before each full payload of color
|
/// zero is 'special'). This should be done before each full payload of color
|
||||||
/// values to the strip. Curiously, zero bytes can only travel one meter (32
|
/// values to the strip. Curiously, zero bytes can only travel one meter (32
|
||||||
/// LEDs) down the line before needing backup; the next meter requires an
|
/// LEDs) down the line before needing backup; the next meter requires an
|
||||||
/// extra zero byte, and so forth. Longer strips will require progressively
|
/// extra zero byte, and so forth. Longer strips will require progressively
|
||||||
/// more zeros. *(see note below)
|
/// more zeros. *(see note below)
|
||||||
///
|
///
|
||||||
/// In the interest of efficiency, it's possible to combine the former EOD
|
/// In the interest of efficiency, it's possible to combine the former EOD
|
||||||
/// extra latch byte and the latter zero reset...the same data can do double
|
/// extra latch byte and the latter zero reset...the same data can do double
|
||||||
/// duty, latching the last blue LED while also resetting the strip for the
|
/// duty, latching the last blue LED while also resetting the strip for the
|
||||||
/// next payload.
|
/// next payload.
|
||||||
///
|
///
|
||||||
/// So: reset byte(s) of suitable length are issued once at startup to 'prime'
|
/// So: reset byte(s) of suitable length are issued once at startup to 'prime'
|
||||||
/// the strip to a known ready state. After each subsequent LED color payload,
|
/// the strip to a known ready state. After each subsequent LED color payload,
|
||||||
/// these reset byte(s) are then issued at the END of each payload, both to
|
/// these reset byte(s) are then issued at the END of each payload, both to
|
||||||
/// latch the last LED and to prep the strip for the start of the next payload
|
/// latch the last LED and to prep the strip for the start of the next payload
|
||||||
/// (even if that data does not arrive immediately). This avoids a tiny bit
|
/// (even if that data does not arrive immediately). This avoids a tiny bit
|
||||||
/// of latency as the new color payload can begin issuing immediately on some
|
/// of latency as the new color payload can begin issuing immediately on some
|
||||||
/// signal, such as a timer or GPIO trigger.
|
/// signal, such as a timer or GPIO trigger.
|
||||||
///
|
///
|
||||||
/// Technically these zero byte(s) are not a latch, as the color data (save
|
/// Technically these zero byte(s) are not a latch, as the color data (save
|
||||||
/// for the last byte) is already latched. It's a start-of-data marker, or
|
/// for the last byte) is already latched. It's a start-of-data marker, or
|
||||||
/// an indicator to clear the thing-that's-not-a-shift-register. But for
|
/// an indicator to clear the thing-that's-not-a-shift-register. But for
|
||||||
/// conversational consistency with other LED drivers, we'll refer to it as
|
/// conversational consistency with other LED drivers, we'll refer to it as
|
||||||
/// a 'latch' anyway.
|
/// a 'latch' anyway.
|
||||||
///
|
///
|
||||||
/// This has been validated independently with multiple customers'
|
/// This has been validated independently with multiple customers'
|
||||||
/// hardware. Please do not report as a bug or issue pull requests for
|
/// hardware. Please do not report as a bug or issue pull requests for
|
||||||
/// this. Fewer zeros sometimes gives the *illusion* of working, the first
|
/// this. Fewer zeros sometimes gives the *illusion* of working, the first
|
||||||
/// payload will correctly load and latch, but subsequent frames will drop
|
/// payload will correctly load and latch, but subsequent frames will drop
|
||||||
/// data at the end. The data shortfall won't always be visually apparent
|
/// data at the end. The data shortfall won't always be visually apparent
|
||||||
/// depending on the color data loaded on the prior and subsequent frames.
|
/// depending on the color data loaded on the prior and subsequent frames.
|
||||||
/// Tested. Confirmed. Fact.
|
/// Tested. Confirmed. Fact.
|
||||||
///
|
///
|
||||||
///
|
///
|
||||||
/// The summary of the story is that the following needs to be writen on the spi-device:
|
/// The summary of the story is that the following needs to be writen on the spi-device:
|
||||||
/// 1RRRRRRR 1GGGGGGG 1BBBBBBB 1RRRRRRR 1GGGGGGG ... ... 1GGGGGGG 1BBBBBBB 00000000 00000000 ...
|
/// 1RRRRRRR 1GGGGGGG 1BBBBBBB 1RRRRRRR 1GGGGGGG ... ... 1GGGGGGG 1BBBBBBB 00000000 00000000 ...
|
||||||
/// |---------led_1----------| |---------led_2-- -led_n----------| |----clear data--
|
/// |---------led_1----------| |---------led_2-- -led_n----------| |----clear data--
|
||||||
///
|
///
|
||||||
/// The number of zeroes in the 'clear data' is (#led/32 + 1)bytes (or *8 for bits)
|
/// The number of zeroes in the 'clear data' is (#led/32 + 1)bytes (or *8 for bits)
|
||||||
///
|
///
|
||||||
class LedDeviceLpd8806 : public LedSpiDevice
|
class LedDeviceLpd8806 : public LedSpiDevice
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
/// Constructs the LedDevice for a string containing leds of the type LPD8806
|
/// Constructs the LedDevice for a string containing leds of the type LPD8806
|
||||||
///
|
///
|
||||||
/// @param[in] outputDevice The name of the output device (eg '/dev/spidev0.0')
|
/// @param[in] outputDevice The name of the output device (eg '/dev/spidev0.0')
|
||||||
/// @param[in] baudrate The used baudrate for writing to the output device
|
/// @param[in] baudrate The used baudrate for writing to the output device
|
||||||
///
|
///
|
||||||
LedDeviceLpd8806(const std::string& outputDevice, const unsigned baudrate);
|
LedDeviceLpd8806(const std::string& outputDevice, const unsigned baudrate);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Writes the led color values to the led-device
|
/// Writes the led color values to the led-device
|
||||||
///
|
///
|
||||||
/// @param ledValues The color-value per led
|
/// @param ledValues The color-value per led
|
||||||
/// @return Zero on succes else negative
|
/// @return Zero on succes else negative
|
||||||
///
|
///
|
||||||
virtual int write(const std::vector<ColorRgb> &ledValues);
|
virtual int write(const std::vector<ColorRgb> &ledValues);
|
||||||
|
|
||||||
/// Switch the leds off
|
/// Switch the leds off
|
||||||
virtual int switchOff();
|
virtual int switchOff();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The buffer containing the packed RGB values
|
/// The buffer containing the packed RGB values
|
||||||
std::vector<uint8_t> _ledBuffer;
|
std::vector<uint8_t> _ledBuffer;
|
||||||
};
|
};
|
||||||
|
@ -1,342 +1,342 @@
|
|||||||
// Local-Hyperion includes
|
// Local-Hyperion includes
|
||||||
#include "LedDevicePhilipsHue.h"
|
#include "LedDevicePhilipsHue.h"
|
||||||
|
|
||||||
// jsoncpp includes
|
// jsoncpp includes
|
||||||
#include <json/json.h>
|
#include <json/json.h>
|
||||||
|
|
||||||
// qt includes
|
// qt includes
|
||||||
#include <QtCore/qmath.h>
|
#include <QtCore/qmath.h>
|
||||||
#include <QEventLoop>
|
#include <QEventLoop>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
|
||||||
bool operator ==(CiColor p1, CiColor p2) {
|
bool operator ==(CiColor p1, CiColor p2) {
|
||||||
return (p1.x == p2.x) && (p1.y == p2.y) && (p1.bri == p2.bri);
|
return (p1.x == p2.x) && (p1.y == p2.y) && (p1.bri == p2.bri);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool operator !=(CiColor p1, CiColor p2) {
|
bool operator !=(CiColor p1, CiColor p2) {
|
||||||
return !(p1 == p2);
|
return !(p1 == p2);
|
||||||
}
|
}
|
||||||
|
|
||||||
PhilipsHueLight::PhilipsHueLight(unsigned int id, QString originalState, QString modelId) :
|
PhilipsHueLight::PhilipsHueLight(unsigned int id, QString originalState, QString modelId) :
|
||||||
id(id), originalState(originalState) {
|
id(id), originalState(originalState) {
|
||||||
// Hue system model ids (http://www.developers.meethue.com/documentation/supported-lights).
|
// Hue system model ids (http://www.developers.meethue.com/documentation/supported-lights).
|
||||||
// Light strips, color iris, ...
|
// Light strips, color iris, ...
|
||||||
const std::set<QString> GAMUT_A_MODEL_IDS = { "LLC001", "LLC005", "LLC006", "LLC007", "LLC010", "LLC011", "LLC012",
|
const std::set<QString> GAMUT_A_MODEL_IDS = { "LLC001", "LLC005", "LLC006", "LLC007", "LLC010", "LLC011", "LLC012",
|
||||||
"LLC013", "LLC014", "LST001" };
|
"LLC013", "LLC014", "LST001" };
|
||||||
// Hue bulbs, spots, ...
|
// Hue bulbs, spots, ...
|
||||||
const std::set<QString> GAMUT_B_MODEL_IDS = { "LCT001", "LCT002", "LCT003", "LCT007", "LLM001" };
|
const std::set<QString> GAMUT_B_MODEL_IDS = { "LCT001", "LCT002", "LCT003", "LCT007", "LLM001" };
|
||||||
// Hue Lightstrip plus, go ...
|
// Hue Lightstrip plus, go ...
|
||||||
const std::set<QString> GAMUT_C_MODEL_IDS = { "LLC020", "LST002" };
|
const std::set<QString> GAMUT_C_MODEL_IDS = { "LLC020", "LST002" };
|
||||||
// Find id in the sets and set the appropiate color space.
|
// Find id in the sets and set the appropiate color space.
|
||||||
if (GAMUT_A_MODEL_IDS.find(modelId) != GAMUT_A_MODEL_IDS.end()) {
|
if (GAMUT_A_MODEL_IDS.find(modelId) != GAMUT_A_MODEL_IDS.end()) {
|
||||||
colorSpace.red = {0.703f, 0.296f};
|
colorSpace.red = {0.703f, 0.296f};
|
||||||
colorSpace.green = {0.2151f, 0.7106f};
|
colorSpace.green = {0.2151f, 0.7106f};
|
||||||
colorSpace.blue = {0.138f, 0.08f};
|
colorSpace.blue = {0.138f, 0.08f};
|
||||||
} else if (GAMUT_B_MODEL_IDS.find(modelId) != GAMUT_B_MODEL_IDS.end()) {
|
} else if (GAMUT_B_MODEL_IDS.find(modelId) != GAMUT_B_MODEL_IDS.end()) {
|
||||||
colorSpace.red = {0.675f, 0.322f};
|
colorSpace.red = {0.675f, 0.322f};
|
||||||
colorSpace.green = {0.4091f, 0.518f};
|
colorSpace.green = {0.4091f, 0.518f};
|
||||||
colorSpace.blue = {0.167f, 0.04f};
|
colorSpace.blue = {0.167f, 0.04f};
|
||||||
} else if (GAMUT_C_MODEL_IDS.find(modelId) != GAMUT_B_MODEL_IDS.end()) {
|
} else if (GAMUT_C_MODEL_IDS.find(modelId) != GAMUT_B_MODEL_IDS.end()) {
|
||||||
colorSpace.red = {0.675f, 0.322f};
|
colorSpace.red = {0.675f, 0.322f};
|
||||||
colorSpace.green = {0.2151f, 0.7106f};
|
colorSpace.green = {0.2151f, 0.7106f};
|
||||||
colorSpace.blue = {0.167f, 0.04f};
|
colorSpace.blue = {0.167f, 0.04f};
|
||||||
} else {
|
} else {
|
||||||
colorSpace.red = {1.0f, 0.0f};
|
colorSpace.red = {1.0f, 0.0f};
|
||||||
colorSpace.green = {0.0f, 1.0f};
|
colorSpace.green = {0.0f, 1.0f};
|
||||||
colorSpace.blue = {0.0f, 0.0f};
|
colorSpace.blue = {0.0f, 0.0f};
|
||||||
}
|
}
|
||||||
// Initialize black color.
|
// Initialize black color.
|
||||||
black = rgbToCiColor(0.0f, 0.0f, 0.0f);
|
black = rgbToCiColor(0.0f, 0.0f, 0.0f);
|
||||||
// Initialize color with black
|
// Initialize color with black
|
||||||
color = {black.x, black.y, black.bri};
|
color = {black.x, black.y, black.bri};
|
||||||
}
|
}
|
||||||
|
|
||||||
float PhilipsHueLight::crossProduct(CiColor p1, CiColor p2) {
|
float PhilipsHueLight::crossProduct(CiColor p1, CiColor p2) {
|
||||||
return p1.x * p2.y - p1.y * p2.x;
|
return p1.x * p2.y - p1.y * p2.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PhilipsHueLight::isPointInLampsReach(CiColor p) {
|
bool PhilipsHueLight::isPointInLampsReach(CiColor p) {
|
||||||
CiColor v1 = { colorSpace.green.x - colorSpace.red.x, colorSpace.green.y - colorSpace.red.y };
|
CiColor v1 = { colorSpace.green.x - colorSpace.red.x, colorSpace.green.y - colorSpace.red.y };
|
||||||
CiColor v2 = { colorSpace.blue.x - colorSpace.red.x, colorSpace.blue.y - colorSpace.red.y };
|
CiColor v2 = { colorSpace.blue.x - colorSpace.red.x, colorSpace.blue.y - colorSpace.red.y };
|
||||||
CiColor q = { p.x - colorSpace.red.x, p.y - colorSpace.red.y };
|
CiColor q = { p.x - colorSpace.red.x, p.y - colorSpace.red.y };
|
||||||
float s = crossProduct(q, v2) / crossProduct(v1, v2);
|
float s = crossProduct(q, v2) / crossProduct(v1, v2);
|
||||||
float t = crossProduct(v1, q) / crossProduct(v1, v2);
|
float t = crossProduct(v1, q) / crossProduct(v1, v2);
|
||||||
if ((s >= 0.0f) && (t >= 0.0f) && (s + t <= 1.0f)) {
|
if ((s >= 0.0f) && (t >= 0.0f) && (s + t <= 1.0f)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CiColor PhilipsHueLight::getClosestPointToPoint(CiColor a, CiColor b, CiColor p) {
|
CiColor PhilipsHueLight::getClosestPointToPoint(CiColor a, CiColor b, CiColor p) {
|
||||||
CiColor AP = { p.x - a.x, p.y - a.y };
|
CiColor AP = { p.x - a.x, p.y - a.y };
|
||||||
CiColor AB = { b.x - a.x, b.y - a.y };
|
CiColor AB = { b.x - a.x, b.y - a.y };
|
||||||
float ab2 = AB.x * AB.x + AB.y * AB.y;
|
float ab2 = AB.x * AB.x + AB.y * AB.y;
|
||||||
float ap_ab = AP.x * AB.x + AP.y * AB.y;
|
float ap_ab = AP.x * AB.x + AP.y * AB.y;
|
||||||
float t = ap_ab / ab2;
|
float t = ap_ab / ab2;
|
||||||
if (t < 0.0f) {
|
if (t < 0.0f) {
|
||||||
t = 0.0f;
|
t = 0.0f;
|
||||||
} else if (t > 1.0f) {
|
} else if (t > 1.0f) {
|
||||||
t = 1.0f;
|
t = 1.0f;
|
||||||
}
|
}
|
||||||
return {a.x + AB.x * t, a.y + AB.y * t};
|
return {a.x + AB.x * t, a.y + AB.y * t};
|
||||||
}
|
}
|
||||||
|
|
||||||
float PhilipsHueLight::getDistanceBetweenTwoPoints(CiColor p1, CiColor p2) {
|
float PhilipsHueLight::getDistanceBetweenTwoPoints(CiColor p1, CiColor p2) {
|
||||||
// Horizontal difference.
|
// Horizontal difference.
|
||||||
float dx = p1.x - p2.x;
|
float dx = p1.x - p2.x;
|
||||||
// Vertical difference.
|
// Vertical difference.
|
||||||
float dy = p1.y - p2.y;
|
float dy = p1.y - p2.y;
|
||||||
// Absolute value.
|
// Absolute value.
|
||||||
return sqrt(dx * dx + dy * dy);
|
return sqrt(dx * dx + dy * dy);
|
||||||
}
|
}
|
||||||
|
|
||||||
CiColor PhilipsHueLight::rgbToCiColor(float red, float green, float blue) {
|
CiColor PhilipsHueLight::rgbToCiColor(float red, float green, float blue) {
|
||||||
// Apply gamma correction.
|
// Apply gamma correction.
|
||||||
float r = (red > 0.04045f) ? powf((red + 0.055f) / (1.0f + 0.055f), 2.4f) : (red / 12.92f);
|
float r = (red > 0.04045f) ? powf((red + 0.055f) / (1.0f + 0.055f), 2.4f) : (red / 12.92f);
|
||||||
float g = (green > 0.04045f) ? powf((green + 0.055f) / (1.0f + 0.055f), 2.4f) : (green / 12.92f);
|
float g = (green > 0.04045f) ? powf((green + 0.055f) / (1.0f + 0.055f), 2.4f) : (green / 12.92f);
|
||||||
float b = (blue > 0.04045f) ? powf((blue + 0.055f) / (1.0f + 0.055f), 2.4f) : (blue / 12.92f);
|
float b = (blue > 0.04045f) ? powf((blue + 0.055f) / (1.0f + 0.055f), 2.4f) : (blue / 12.92f);
|
||||||
// Convert to XYZ space.
|
// Convert to XYZ space.
|
||||||
float X = r * 0.649926f + g * 0.103455f + b * 0.197109f;
|
float X = r * 0.649926f + g * 0.103455f + b * 0.197109f;
|
||||||
float Y = r * 0.234327f + g * 0.743075f + b * 0.022598f;
|
float Y = r * 0.234327f + g * 0.743075f + b * 0.022598f;
|
||||||
float Z = r * 0.0000000f + g * 0.053077f + b * 1.035763f;
|
float Z = r * 0.0000000f + g * 0.053077f + b * 1.035763f;
|
||||||
// Convert to x,y space.
|
// Convert to x,y space.
|
||||||
float cx = X / (X + Y + Z);
|
float cx = X / (X + Y + Z);
|
||||||
float cy = Y / (X + Y + Z);
|
float cy = Y / (X + Y + Z);
|
||||||
if (isnan(cx)) {
|
if (isnan(cx)) {
|
||||||
cx = 0.0f;
|
cx = 0.0f;
|
||||||
}
|
}
|
||||||
if (isnan(cy)) {
|
if (isnan(cy)) {
|
||||||
cy = 0.0f;
|
cy = 0.0f;
|
||||||
}
|
}
|
||||||
// Brightness is simply Y in the XYZ space.
|
// Brightness is simply Y in the XYZ space.
|
||||||
CiColor xy = { cx, cy, Y };
|
CiColor xy = { cx, cy, Y };
|
||||||
// Check if the given XY value is within the color reach of our lamps.
|
// Check if the given XY value is within the color reach of our lamps.
|
||||||
if (!isPointInLampsReach(xy)) {
|
if (!isPointInLampsReach(xy)) {
|
||||||
// It seems the color is out of reach let's find the closes color we can produce with our lamp and send this XY value out.
|
// It seems the color is out of reach let's find the closes color we can produce with our lamp and send this XY value out.
|
||||||
CiColor pAB = getClosestPointToPoint(colorSpace.red, colorSpace.green, xy);
|
CiColor pAB = getClosestPointToPoint(colorSpace.red, colorSpace.green, xy);
|
||||||
CiColor pAC = getClosestPointToPoint(colorSpace.blue, colorSpace.red, xy);
|
CiColor pAC = getClosestPointToPoint(colorSpace.blue, colorSpace.red, xy);
|
||||||
CiColor pBC = getClosestPointToPoint(colorSpace.green, colorSpace.blue, xy);
|
CiColor pBC = getClosestPointToPoint(colorSpace.green, colorSpace.blue, xy);
|
||||||
// Get the distances per point and see which point is closer to our Point.
|
// Get the distances per point and see which point is closer to our Point.
|
||||||
float dAB = getDistanceBetweenTwoPoints(xy, pAB);
|
float dAB = getDistanceBetweenTwoPoints(xy, pAB);
|
||||||
float dAC = getDistanceBetweenTwoPoints(xy, pAC);
|
float dAC = getDistanceBetweenTwoPoints(xy, pAC);
|
||||||
float dBC = getDistanceBetweenTwoPoints(xy, pBC);
|
float dBC = getDistanceBetweenTwoPoints(xy, pBC);
|
||||||
float lowest = dAB;
|
float lowest = dAB;
|
||||||
CiColor closestPoint = pAB;
|
CiColor closestPoint = pAB;
|
||||||
if (dAC < lowest) {
|
if (dAC < lowest) {
|
||||||
lowest = dAC;
|
lowest = dAC;
|
||||||
closestPoint = pAC;
|
closestPoint = pAC;
|
||||||
}
|
}
|
||||||
if (dBC < lowest) {
|
if (dBC < lowest) {
|
||||||
lowest = dBC;
|
lowest = dBC;
|
||||||
closestPoint = pBC;
|
closestPoint = pBC;
|
||||||
}
|
}
|
||||||
// Change the xy value to a value which is within the reach of the lamp.
|
// Change the xy value to a value which is within the reach of the lamp.
|
||||||
xy.x = closestPoint.x;
|
xy.x = closestPoint.x;
|
||||||
xy.y = closestPoint.y;
|
xy.y = closestPoint.y;
|
||||||
}
|
}
|
||||||
return xy;
|
return xy;
|
||||||
}
|
}
|
||||||
|
|
||||||
LedDevicePhilipsHue::LedDevicePhilipsHue(const std::string& output, const std::string& username, bool switchOffOnBlack,
|
LedDevicePhilipsHue::LedDevicePhilipsHue(const std::string& output, const std::string& username, bool switchOffOnBlack,
|
||||||
int transitiontime, std::vector<unsigned int> lightIds) :
|
int transitiontime, std::vector<unsigned int> lightIds) :
|
||||||
host(output.c_str()), username(username.c_str()), switchOffOnBlack(switchOffOnBlack), transitiontime(
|
host(output.c_str()), username(username.c_str()), switchOffOnBlack(switchOffOnBlack), transitiontime(
|
||||||
transitiontime), lightIds(lightIds) {
|
transitiontime), lightIds(lightIds) {
|
||||||
manager = new QNetworkAccessManager();
|
manager = new QNetworkAccessManager();
|
||||||
timer.setInterval(3000);
|
timer.setInterval(3000);
|
||||||
timer.setSingleShot(true);
|
timer.setSingleShot(true);
|
||||||
connect(&timer, SIGNAL(timeout()), this, SLOT(restoreStates()));
|
connect(&timer, SIGNAL(timeout()), this, SLOT(restoreStates()));
|
||||||
}
|
}
|
||||||
|
|
||||||
LedDevicePhilipsHue::~LedDevicePhilipsHue() {
|
LedDevicePhilipsHue::~LedDevicePhilipsHue() {
|
||||||
delete manager;
|
delete manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDevicePhilipsHue::write(const std::vector<ColorRgb> & ledValues) {
|
int LedDevicePhilipsHue::write(const std::vector<ColorRgb> & ledValues) {
|
||||||
// Save light states if not done before.
|
// Save light states if not done before.
|
||||||
if (!areStatesSaved()) {
|
if (!areStatesSaved()) {
|
||||||
saveStates((unsigned int) ledValues.size());
|
saveStates((unsigned int) ledValues.size());
|
||||||
switchOn((unsigned int) ledValues.size());
|
switchOn((unsigned int) ledValues.size());
|
||||||
}
|
}
|
||||||
// If there are less states saved than colors given, then maybe something went wrong before.
|
// If there are less states saved than colors given, then maybe something went wrong before.
|
||||||
if (lights.size() != ledValues.size()) {
|
if (lights.size() != ledValues.size()) {
|
||||||
restoreStates();
|
restoreStates();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// Iterate through colors and set light states.
|
// Iterate through colors and set light states.
|
||||||
unsigned int idx = 0;
|
unsigned int idx = 0;
|
||||||
for (const ColorRgb& color : ledValues) {
|
for (const ColorRgb& color : ledValues) {
|
||||||
// Get lamp.
|
// Get lamp.
|
||||||
PhilipsHueLight& lamp = lights.at(idx);
|
PhilipsHueLight& lamp = lights.at(idx);
|
||||||
// Scale colors from [0, 255] to [0, 1] and convert to xy space.
|
// Scale colors from [0, 255] to [0, 1] and convert to xy space.
|
||||||
CiColor xy = lamp.rgbToCiColor(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f);
|
CiColor xy = lamp.rgbToCiColor(color.red / 255.0f, color.green / 255.0f, color.blue / 255.0f);
|
||||||
// Write color if color has been changed.
|
// Write color if color has been changed.
|
||||||
if (xy != lamp.color) {
|
if (xy != lamp.color) {
|
||||||
// Switch on if the lamp has been previously switched off.
|
// Switch on if the lamp has been previously switched off.
|
||||||
if (switchOffOnBlack && lamp.color == lamp.black) {
|
if (switchOffOnBlack && lamp.color == lamp.black) {
|
||||||
put(getStateRoute(lamp.id), QString("{\"on\": true}"));
|
put(getStateRoute(lamp.id), QString("{\"on\": true}"));
|
||||||
}
|
}
|
||||||
// Send adjust color and brightness command in JSON format.
|
// Send adjust color and brightness command in JSON format.
|
||||||
// We have to set the transition time each time.
|
// We have to set the transition time each time.
|
||||||
put(getStateRoute(lamp.id),
|
put(getStateRoute(lamp.id),
|
||||||
QString("{\"xy\": [%1, %2], \"bri\": %3, \"transitiontime\": %4}").arg(xy.x).arg(xy.y).arg(
|
QString("{\"xy\": [%1, %2], \"bri\": %3, \"transitiontime\": %4}").arg(xy.x).arg(xy.y).arg(
|
||||||
qRound(xy.bri * 255.0f)).arg(transitiontime));
|
qRound(xy.bri * 255.0f)).arg(transitiontime));
|
||||||
|
|
||||||
}
|
}
|
||||||
// Switch lamp off if switchOffOnBlack is enabled and the lamp is currently on.
|
// Switch lamp off if switchOffOnBlack is enabled and the lamp is currently on.
|
||||||
if (switchOffOnBlack) {
|
if (switchOffOnBlack) {
|
||||||
// From black to a color.
|
// From black to a color.
|
||||||
if (lamp.color == lamp.black && xy != lamp.black) {
|
if (lamp.color == lamp.black && xy != lamp.black) {
|
||||||
put(getStateRoute(lamp.id), QString("{\"on\": true}"));
|
put(getStateRoute(lamp.id), QString("{\"on\": true}"));
|
||||||
}
|
}
|
||||||
// From a color to black.
|
// From a color to black.
|
||||||
else if (lamp.color != lamp.black && xy == lamp.black) {
|
else if (lamp.color != lamp.black && xy == lamp.black) {
|
||||||
put(getStateRoute(lamp.id), QString("{\"on\": false}"));
|
put(getStateRoute(lamp.id), QString("{\"on\": false}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Remember last color.
|
// Remember last color.
|
||||||
lamp.color = xy;
|
lamp.color = xy;
|
||||||
// Next light id.
|
// Next light id.
|
||||||
idx++;
|
idx++;
|
||||||
}
|
}
|
||||||
timer.start();
|
timer.start();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int LedDevicePhilipsHue::switchOff() {
|
int LedDevicePhilipsHue::switchOff() {
|
||||||
timer.stop();
|
timer.stop();
|
||||||
// If light states have been saved before, ...
|
// If light states have been saved before, ...
|
||||||
if (areStatesSaved()) {
|
if (areStatesSaved()) {
|
||||||
// ... restore them.
|
// ... restore them.
|
||||||
restoreStates();
|
restoreStates();
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void LedDevicePhilipsHue::put(QString route, QString content) {
|
void LedDevicePhilipsHue::put(QString route, QString content) {
|
||||||
QString url = getUrl(route);
|
QString url = getUrl(route);
|
||||||
// Perfrom request
|
// Perfrom request
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
QNetworkReply* reply = manager->put(request, content.toLatin1());
|
QNetworkReply* reply = manager->put(request, content.toLatin1());
|
||||||
// Connect finished signal to quit slot of the loop.
|
// Connect finished signal to quit slot of the loop.
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
loop.connect(reply, SIGNAL(finished()), SLOT(quit()));
|
loop.connect(reply, SIGNAL(finished()), SLOT(quit()));
|
||||||
// Go into the loop until the request is finished.
|
// Go into the loop until the request is finished.
|
||||||
loop.exec();
|
loop.exec();
|
||||||
// Free space.
|
// Free space.
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
QByteArray LedDevicePhilipsHue::get(QString route) {
|
QByteArray LedDevicePhilipsHue::get(QString route) {
|
||||||
QString url = getUrl(route);
|
QString url = getUrl(route);
|
||||||
// Perfrom request
|
// Perfrom request
|
||||||
QNetworkRequest request(url);
|
QNetworkRequest request(url);
|
||||||
QNetworkReply* reply = manager->get(request);
|
QNetworkReply* reply = manager->get(request);
|
||||||
// Connect requestFinished signal to quit slot of the loop.
|
// Connect requestFinished signal to quit slot of the loop.
|
||||||
QEventLoop loop;
|
QEventLoop loop;
|
||||||
loop.connect(reply, SIGNAL(finished()), SLOT(quit()));
|
loop.connect(reply, SIGNAL(finished()), SLOT(quit()));
|
||||||
// Go into the loop until the request is finished.
|
// Go into the loop until the request is finished.
|
||||||
loop.exec();
|
loop.exec();
|
||||||
// Read all data of the response.
|
// Read all data of the response.
|
||||||
QByteArray response = reply->readAll();
|
QByteArray response = reply->readAll();
|
||||||
// Free space.
|
// Free space.
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
// Return response
|
// Return response
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LedDevicePhilipsHue::getStateRoute(unsigned int lightId) {
|
QString LedDevicePhilipsHue::getStateRoute(unsigned int lightId) {
|
||||||
return QString("lights/%1/state").arg(lightId);
|
return QString("lights/%1/state").arg(lightId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LedDevicePhilipsHue::getRoute(unsigned int lightId) {
|
QString LedDevicePhilipsHue::getRoute(unsigned int lightId) {
|
||||||
return QString("lights/%1").arg(lightId);
|
return QString("lights/%1").arg(lightId);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LedDevicePhilipsHue::getUrl(QString route) {
|
QString LedDevicePhilipsHue::getUrl(QString route) {
|
||||||
return QString("http://%1/api/%2/%3").arg(host).arg(username).arg(route);
|
return QString("http://%1/api/%2/%3").arg(host).arg(username).arg(route);
|
||||||
}
|
}
|
||||||
|
|
||||||
void LedDevicePhilipsHue::saveStates(unsigned int nLights) {
|
void LedDevicePhilipsHue::saveStates(unsigned int nLights) {
|
||||||
// Clear saved lamps.
|
// Clear saved lamps.
|
||||||
lights.clear();
|
lights.clear();
|
||||||
// Use json parser to parse reponse.
|
// Use json parser to parse reponse.
|
||||||
Json::Reader reader;
|
Json::Reader reader;
|
||||||
Json::FastWriter writer;
|
Json::FastWriter writer;
|
||||||
// Read light ids if none have been supplied by the user.
|
// Read light ids if none have been supplied by the user.
|
||||||
if (lightIds.size() != nLights) {
|
if (lightIds.size() != nLights) {
|
||||||
lightIds.clear();
|
lightIds.clear();
|
||||||
//
|
//
|
||||||
QByteArray response = get("lights");
|
QByteArray response = get("lights");
|
||||||
Json::Value json;
|
Json::Value json;
|
||||||
if (!reader.parse(QString(response).toStdString(), json)) {
|
if (!reader.parse(QString(response).toStdString(), json)) {
|
||||||
throw std::runtime_error(("No lights found at " + getUrl("lights")).toStdString());
|
throw std::runtime_error(("No lights found at " + getUrl("lights")).toStdString());
|
||||||
}
|
}
|
||||||
// Loop over all children.
|
// Loop over all children.
|
||||||
for (Json::ValueIterator it = json.begin(); it != json.end() && lightIds.size() < nLights; it++) {
|
for (Json::ValueIterator it = json.begin(); it != json.end() && lightIds.size() < nLights; it++) {
|
||||||
int lightId = atoi(it.key().asCString());
|
int lightId = atoi(it.key().asCString());
|
||||||
lightIds.push_back(lightId);
|
lightIds.push_back(lightId);
|
||||||
std::cout << "LedDevicePhilipsHue::saveStates(nLights=" << nLights << "): found light with id " << lightId
|
std::cout << "LedDevicePhilipsHue::saveStates(nLights=" << nLights << "): found light with id " << lightId
|
||||||
<< "." << std::endl;
|
<< "." << std::endl;
|
||||||
}
|
}
|
||||||
// Check if we found enough lights.
|
// Check if we found enough lights.
|
||||||
if (lightIds.size() != nLights) {
|
if (lightIds.size() != nLights) {
|
||||||
throw std::runtime_error(("Not enough lights found at " + getUrl("lights")).toStdString());
|
throw std::runtime_error(("Not enough lights found at " + getUrl("lights")).toStdString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Iterate lights.
|
// Iterate lights.
|
||||||
for (unsigned int i = 0; i < nLights; i++) {
|
for (unsigned int i = 0; i < nLights; i++) {
|
||||||
// Read the response.
|
// Read the response.
|
||||||
QByteArray response = get(getRoute(lightIds.at(i)));
|
QByteArray response = get(getRoute(lightIds.at(i)));
|
||||||
// Parse JSON.
|
// Parse JSON.
|
||||||
Json::Value json;
|
Json::Value json;
|
||||||
if (!reader.parse(QString(response).toStdString(), json)) {
|
if (!reader.parse(QString(response).toStdString(), json)) {
|
||||||
// Error occured, break loop.
|
// Error occured, break loop.
|
||||||
std::cerr << "LedDevicePhilipsHue::saveStates(nLights=" << nLights << "): got invalid response from light "
|
std::cerr << "LedDevicePhilipsHue::saveStates(nLights=" << nLights << "): got invalid response from light "
|
||||||
<< getUrl(getRoute(lightIds.at(i))).toStdString() << "." << std::endl;
|
<< getUrl(getRoute(lightIds.at(i))).toStdString() << "." << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Get state object values which are subject to change.
|
// Get state object values which are subject to change.
|
||||||
Json::Value state(Json::objectValue);
|
Json::Value state(Json::objectValue);
|
||||||
if (!json.isMember("state")) {
|
if (!json.isMember("state")) {
|
||||||
std::cerr << "LedDevicePhilipsHue::saveStates(nLights=" << nLights << "): got no state for light from "
|
std::cerr << "LedDevicePhilipsHue::saveStates(nLights=" << nLights << "): got no state for light from "
|
||||||
<< getUrl(getRoute(lightIds.at(i))).toStdString() << std::endl;
|
<< getUrl(getRoute(lightIds.at(i))).toStdString() << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!json["state"].isMember("on")) {
|
if (!json["state"].isMember("on")) {
|
||||||
std::cerr << "LedDevicePhilipsHue::saveStates(nLights=" << nLights << "): got no valid state from light "
|
std::cerr << "LedDevicePhilipsHue::saveStates(nLights=" << nLights << "): got no valid state from light "
|
||||||
<< getUrl(getRoute(lightIds.at(i))).toStdString() << std::endl;
|
<< getUrl(getRoute(lightIds.at(i))).toStdString() << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
state["on"] = json["state"]["on"];
|
state["on"] = json["state"]["on"];
|
||||||
if (json["state"]["on"] == true) {
|
if (json["state"]["on"] == true) {
|
||||||
state["xy"] = json["state"]["xy"];
|
state["xy"] = json["state"]["xy"];
|
||||||
state["bri"] = json["state"]["bri"];
|
state["bri"] = json["state"]["bri"];
|
||||||
}
|
}
|
||||||
// Determine the model id.
|
// Determine the model id.
|
||||||
QString modelId = QString(writer.write(json["modelid"]).c_str()).trimmed().replace("\"", "");
|
QString modelId = QString(writer.write(json["modelid"]).c_str()).trimmed().replace("\"", "");
|
||||||
QString originalState = QString(writer.write(state).c_str()).trimmed();
|
QString originalState = QString(writer.write(state).c_str()).trimmed();
|
||||||
// Save state object.
|
// Save state object.
|
||||||
lights.push_back(PhilipsHueLight(lightIds.at(i), originalState, modelId));
|
lights.push_back(PhilipsHueLight(lightIds.at(i), originalState, modelId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LedDevicePhilipsHue::switchOn(unsigned int nLights) {
|
void LedDevicePhilipsHue::switchOn(unsigned int nLights) {
|
||||||
for (PhilipsHueLight light : lights) {
|
for (PhilipsHueLight light : lights) {
|
||||||
put(getStateRoute(light.id), "{\"on\": true}");
|
put(getStateRoute(light.id), "{\"on\": true}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LedDevicePhilipsHue::restoreStates() {
|
void LedDevicePhilipsHue::restoreStates() {
|
||||||
for (PhilipsHueLight light : lights) {
|
for (PhilipsHueLight light : lights) {
|
||||||
put(getStateRoute(light.id), light.originalState);
|
put(getStateRoute(light.id), light.originalState);
|
||||||
}
|
}
|
||||||
// Clear saved light states.
|
// Clear saved light states.
|
||||||
lights.clear();
|
lights.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LedDevicePhilipsHue::areStatesSaved() {
|
bool LedDevicePhilipsHue::areStatesSaved() {
|
||||||
return !lights.empty();
|
return !lights.empty();
|
||||||
}
|
}
|
||||||
|
@ -1,236 +1,236 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
// STL includes
|
// STL includes
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
// Qt includes
|
// Qt includes
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
// Leddevice includes
|
// Leddevice includes
|
||||||
#include <leddevice/LedDevice.h>
|
#include <leddevice/LedDevice.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A color point in the color space of the hue system.
|
* A color point in the color space of the hue system.
|
||||||
*/
|
*/
|
||||||
struct CiColor {
|
struct CiColor {
|
||||||
/// X component.
|
/// X component.
|
||||||
float x;
|
float x;
|
||||||
/// Y component.
|
/// Y component.
|
||||||
float y;
|
float y;
|
||||||
/// The brightness.
|
/// The brightness.
|
||||||
float bri;
|
float bri;
|
||||||
};
|
};
|
||||||
|
|
||||||
bool operator==(CiColor p1, CiColor p2);
|
bool operator==(CiColor p1, CiColor p2);
|
||||||
bool operator!=(CiColor p1, CiColor p2);
|
bool operator!=(CiColor p1, CiColor p2);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Color triangle to define an available color space for the hue lamps.
|
* Color triangle to define an available color space for the hue lamps.
|
||||||
*/
|
*/
|
||||||
struct CiColorTriangle {
|
struct CiColorTriangle {
|
||||||
CiColor red, green, blue;
|
CiColor red, green, blue;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple class to hold the id, the latest color, the color space and the original state.
|
* Simple class to hold the id, the latest color, the color space and the original state.
|
||||||
*/
|
*/
|
||||||
class PhilipsHueLight {
|
class PhilipsHueLight {
|
||||||
public:
|
public:
|
||||||
unsigned int id;
|
unsigned int id;
|
||||||
CiColor black;
|
CiColor black;
|
||||||
CiColor color;
|
CiColor color;
|
||||||
CiColorTriangle colorSpace;
|
CiColorTriangle colorSpace;
|
||||||
QString originalState;
|
QString originalState;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Constructs the light.
|
/// Constructs the light.
|
||||||
///
|
///
|
||||||
/// @param id the light id
|
/// @param id the light id
|
||||||
///
|
///
|
||||||
/// @param originalState the json string of the original state
|
/// @param originalState the json string of the original state
|
||||||
///
|
///
|
||||||
/// @param modelId the model id of the hue lamp which is used to determine the color space
|
/// @param modelId the model id of the hue lamp which is used to determine the color space
|
||||||
///
|
///
|
||||||
PhilipsHueLight(unsigned int id, QString originalState, QString modelId);
|
PhilipsHueLight(unsigned int id, QString originalState, QString modelId);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Converts an RGB color to the Hue xy color space and brightness.
|
/// Converts an RGB color to the Hue xy color space and brightness.
|
||||||
/// https://github.com/PhilipsHue/PhilipsHueSDK-iOS-OSX/blob/master/ApplicationDesignNotes/RGB%20to%20xy%20Color%20conversion.md
|
/// https://github.com/PhilipsHue/PhilipsHueSDK-iOS-OSX/blob/master/ApplicationDesignNotes/RGB%20to%20xy%20Color%20conversion.md
|
||||||
///
|
///
|
||||||
/// @param red the red component in [0, 1]
|
/// @param red the red component in [0, 1]
|
||||||
///
|
///
|
||||||
/// @param green the green component in [0, 1]
|
/// @param green the green component in [0, 1]
|
||||||
///
|
///
|
||||||
/// @param blue the blue component in [0, 1]
|
/// @param blue the blue component in [0, 1]
|
||||||
///
|
///
|
||||||
/// @return color point
|
/// @return color point
|
||||||
///
|
///
|
||||||
CiColor rgbToCiColor(float red, float green, float blue);
|
CiColor rgbToCiColor(float red, float green, float blue);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @param p the color point to check
|
/// @param p the color point to check
|
||||||
///
|
///
|
||||||
/// @return true if the color point is covered by the lamp color space
|
/// @return true if the color point is covered by the lamp color space
|
||||||
///
|
///
|
||||||
bool isPointInLampsReach(CiColor p);
|
bool isPointInLampsReach(CiColor p);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @param p1 point one
|
/// @param p1 point one
|
||||||
///
|
///
|
||||||
/// @param p2 point tow
|
/// @param p2 point tow
|
||||||
///
|
///
|
||||||
/// @return the cross product between p1 and p2
|
/// @return the cross product between p1 and p2
|
||||||
///
|
///
|
||||||
float crossProduct(CiColor p1, CiColor p2);
|
float crossProduct(CiColor p1, CiColor p2);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @param a reference point one
|
/// @param a reference point one
|
||||||
///
|
///
|
||||||
/// @param b reference point two
|
/// @param b reference point two
|
||||||
///
|
///
|
||||||
/// @param p the point to which the closest point is to be found
|
/// @param p the point to which the closest point is to be found
|
||||||
///
|
///
|
||||||
/// @return the closest color point of p to a and b
|
/// @return the closest color point of p to a and b
|
||||||
///
|
///
|
||||||
CiColor getClosestPointToPoint(CiColor a, CiColor b, CiColor p);
|
CiColor getClosestPointToPoint(CiColor a, CiColor b, CiColor p);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @param p1 point one
|
/// @param p1 point one
|
||||||
///
|
///
|
||||||
/// @param p2 point tow
|
/// @param p2 point tow
|
||||||
///
|
///
|
||||||
/// @return the distance between the two points
|
/// @return the distance between the two points
|
||||||
///
|
///
|
||||||
float getDistanceBetweenTwoPoints(CiColor p1, CiColor p2);
|
float getDistanceBetweenTwoPoints(CiColor p1, CiColor p2);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation for the Philips Hue system.
|
* Implementation for the Philips Hue system.
|
||||||
*
|
*
|
||||||
* To use set the device to "philipshue".
|
* To use set the device to "philipshue".
|
||||||
* Uses the official Philips Hue API (http://developers.meethue.com).
|
* Uses the official Philips Hue API (http://developers.meethue.com).
|
||||||
* Framegrabber must be limited to 10 Hz / numer of lights to avoid rate limitation by the hue bridge.
|
* Framegrabber must be limited to 10 Hz / numer of lights to avoid rate limitation by the hue bridge.
|
||||||
* Create a new API user name "newdeveloper" on the bridge (http://developers.meethue.com/gettingstarted.html)
|
* Create a new API user name "newdeveloper" on the bridge (http://developers.meethue.com/gettingstarted.html)
|
||||||
*
|
*
|
||||||
* @author ntim (github), bimsarck (github)
|
* @author ntim (github), bimsarck (github)
|
||||||
*/
|
*/
|
||||||
class LedDevicePhilipsHue: public QObject, public LedDevice {
|
class LedDevicePhilipsHue: public QObject, public LedDevice {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
///
|
///
|
||||||
/// Constructs the device.
|
/// Constructs the device.
|
||||||
///
|
///
|
||||||
/// @param output the ip address of the bridge
|
/// @param output the ip address of the bridge
|
||||||
///
|
///
|
||||||
/// @param username username of the hue bridge (default: newdeveloper)
|
/// @param username username of the hue bridge (default: newdeveloper)
|
||||||
///
|
///
|
||||||
/// @param switchOffOnBlack kill lights for black (default: false)
|
/// @param switchOffOnBlack kill lights for black (default: false)
|
||||||
///
|
///
|
||||||
/// @param transitiontime the time duration a light change takes in multiples of 100 ms (default: 400 ms).
|
/// @param transitiontime the time duration a light change takes in multiples of 100 ms (default: 400 ms).
|
||||||
///
|
///
|
||||||
/// @param lightIds light ids of the lights to control if not starting at one in ascending order.
|
/// @param lightIds light ids of the lights to control if not starting at one in ascending order.
|
||||||
///
|
///
|
||||||
LedDevicePhilipsHue(const std::string& output, const std::string& username = "newdeveloper", bool switchOffOnBlack =
|
LedDevicePhilipsHue(const std::string& output, const std::string& username = "newdeveloper", bool switchOffOnBlack =
|
||||||
false, int transitiontime = 1, std::vector<unsigned int> lightIds = std::vector<unsigned int>());
|
false, int transitiontime = 1, std::vector<unsigned int> lightIds = std::vector<unsigned int>());
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Destructor of this device
|
/// Destructor of this device
|
||||||
///
|
///
|
||||||
virtual ~LedDevicePhilipsHue();
|
virtual ~LedDevicePhilipsHue();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sends the given led-color values via put request to the hue system
|
/// Sends the given led-color values via put request to the hue system
|
||||||
///
|
///
|
||||||
/// @param ledValues The color-value per led
|
/// @param ledValues The color-value per led
|
||||||
///
|
///
|
||||||
/// @return Zero on success else negative
|
/// @return Zero on success else negative
|
||||||
///
|
///
|
||||||
virtual int write(const std::vector<ColorRgb> & ledValues);
|
virtual int write(const std::vector<ColorRgb> & ledValues);
|
||||||
|
|
||||||
/// Restores the original state of the leds.
|
/// Restores the original state of the leds.
|
||||||
virtual int switchOff();
|
virtual int switchOff();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
/// Restores the status of all lights.
|
/// Restores the status of all lights.
|
||||||
void restoreStates();
|
void restoreStates();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Array to save the lamps.
|
/// Array to save the lamps.
|
||||||
std::vector<PhilipsHueLight> lights;
|
std::vector<PhilipsHueLight> lights;
|
||||||
/// Ip address of the bridge
|
/// Ip address of the bridge
|
||||||
QString host;
|
QString host;
|
||||||
/// User name for the API ("newdeveloper")
|
/// User name for the API ("newdeveloper")
|
||||||
QString username;
|
QString username;
|
||||||
/// QNetworkAccessManager object for sending requests.
|
/// QNetworkAccessManager object for sending requests.
|
||||||
QNetworkAccessManager* manager;
|
QNetworkAccessManager* manager;
|
||||||
/// Use timer to reset lights when we got into "GRABBINGMODE_OFF".
|
/// Use timer to reset lights when we got into "GRABBINGMODE_OFF".
|
||||||
QTimer timer;
|
QTimer timer;
|
||||||
///
|
///
|
||||||
bool switchOffOnBlack;
|
bool switchOffOnBlack;
|
||||||
/// Transition time in multiples of 100 ms.
|
/// Transition time in multiples of 100 ms.
|
||||||
/// The default of the Hue lights will be 400 ms, but we want to have it snapier
|
/// The default of the Hue lights will be 400 ms, but we want to have it snapier
|
||||||
int transitiontime;
|
int transitiontime;
|
||||||
/// Array of the light ids.
|
/// Array of the light ids.
|
||||||
std::vector<unsigned int> lightIds;
|
std::vector<unsigned int> lightIds;
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sends a HTTP GET request (blocking).
|
/// Sends a HTTP GET request (blocking).
|
||||||
///
|
///
|
||||||
/// @param route the URI of the request
|
/// @param route the URI of the request
|
||||||
///
|
///
|
||||||
/// @return response of the request
|
/// @return response of the request
|
||||||
///
|
///
|
||||||
QByteArray get(QString route);
|
QByteArray get(QString route);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Sends a HTTP PUT request (non-blocking).
|
/// Sends a HTTP PUT request (non-blocking).
|
||||||
///
|
///
|
||||||
/// @param route the URI of the request
|
/// @param route the URI of the request
|
||||||
///
|
///
|
||||||
/// @param content content of the request
|
/// @param content content of the request
|
||||||
///
|
///
|
||||||
void put(QString route, QString content);
|
void put(QString route, QString content);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @param lightId the id of the hue light (starting from 1)
|
/// @param lightId the id of the hue light (starting from 1)
|
||||||
///
|
///
|
||||||
/// @return the URI of the light state for PUT requests.
|
/// @return the URI of the light state for PUT requests.
|
||||||
///
|
///
|
||||||
QString getStateRoute(unsigned int lightId);
|
QString getStateRoute(unsigned int lightId);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @param lightId the id of the hue light (starting from 1)
|
/// @param lightId the id of the hue light (starting from 1)
|
||||||
///
|
///
|
||||||
/// @return the URI of the light for GET requests.
|
/// @return the URI of the light for GET requests.
|
||||||
///
|
///
|
||||||
QString getRoute(unsigned int lightId);
|
QString getRoute(unsigned int lightId);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @param route
|
/// @param route
|
||||||
///
|
///
|
||||||
/// @return the full URL of the request.
|
/// @return the full URL of the request.
|
||||||
///
|
///
|
||||||
QString getUrl(QString route);
|
QString getUrl(QString route);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Queries the status of all lights and saves it.
|
/// Queries the status of all lights and saves it.
|
||||||
///
|
///
|
||||||
/// @param nLights the number of lights
|
/// @param nLights the number of lights
|
||||||
///
|
///
|
||||||
void saveStates(unsigned int nLights);
|
void saveStates(unsigned int nLights);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Switches the leds on.
|
/// Switches the leds on.
|
||||||
///
|
///
|
||||||
/// @param nLights the number of lights
|
/// @param nLights the number of lights
|
||||||
///
|
///
|
||||||
void switchOn(unsigned int nLights);
|
void switchOn(unsigned int nLights);
|
||||||
|
|
||||||
///
|
///
|
||||||
/// @return true if light states have been saved.
|
/// @return true if light states have been saved.
|
||||||
///
|
///
|
||||||
bool areStatesSaved();
|
bool areStatesSaved();
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -16,18 +16,18 @@ LedDeviceTpm2::LedDeviceTpm2(const std::string& outputDevice, const unsigned bau
|
|||||||
|
|
||||||
int LedDeviceTpm2::write(const std::vector<ColorRgb> &ledValues)
|
int LedDeviceTpm2::write(const std::vector<ColorRgb> &ledValues)
|
||||||
{
|
{
|
||||||
if (_ledBuffer.size() == 0)
|
if (_ledBuffer.size() == 0)
|
||||||
{
|
{
|
||||||
_ledBuffer.resize(5 + 3*ledValues.size());
|
_ledBuffer.resize(5 + 3*ledValues.size());
|
||||||
_ledBuffer[0] = 0xC9; // block-start byte
|
_ledBuffer[0] = 0xC9; // block-start byte
|
||||||
_ledBuffer[1] = 0xDA; // DATA frame
|
_ledBuffer[1] = 0xDA; // DATA frame
|
||||||
_ledBuffer[2] = ((3 * ledValues.size()) >> 8) & 0xFF; // frame size high byte
|
_ledBuffer[2] = ((3 * ledValues.size()) >> 8) & 0xFF; // frame size high byte
|
||||||
_ledBuffer[3] = (3 * ledValues.size()) & 0xFF; // frame size low byte
|
_ledBuffer[3] = (3 * ledValues.size()) & 0xFF; // frame size low byte
|
||||||
_ledBuffer.back() = 0x36; // block-end byte
|
_ledBuffer.back() = 0x36; // block-end byte
|
||||||
}
|
}
|
||||||
|
|
||||||
// write data
|
// write data
|
||||||
memcpy(4 + _ledBuffer.data(), ledValues.data(), ledValues.size() * 3);
|
memcpy(4 + _ledBuffer.data(), ledValues.data(), ledValues.size() * 3);
|
||||||
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
|
return writeBytes(_ledBuffer.size(), _ledBuffer.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,55 +25,54 @@ LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate, c
|
|||||||
//LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate) :
|
//LedDeviceUdp::LedDeviceUdp(const std::string& output, const unsigned baudrate) :
|
||||||
// _ofs(output.empty()?"/home/pi/LedDevice.out":output.c_str())
|
// _ofs(output.empty()?"/home/pi/LedDevice.out":output.c_str())
|
||||||
{
|
{
|
||||||
|
std::string hostname;
|
||||||
std::string hostname;
|
std::string port;
|
||||||
std::string port;
|
ledprotocol = protocol;
|
||||||
ledprotocol = protocol;
|
leds_per_pkt = ((maxPacket-4)/3);
|
||||||
leds_per_pkt = ((maxPacket-4)/3);
|
if (leds_per_pkt <= 0) {
|
||||||
if (leds_per_pkt <= 0) {
|
leds_per_pkt = 200;
|
||||||
leds_per_pkt = 200;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
//printf ("leds_per_pkt is %d\n", leds_per_pkt);
|
//printf ("leds_per_pkt is %d\n", leds_per_pkt);
|
||||||
int got_colon=0;
|
int got_colon=0;
|
||||||
for (unsigned int i=0; i<output.length(); i++) {
|
for (unsigned int i=0; i<output.length(); i++) {
|
||||||
if (output[i] == ':') {
|
if (output[i] == ':') {
|
||||||
got_colon++;
|
got_colon++;
|
||||||
} else if (got_colon == 0) {
|
} else if (got_colon == 0) {
|
||||||
hostname+=output[i];
|
hostname+=output[i];
|
||||||
} else {
|
} else {
|
||||||
port+=output[i];
|
port+=output[i];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
//std::cout << "output " << output << " hostname " << hostname << " port " << port <<std::endl;
|
||||||
//std::cout << "output " << output << " hostname " << hostname << " port " << port <<std::endl;
|
assert(got_colon==1);
|
||||||
assert(got_colon==1);
|
|
||||||
|
|
||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
memset(&hints, 0, sizeof hints);
|
memset(&hints, 0, sizeof hints);
|
||||||
hints.ai_family = AF_UNSPEC;
|
hints.ai_family = AF_UNSPEC;
|
||||||
hints.ai_socktype = SOCK_DGRAM;
|
hints.ai_socktype = SOCK_DGRAM;
|
||||||
|
|
||||||
if ((rv = getaddrinfo(hostname.c_str() , port.c_str(), &hints, &servinfo)) != 0) {
|
if ((rv = getaddrinfo(hostname.c_str() , port.c_str(), &hints, &servinfo)) != 0) {
|
||||||
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
|
||||||
assert(rv==0);
|
assert(rv==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// loop through all the results and make a socket
|
// loop through all the results and make a socket
|
||||||
for(p = servinfo; p != NULL; p = p->ai_next) {
|
for(p = servinfo; p != NULL; p = p->ai_next) {
|
||||||
if ((sockfd = socket(p->ai_family, p->ai_socktype,
|
if ((sockfd = socket(p->ai_family, p->ai_socktype,
|
||||||
p->ai_protocol)) == -1) {
|
p->ai_protocol)) == -1) {
|
||||||
perror("talker: socket");
|
perror("talker: socket");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
fprintf(stderr, "talker: failed to create socket\n");
|
fprintf(stderr, "talker: failed to create socket\n");
|
||||||
assert(p!=NULL);
|
assert(p!=NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LedDeviceUdp::~LedDeviceUdp()
|
LedDeviceUdp::~LedDeviceUdp()
|
||||||
@ -99,7 +98,7 @@ int LedDeviceUdp::write(const std::vector<ColorRgb> & ledValues)
|
|||||||
udpbuffer[i++] = color.green;
|
udpbuffer[i++] = color.green;
|
||||||
udpbuffer[i++] = color.blue;
|
udpbuffer[i++] = color.blue;
|
||||||
}
|
}
|
||||||
//printf ("c.red %d sz c.red %d\n", color.red, sizeof(color.red));
|
//printf ("c.red %d sz c.red %d\n", color.red, sizeof(color.red));
|
||||||
}
|
}
|
||||||
sendto(sockfd, udpbuffer, i, 0, p->ai_addr, p->ai_addrlen);
|
sendto(sockfd, udpbuffer, i, 0, p->ai_addr, p->ai_addrlen);
|
||||||
}
|
}
|
||||||
@ -153,7 +152,6 @@ int LedDeviceUdp::write(const std::vector<ColorRgb> & ledValues)
|
|||||||
udpbuffer[udpPtr++] = ledCtr%256; // low byte
|
udpbuffer[udpPtr++] = ledCtr%256; // low byte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ledprotocol == 3) {
|
if (ledprotocol == 3) {
|
||||||
@ -172,7 +170,6 @@ int LedDeviceUdp::write(const std::vector<ColorRgb> & ledValues)
|
|||||||
udpbuffer[udpPtr++] = fragment_number++;
|
udpbuffer[udpPtr++] = fragment_number++;
|
||||||
udpbuffer[udpPtr++] = fragments;
|
udpbuffer[udpPtr++] = fragments;
|
||||||
|
|
||||||
|
|
||||||
for (const ColorRgb& color : ledValues)
|
for (const ColorRgb& color : ledValues)
|
||||||
{
|
{
|
||||||
if (udpPtr<4090) {
|
if (udpPtr<4090) {
|
||||||
@ -201,6 +198,6 @@ int LedDeviceUdp::write(const std::vector<ColorRgb> & ledValues)
|
|||||||
|
|
||||||
int LedDeviceUdp::switchOff()
|
int LedDeviceUdp::switchOff()
|
||||||
{
|
{
|
||||||
// return write(std::vector<ColorRgb>(mLedCount, ColorRgb{0,0,0}));
|
// return write(std::vector<ColorRgb>(mLedCount, ColorRgb{0,0,0}));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -86,17 +86,17 @@
|
|||||||
// Raspberry Pi low-level peripherals:
|
// Raspberry Pi low-level peripherals:
|
||||||
// http://elinux.org/RPi_Low-level_peripherals
|
// http://elinux.org/RPi_Low-level_peripherals
|
||||||
//
|
//
|
||||||
// Richard Hirst's nice, clean code:
|
// Richard Hirst's nice, clean code:
|
||||||
// https://github.com/richardghirst/PiBits/blob/master/PiFmDma/PiFmDma.c
|
// https://github.com/richardghirst/PiBits/blob/master/PiFmDma/PiFmDma.c
|
||||||
//
|
//
|
||||||
// PWM clock register:
|
// PWM clock register:
|
||||||
// http://www.raspberrypi.org/forums/viewtopic.php?t=8467&p=124620
|
// http://www.raspberrypi.org/forums/viewtopic.php?t=8467&p=124620
|
||||||
//
|
//
|
||||||
// Simple (because it's in assembly) PWM+DMA setup:
|
// Simple (because it's in assembly) PWM+DMA setup:
|
||||||
// https://github.com/mikedurso/rpi-projects/blob/master/asm-nyancat/rpi-nyancat.s
|
// https://github.com/mikedurso/rpi-projects/blob/master/asm-nyancat/rpi-nyancat.s
|
||||||
//
|
//
|
||||||
// Adafruit's NeoPixel driver:
|
// Adafruit's NeoPixel driver:
|
||||||
// https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.cpp
|
// https://github.com/adafruit/Adafruit_NeoPixel/blob/master/Adafruit_NeoPixel.cpp
|
||||||
|
|
||||||
// Hyperion includes
|
// Hyperion includes
|
||||||
#include <leddevice/LedDevice.h>
|
#include <leddevice/LedDevice.h>
|
||||||
|
@ -1,61 +1,61 @@
|
|||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/protoserver)
|
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/protoserver)
|
||||||
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/protoserver)
|
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/protoserver)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
${CMAKE_CURRENT_BINARY_DIR}
|
${CMAKE_CURRENT_BINARY_DIR}
|
||||||
${PROTOBUF_INCLUDE_DIRS}
|
${PROTOBUF_INCLUDE_DIRS}
|
||||||
)
|
)
|
||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
set(ProtoServer_QT_HEADERS
|
set(ProtoServer_QT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/ProtoServer.h
|
${CURRENT_HEADER_DIR}/ProtoServer.h
|
||||||
${CURRENT_HEADER_DIR}/ProtoConnection.h
|
${CURRENT_HEADER_DIR}/ProtoConnection.h
|
||||||
${CURRENT_SOURCE_DIR}/ProtoClientConnection.h
|
${CURRENT_SOURCE_DIR}/ProtoClientConnection.h
|
||||||
${CURRENT_HEADER_DIR}/ProtoConnectionWrapper.h
|
${CURRENT_HEADER_DIR}/ProtoConnectionWrapper.h
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ProtoServer_HEADERS
|
set(ProtoServer_HEADERS
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ProtoServer_SOURCES
|
set(ProtoServer_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/ProtoServer.cpp
|
${CURRENT_SOURCE_DIR}/ProtoServer.cpp
|
||||||
${CURRENT_SOURCE_DIR}/ProtoClientConnection.cpp
|
${CURRENT_SOURCE_DIR}/ProtoClientConnection.cpp
|
||||||
${CURRENT_SOURCE_DIR}/ProtoConnection.cpp
|
${CURRENT_SOURCE_DIR}/ProtoConnection.cpp
|
||||||
${CURRENT_SOURCE_DIR}/ProtoConnectionWrapper.cpp
|
${CURRENT_SOURCE_DIR}/ProtoConnectionWrapper.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
set(ProtoServer_PROTOS
|
set(ProtoServer_PROTOS
|
||||||
${CURRENT_SOURCE_DIR}/message.proto
|
${CURRENT_SOURCE_DIR}/message.proto
|
||||||
)
|
)
|
||||||
|
|
||||||
protobuf_generate_cpp(ProtoServer_PROTO_SRCS ProtoServer_PROTO_HDRS
|
protobuf_generate_cpp(ProtoServer_PROTO_SRCS ProtoServer_PROTO_HDRS
|
||||||
${ProtoServer_PROTOS}
|
${ProtoServer_PROTOS}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_wrap_cpp(ProtoServer_HEADERS_MOC ${ProtoServer_QT_HEADERS})
|
qt5_wrap_cpp(ProtoServer_HEADERS_MOC ${ProtoServer_QT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
qt4_wrap_cpp(ProtoServer_HEADERS_MOC ${ProtoServer_QT_HEADERS})
|
qt4_wrap_cpp(ProtoServer_HEADERS_MOC ${ProtoServer_QT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(protoserver
|
add_library(protoserver
|
||||||
${ProtoServer_HEADERS}
|
${ProtoServer_HEADERS}
|
||||||
${ProtoServer_QT_HEADERS}
|
${ProtoServer_QT_HEADERS}
|
||||||
${ProtoServer_SOURCES}
|
${ProtoServer_SOURCES}
|
||||||
${ProtoServer_HEADERS_MOC}
|
${ProtoServer_HEADERS_MOC}
|
||||||
${ProtoServer_PROTOS}
|
${ProtoServer_PROTOS}
|
||||||
${ProtoServer_PROTO_SRCS}
|
${ProtoServer_PROTO_SRCS}
|
||||||
${ProtoServer_PROTO_HDRS}
|
${ProtoServer_PROTO_HDRS}
|
||||||
)
|
)
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_use_modules(protoserver Widgets)
|
qt5_use_modules(protoserver Widgets)
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
target_link_libraries(protoserver
|
target_link_libraries(protoserver
|
||||||
hyperion
|
hyperion
|
||||||
hyperion-utils
|
hyperion-utils
|
||||||
protobuf
|
protobuf
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
@ -8,207 +8,207 @@
|
|||||||
#include "protoserver/ProtoConnection.h"
|
#include "protoserver/ProtoConnection.h"
|
||||||
|
|
||||||
ProtoConnection::ProtoConnection(const std::string & a) :
|
ProtoConnection::ProtoConnection(const std::string & a) :
|
||||||
_socket(),
|
_socket(),
|
||||||
_skipReply(false),
|
_skipReply(false),
|
||||||
_prevSocketState(QAbstractSocket::UnconnectedState)
|
_prevSocketState(QAbstractSocket::UnconnectedState)
|
||||||
{
|
{
|
||||||
QString address(a.c_str());
|
QString address(a.c_str());
|
||||||
QStringList parts = address.split(":");
|
QStringList parts = address.split(":");
|
||||||
if (parts.size() != 2)
|
if (parts.size() != 2)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(QString("PROTOCONNECTION ERROR: Wrong address: Unable to parse address (%1)").arg(address).toStdString());
|
throw std::runtime_error(QString("PROTOCONNECTION ERROR: Wrong address: Unable to parse address (%1)").arg(address).toStdString());
|
||||||
}
|
}
|
||||||
_host = parts[0];
|
_host = parts[0];
|
||||||
|
|
||||||
bool ok;
|
bool ok;
|
||||||
_port = parts[1].toUShort(&ok);
|
_port = parts[1].toUShort(&ok);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
{
|
{
|
||||||
throw std::runtime_error(QString("PROTOCONNECTION ERROR: Wrong port: Unable to parse the port number (%1)").arg(parts[1]).toStdString());
|
throw std::runtime_error(QString("PROTOCONNECTION ERROR: Wrong port: Unable to parse the port number (%1)").arg(parts[1]).toStdString());
|
||||||
}
|
}
|
||||||
|
|
||||||
// try to connect to host
|
// try to connect to host
|
||||||
std::cout << "PROTOCONNECTION INFO: Connecting to Hyperion: " << _host.toStdString() << ":" << _port << std::endl;
|
std::cout << "PROTOCONNECTION INFO: Connecting to Hyperion: " << _host.toStdString() << ":" << _port << std::endl;
|
||||||
connectToHost();
|
connectToHost();
|
||||||
|
|
||||||
// start the connection timer
|
// start the connection timer
|
||||||
_timer.setInterval(5000);
|
_timer.setInterval(5000);
|
||||||
_timer.setSingleShot(false);
|
_timer.setSingleShot(false);
|
||||||
|
|
||||||
connect(&_timer,SIGNAL(timeout()), this, SLOT(connectToHost()) );
|
connect(&_timer,SIGNAL(timeout()), this, SLOT(connectToHost()) );
|
||||||
_timer.start();
|
_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtoConnection::~ProtoConnection()
|
ProtoConnection::~ProtoConnection()
|
||||||
{
|
{
|
||||||
_timer.stop();
|
_timer.stop();
|
||||||
_socket.close();
|
_socket.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConnection::setSkipReply(bool skip)
|
void ProtoConnection::setSkipReply(bool skip)
|
||||||
{
|
{
|
||||||
_skipReply = skip;
|
_skipReply = skip;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConnection::setColor(const ColorRgb & color, int priority, int duration)
|
void ProtoConnection::setColor(const ColorRgb & color, int priority, int duration)
|
||||||
{
|
{
|
||||||
proto::HyperionRequest request;
|
proto::HyperionRequest request;
|
||||||
request.set_command(proto::HyperionRequest::COLOR);
|
request.set_command(proto::HyperionRequest::COLOR);
|
||||||
proto::ColorRequest * colorRequest = request.MutableExtension(proto::ColorRequest::colorRequest);
|
proto::ColorRequest * colorRequest = request.MutableExtension(proto::ColorRequest::colorRequest);
|
||||||
colorRequest->set_rgbcolor((color.red << 16) | (color.green << 8) | color.blue);
|
colorRequest->set_rgbcolor((color.red << 16) | (color.green << 8) | color.blue);
|
||||||
colorRequest->set_priority(priority);
|
colorRequest->set_priority(priority);
|
||||||
colorRequest->set_duration(duration);
|
colorRequest->set_duration(duration);
|
||||||
|
|
||||||
// send command message
|
// send command message
|
||||||
sendMessage(request);
|
sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConnection::setImage(const Image<ColorRgb> &image, int priority, int duration)
|
void ProtoConnection::setImage(const Image<ColorRgb> &image, int priority, int duration)
|
||||||
{
|
{
|
||||||
proto::HyperionRequest request;
|
proto::HyperionRequest request;
|
||||||
request.set_command(proto::HyperionRequest::IMAGE);
|
request.set_command(proto::HyperionRequest::IMAGE);
|
||||||
proto::ImageRequest * imageRequest = request.MutableExtension(proto::ImageRequest::imageRequest);
|
proto::ImageRequest * imageRequest = request.MutableExtension(proto::ImageRequest::imageRequest);
|
||||||
imageRequest->set_imagedata(image.memptr(), image.width() * image.height() * 3);
|
imageRequest->set_imagedata(image.memptr(), image.width() * image.height() * 3);
|
||||||
imageRequest->set_imagewidth(image.width());
|
imageRequest->set_imagewidth(image.width());
|
||||||
imageRequest->set_imageheight(image.height());
|
imageRequest->set_imageheight(image.height());
|
||||||
imageRequest->set_priority(priority);
|
imageRequest->set_priority(priority);
|
||||||
imageRequest->set_duration(duration);
|
imageRequest->set_duration(duration);
|
||||||
|
|
||||||
// send command message
|
// send command message
|
||||||
sendMessage(request);
|
sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConnection::clear(int priority)
|
void ProtoConnection::clear(int priority)
|
||||||
{
|
{
|
||||||
proto::HyperionRequest request;
|
proto::HyperionRequest request;
|
||||||
request.set_command(proto::HyperionRequest::CLEAR);
|
request.set_command(proto::HyperionRequest::CLEAR);
|
||||||
proto::ClearRequest * clearRequest = request.MutableExtension(proto::ClearRequest::clearRequest);
|
proto::ClearRequest * clearRequest = request.MutableExtension(proto::ClearRequest::clearRequest);
|
||||||
clearRequest->set_priority(priority);
|
clearRequest->set_priority(priority);
|
||||||
|
|
||||||
// send command message
|
// send command message
|
||||||
sendMessage(request);
|
sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConnection::clearAll()
|
void ProtoConnection::clearAll()
|
||||||
{
|
{
|
||||||
proto::HyperionRequest request;
|
proto::HyperionRequest request;
|
||||||
request.set_command(proto::HyperionRequest::CLEARALL);
|
request.set_command(proto::HyperionRequest::CLEARALL);
|
||||||
|
|
||||||
// send command message
|
// send command message
|
||||||
sendMessage(request);
|
sendMessage(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConnection::connectToHost()
|
void ProtoConnection::connectToHost()
|
||||||
{
|
{
|
||||||
// try connection only when
|
// try connection only when
|
||||||
if (_socket.state() == QAbstractSocket::UnconnectedState)
|
if (_socket.state() == QAbstractSocket::UnconnectedState)
|
||||||
{
|
{
|
||||||
_socket.connectToHost(_host, _port);
|
_socket.connectToHost(_host, _port);
|
||||||
//_socket.waitForConnected(1000);
|
//_socket.waitForConnected(1000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProtoConnection::sendMessage(const proto::HyperionRequest &message)
|
void ProtoConnection::sendMessage(const proto::HyperionRequest &message)
|
||||||
{
|
{
|
||||||
// print out connection message only when state is changed
|
// print out connection message only when state is changed
|
||||||
if (_socket.state() != _prevSocketState )
|
if (_socket.state() != _prevSocketState )
|
||||||
{
|
{
|
||||||
switch (_socket.state() )
|
switch (_socket.state() )
|
||||||
{
|
{
|
||||||
case QAbstractSocket::UnconnectedState:
|
case QAbstractSocket::UnconnectedState:
|
||||||
std::cout << "PROTOCONNECTION INFO: No connection to Hyperion: " << _host.toStdString() << ":" << _port << std::endl;
|
std::cout << "PROTOCONNECTION INFO: No connection to Hyperion: " << _host.toStdString() << ":" << _port << std::endl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case QAbstractSocket::ConnectedState:
|
case QAbstractSocket::ConnectedState:
|
||||||
std::cout << "PROTOCONNECTION INFO: Connected to Hyperion: " << _host.toStdString() << ":" << _port << std::endl;
|
std::cout << "PROTOCONNECTION INFO: Connected to Hyperion: " << _host.toStdString() << ":" << _port << std::endl;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
//std::cout << "Connecting to Hyperion: " << _host.toStdString() << ":" << _port << std::endl;
|
//std::cout << "Connecting to Hyperion: " << _host.toStdString() << ":" << _port << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
_prevSocketState = _socket.state();
|
_prevSocketState = _socket.state();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (_socket.state() != QAbstractSocket::ConnectedState)
|
if (_socket.state() != QAbstractSocket::ConnectedState)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We only get here if we are connected
|
// We only get here if we are connected
|
||||||
|
|
||||||
// serialize message (FastWriter already appends a newline)
|
// serialize message (FastWriter already appends a newline)
|
||||||
std::string serializedMessage = message.SerializeAsString();
|
std::string serializedMessage = message.SerializeAsString();
|
||||||
|
|
||||||
int length = serializedMessage.size();
|
int length = serializedMessage.size();
|
||||||
const uint8_t header[] = {
|
const uint8_t header[] = {
|
||||||
uint8_t((length >> 24) & 0xFF),
|
uint8_t((length >> 24) & 0xFF),
|
||||||
uint8_t((length >> 16) & 0xFF),
|
uint8_t((length >> 16) & 0xFF),
|
||||||
uint8_t((length >> 8) & 0xFF),
|
uint8_t((length >> 8) & 0xFF),
|
||||||
uint8_t((length ) & 0xFF)};
|
uint8_t((length ) & 0xFF)};
|
||||||
|
|
||||||
// write message
|
// write message
|
||||||
int count = 0;
|
int count = 0;
|
||||||
count += _socket.write(reinterpret_cast<const char *>(header), 4);
|
count += _socket.write(reinterpret_cast<const char *>(header), 4);
|
||||||
count += _socket.write(reinterpret_cast<const char *>(serializedMessage.data()), length);
|
count += _socket.write(reinterpret_cast<const char *>(serializedMessage.data()), length);
|
||||||
if (!_socket.waitForBytesWritten())
|
if (!_socket.waitForBytesWritten())
|
||||||
{
|
{
|
||||||
std::cerr << "PROTOCONNECTION ERROR: Error while writing data to host" << std::endl;
|
std::cerr << "PROTOCONNECTION ERROR: Error while writing data to host" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_skipReply)
|
if (!_skipReply)
|
||||||
{
|
{
|
||||||
// read reply data
|
// read reply data
|
||||||
QByteArray serializedReply;
|
QByteArray serializedReply;
|
||||||
length = -1;
|
length = -1;
|
||||||
while (length < 0 && serializedReply.size() < length+4)
|
while (length < 0 && serializedReply.size() < length+4)
|
||||||
{
|
{
|
||||||
// receive reply
|
// receive reply
|
||||||
if (!_socket.waitForReadyRead())
|
if (!_socket.waitForReadyRead())
|
||||||
{
|
{
|
||||||
std::cerr << "PROTOCONNECTION ERROR: Error while reading data from host" << std::endl;
|
std::cerr << "PROTOCONNECTION ERROR: Error while reading data from host" << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
serializedReply += _socket.readAll();
|
serializedReply += _socket.readAll();
|
||||||
|
|
||||||
if (length < 0 && serializedReply.size() >= 4)
|
if (length < 0 && serializedReply.size() >= 4)
|
||||||
{
|
{
|
||||||
// read the message size
|
// read the message size
|
||||||
length =
|
length =
|
||||||
((serializedReply[0]<<24) & 0xFF000000) |
|
((serializedReply[0]<<24) & 0xFF000000) |
|
||||||
((serializedReply[1]<<16) & 0x00FF0000) |
|
((serializedReply[1]<<16) & 0x00FF0000) |
|
||||||
((serializedReply[2]<< 8) & 0x0000FF00) |
|
((serializedReply[2]<< 8) & 0x0000FF00) |
|
||||||
((serializedReply[3] ) & 0x000000FF);
|
((serializedReply[3] ) & 0x000000FF);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse reply data
|
// parse reply data
|
||||||
proto::HyperionReply reply;
|
proto::HyperionReply reply;
|
||||||
reply.ParseFromArray(serializedReply.constData()+4, length);
|
reply.ParseFromArray(serializedReply.constData()+4, length);
|
||||||
|
|
||||||
// parse reply message
|
// parse reply message
|
||||||
parseReply(reply);
|
parseReply(reply);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ProtoConnection::parseReply(const proto::HyperionReply &reply)
|
bool ProtoConnection::parseReply(const proto::HyperionReply &reply)
|
||||||
{
|
{
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
if (!reply.success())
|
if (!reply.success())
|
||||||
{
|
{
|
||||||
if (reply.has_error())
|
if (reply.has_error())
|
||||||
{
|
{
|
||||||
throw std::runtime_error("PROTOCONNECTION ERROR: " + reply.error());
|
throw std::runtime_error("PROTOCONNECTION ERROR: " + reply.error());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw std::runtime_error("PROTOCONNECTION ERROR: No error info");
|
throw std::runtime_error("PROTOCONNECTION ERROR: No error info");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
@ -2,11 +2,11 @@
|
|||||||
#include "protoserver/ProtoConnectionWrapper.h"
|
#include "protoserver/ProtoConnectionWrapper.h"
|
||||||
|
|
||||||
ProtoConnectionWrapper::ProtoConnectionWrapper(const std::string & address, int priority, int duration_ms, bool skipProtoReply) :
|
ProtoConnectionWrapper::ProtoConnectionWrapper(const std::string & address, int priority, int duration_ms, bool skipProtoReply) :
|
||||||
_priority(priority),
|
_priority(priority),
|
||||||
_duration_ms(duration_ms),
|
_duration_ms(duration_ms),
|
||||||
_connection(address)
|
_connection(address)
|
||||||
{
|
{
|
||||||
_connection.setSkipReply(skipProtoReply);
|
_connection.setSkipReply(skipProtoReply);
|
||||||
}
|
}
|
||||||
|
|
||||||
ProtoConnectionWrapper::~ProtoConnectionWrapper()
|
ProtoConnectionWrapper::~ProtoConnectionWrapper()
|
||||||
@ -15,5 +15,5 @@ ProtoConnectionWrapper::~ProtoConnectionWrapper()
|
|||||||
|
|
||||||
void ProtoConnectionWrapper::receiveImage(const Image<ColorRgb> & image)
|
void ProtoConnectionWrapper::receiveImage(const Image<ColorRgb> & image)
|
||||||
{
|
{
|
||||||
_connection.setImage(image, _priority, _duration_ms);
|
_connection.setImage(image, _priority, _duration_ms);
|
||||||
}
|
}
|
||||||
|
@ -1,41 +1,41 @@
|
|||||||
|
|
||||||
# Define the current source locations
|
# Define the current source locations
|
||||||
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/utils)
|
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/utils)
|
||||||
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/utils)
|
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/utils)
|
||||||
|
|
||||||
add_library(hyperion-utils
|
add_library(hyperion-utils
|
||||||
${CURRENT_HEADER_DIR}/ColorArgb.h
|
${CURRENT_HEADER_DIR}/ColorArgb.h
|
||||||
${CURRENT_SOURCE_DIR}/ColorArgb.cpp
|
${CURRENT_SOURCE_DIR}/ColorArgb.cpp
|
||||||
${CURRENT_HEADER_DIR}/ColorBgr.h
|
${CURRENT_HEADER_DIR}/ColorBgr.h
|
||||||
${CURRENT_SOURCE_DIR}/ColorBgr.cpp
|
${CURRENT_SOURCE_DIR}/ColorBgr.cpp
|
||||||
${CURRENT_HEADER_DIR}/ColorRgb.h
|
${CURRENT_HEADER_DIR}/ColorRgb.h
|
||||||
${CURRENT_SOURCE_DIR}/ColorRgb.cpp
|
${CURRENT_SOURCE_DIR}/ColorRgb.cpp
|
||||||
${CURRENT_HEADER_DIR}/ColorRgba.h
|
${CURRENT_HEADER_DIR}/ColorRgba.h
|
||||||
${CURRENT_SOURCE_DIR}/ColorRgba.cpp
|
${CURRENT_SOURCE_DIR}/ColorRgba.cpp
|
||||||
${CURRENT_HEADER_DIR}/Image.h
|
${CURRENT_HEADER_DIR}/Image.h
|
||||||
${CURRENT_HEADER_DIR}/Sleep.h
|
${CURRENT_HEADER_DIR}/Sleep.h
|
||||||
|
|
||||||
${CURRENT_HEADER_DIR}/PixelFormat.h
|
${CURRENT_HEADER_DIR}/PixelFormat.h
|
||||||
${CURRENT_HEADER_DIR}/VideoMode.h
|
${CURRENT_HEADER_DIR}/VideoMode.h
|
||||||
|
|
||||||
${CURRENT_HEADER_DIR}/ImageResampler.h
|
${CURRENT_HEADER_DIR}/ImageResampler.h
|
||||||
${CURRENT_SOURCE_DIR}/ImageResampler.cpp
|
${CURRENT_SOURCE_DIR}/ImageResampler.cpp
|
||||||
|
|
||||||
${CURRENT_HEADER_DIR}/HsvTransform.h
|
${CURRENT_HEADER_DIR}/HsvTransform.h
|
||||||
${CURRENT_SOURCE_DIR}/HsvTransform.cpp
|
${CURRENT_SOURCE_DIR}/HsvTransform.cpp
|
||||||
${CURRENT_HEADER_DIR}/HslTransform.h
|
${CURRENT_HEADER_DIR}/HslTransform.h
|
||||||
${CURRENT_SOURCE_DIR}/HslTransform.cpp
|
${CURRENT_SOURCE_DIR}/HslTransform.cpp
|
||||||
${CURRENT_HEADER_DIR}/RgbChannelTransform.h
|
${CURRENT_HEADER_DIR}/RgbChannelTransform.h
|
||||||
${CURRENT_SOURCE_DIR}/RgbChannelTransform.cpp
|
${CURRENT_SOURCE_DIR}/RgbChannelTransform.cpp
|
||||||
${CURRENT_HEADER_DIR}/RgbChannelCorrection.h
|
${CURRENT_HEADER_DIR}/RgbChannelCorrection.h
|
||||||
${CURRENT_SOURCE_DIR}/RgbChannelCorrection.cpp
|
${CURRENT_SOURCE_DIR}/RgbChannelCorrection.cpp
|
||||||
${CURRENT_HEADER_DIR}/RgbChannelAdjustment.h
|
${CURRENT_HEADER_DIR}/RgbChannelAdjustment.h
|
||||||
${CURRENT_SOURCE_DIR}/RgbChannelAdjustment.cpp
|
${CURRENT_SOURCE_DIR}/RgbChannelAdjustment.cpp
|
||||||
|
|
||||||
${CURRENT_HEADER_DIR}/jsonschema/JsonFactory.h
|
${CURRENT_HEADER_DIR}/jsonschema/JsonFactory.h
|
||||||
${CURRENT_HEADER_DIR}/jsonschema/JsonSchemaChecker.h
|
${CURRENT_HEADER_DIR}/jsonschema/JsonSchemaChecker.h
|
||||||
${CURRENT_SOURCE_DIR}/jsonschema/JsonSchemaChecker.cpp
|
${CURRENT_SOURCE_DIR}/jsonschema/JsonSchemaChecker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(hyperion-utils
|
target_link_libraries(hyperion-utils
|
||||||
jsoncpp)
|
jsoncpp)
|
||||||
|
@ -1,464 +1,464 @@
|
|||||||
// stdlib includes
|
// stdlib includes
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// Utils-Jsonschema includes
|
// Utils-Jsonschema includes
|
||||||
#include <utils/jsonschema/JsonSchemaChecker.h>
|
#include <utils/jsonschema/JsonSchemaChecker.h>
|
||||||
|
|
||||||
JsonSchemaChecker::JsonSchemaChecker()
|
JsonSchemaChecker::JsonSchemaChecker()
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
JsonSchemaChecker::~JsonSchemaChecker()
|
JsonSchemaChecker::~JsonSchemaChecker()
|
||||||
{
|
{
|
||||||
// empty
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonSchemaChecker::setSchema(const Json::Value & schema)
|
bool JsonSchemaChecker::setSchema(const Json::Value & schema)
|
||||||
{
|
{
|
||||||
_schema = schema;
|
_schema = schema;
|
||||||
|
|
||||||
// TODO: check the schema
|
// TODO: check the schema
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool JsonSchemaChecker::validate(const Json::Value & value)
|
bool JsonSchemaChecker::validate(const Json::Value & value)
|
||||||
{
|
{
|
||||||
// initialize state
|
// initialize state
|
||||||
_error = false;
|
_error = false;
|
||||||
_messages.clear();
|
_messages.clear();
|
||||||
_currentPath.clear();
|
_currentPath.clear();
|
||||||
_currentPath.push_back("[root]");
|
_currentPath.push_back("[root]");
|
||||||
_references.clear();
|
_references.clear();
|
||||||
|
|
||||||
// collect dependencies
|
// collect dependencies
|
||||||
collectDependencies(value, _schema);
|
collectDependencies(value, _schema);
|
||||||
|
|
||||||
// validate
|
// validate
|
||||||
validate(value, _schema);
|
validate(value, _schema);
|
||||||
|
|
||||||
return !_error;
|
return !_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::collectDependencies(const Json::Value & value, const Json::Value &schema)
|
void JsonSchemaChecker::collectDependencies(const Json::Value & value, const Json::Value &schema)
|
||||||
{
|
{
|
||||||
assert (schema.isObject());
|
assert (schema.isObject());
|
||||||
|
|
||||||
// check if id is present
|
// check if id is present
|
||||||
if (schema.isMember("id"))
|
if (schema.isMember("id"))
|
||||||
{
|
{
|
||||||
// strore reference
|
// strore reference
|
||||||
assert (schema["id"].isString());
|
assert (schema["id"].isString());
|
||||||
std::ostringstream ref;
|
std::ostringstream ref;
|
||||||
ref << "$(" << schema["id"].asString() << ")";
|
ref << "$(" << schema["id"].asString() << ")";
|
||||||
_references[ref.str()] = &value;
|
_references[ref.str()] = &value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check the current json value
|
// check the current json value
|
||||||
if (schema.isMember("properties"))
|
if (schema.isMember("properties"))
|
||||||
{
|
{
|
||||||
const Json::Value & properties = schema["properties"];
|
const Json::Value & properties = schema["properties"];
|
||||||
assert(properties.isObject());
|
assert(properties.isObject());
|
||||||
|
|
||||||
for (Json::Value::const_iterator j = properties.begin(); j != properties.end(); ++j)
|
for (Json::Value::const_iterator j = properties.begin(); j != properties.end(); ++j)
|
||||||
{
|
{
|
||||||
std::string property = j.memberName();
|
std::string property = j.memberName();
|
||||||
if (value.isMember(property))
|
if (value.isMember(property))
|
||||||
{
|
{
|
||||||
collectDependencies(value[property], properties[property]);
|
collectDependencies(value[property], properties[property]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::validate(const Json::Value & value, const Json::Value &schema)
|
void JsonSchemaChecker::validate(const Json::Value & value, const Json::Value &schema)
|
||||||
{
|
{
|
||||||
assert (schema.isObject());
|
assert (schema.isObject());
|
||||||
|
|
||||||
// check the current json value
|
// check the current json value
|
||||||
for (Json::Value::const_iterator i = schema.begin(); i != schema.end(); ++i)
|
for (Json::Value::const_iterator i = schema.begin(); i != schema.end(); ++i)
|
||||||
{
|
{
|
||||||
std::string attribute = i.memberName();
|
std::string attribute = i.memberName();
|
||||||
const Json::Value & attributeValue = *i;
|
const Json::Value & attributeValue = *i;
|
||||||
|
|
||||||
if (attribute == "type")
|
if (attribute == "type")
|
||||||
checkType(value, attributeValue);
|
checkType(value, attributeValue);
|
||||||
else if (attribute == "properties")
|
else if (attribute == "properties")
|
||||||
checkProperties(value, attributeValue);
|
checkProperties(value, attributeValue);
|
||||||
else if (attribute == "additionalProperties")
|
else if (attribute == "additionalProperties")
|
||||||
{
|
{
|
||||||
// ignore the properties which are handled by the properties attribute (if present)
|
// ignore the properties which are handled by the properties attribute (if present)
|
||||||
Json::Value::Members ignoredProperties;
|
Json::Value::Members ignoredProperties;
|
||||||
if (schema.isMember("properties")) {
|
if (schema.isMember("properties")) {
|
||||||
const Json::Value & props = schema["properties"];
|
const Json::Value & props = schema["properties"];
|
||||||
ignoredProperties = props.getMemberNames();
|
ignoredProperties = props.getMemberNames();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAdditionalProperties(value, attributeValue, ignoredProperties);
|
checkAdditionalProperties(value, attributeValue, ignoredProperties);
|
||||||
}
|
}
|
||||||
else if (attribute == "dependencies")
|
else if (attribute == "dependencies")
|
||||||
checkDependencies(value, attributeValue);
|
checkDependencies(value, attributeValue);
|
||||||
else if (attribute == "minimum")
|
else if (attribute == "minimum")
|
||||||
checkMinimum(value, attributeValue);
|
checkMinimum(value, attributeValue);
|
||||||
else if (attribute == "maximum")
|
else if (attribute == "maximum")
|
||||||
checkMaximum(value, attributeValue);
|
checkMaximum(value, attributeValue);
|
||||||
else if (attribute == "items")
|
else if (attribute == "items")
|
||||||
checkItems(value, attributeValue);
|
checkItems(value, attributeValue);
|
||||||
else if (attribute == "minItems")
|
else if (attribute == "minItems")
|
||||||
checkMinItems(value, attributeValue);
|
checkMinItems(value, attributeValue);
|
||||||
else if (attribute == "maxItems")
|
else if (attribute == "maxItems")
|
||||||
checkMaxItems(value, attributeValue);
|
checkMaxItems(value, attributeValue);
|
||||||
else if (attribute == "uniqueItems")
|
else if (attribute == "uniqueItems")
|
||||||
checkUniqueItems(value, attributeValue);
|
checkUniqueItems(value, attributeValue);
|
||||||
else if (attribute == "enum")
|
else if (attribute == "enum")
|
||||||
checkEnum(value, attributeValue);
|
checkEnum(value, attributeValue);
|
||||||
else if (attribute == "required")
|
else if (attribute == "required")
|
||||||
; // nothing to do. value is present so always oke
|
; // nothing to do. value is present so always oke
|
||||||
else if (attribute == "id")
|
else if (attribute == "id")
|
||||||
; // references have already been collected
|
; // references have already been collected
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// no check function defined for this attribute
|
// no check function defined for this attribute
|
||||||
setMessage(std::string("No check function defined for attribute ") + attribute);
|
setMessage(std::string("No check function defined for attribute ") + attribute);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::setMessage(const std::string & message)
|
void JsonSchemaChecker::setMessage(const std::string & message)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
std::copy(_currentPath.begin(), _currentPath.end(), std::ostream_iterator<std::string>(oss, ""));
|
std::copy(_currentPath.begin(), _currentPath.end(), std::ostream_iterator<std::string>(oss, ""));
|
||||||
oss << ": " << message;
|
oss << ": " << message;
|
||||||
_messages.push_back(oss.str());
|
_messages.push_back(oss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::list<std::string> & JsonSchemaChecker::getMessages() const
|
const std::list<std::string> & JsonSchemaChecker::getMessages() const
|
||||||
{
|
{
|
||||||
return _messages;
|
return _messages;
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkType(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkType(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isString());
|
assert(schema.isString());
|
||||||
|
|
||||||
std::string type = schema.asString();
|
std::string type = schema.asString();
|
||||||
bool wrongType = false;
|
bool wrongType = false;
|
||||||
if (type == "string")
|
if (type == "string")
|
||||||
wrongType = !value.isString();
|
wrongType = !value.isString();
|
||||||
else if (type == "number")
|
else if (type == "number")
|
||||||
wrongType = !value.isNumeric();
|
wrongType = !value.isNumeric();
|
||||||
else if (type == "integer")
|
else if (type == "integer")
|
||||||
wrongType = !value.isIntegral();
|
wrongType = !value.isIntegral();
|
||||||
else if (type == "double")
|
else if (type == "double")
|
||||||
wrongType = !value.isDouble();
|
wrongType = !value.isDouble();
|
||||||
else if (type == "boolean")
|
else if (type == "boolean")
|
||||||
wrongType = !value.isBool();
|
wrongType = !value.isBool();
|
||||||
else if (type == "object")
|
else if (type == "object")
|
||||||
wrongType = !value.isObject();
|
wrongType = !value.isObject();
|
||||||
else if (type == "array")
|
else if (type == "array")
|
||||||
wrongType = !value.isArray();
|
wrongType = !value.isArray();
|
||||||
else if (type == "null")
|
else if (type == "null")
|
||||||
wrongType = !value.isNull();
|
wrongType = !value.isNull();
|
||||||
else if (type == "enum")
|
else if (type == "enum")
|
||||||
wrongType = !value.isString();
|
wrongType = !value.isString();
|
||||||
else if (type == "any")
|
else if (type == "any")
|
||||||
wrongType = false;
|
wrongType = false;
|
||||||
// else
|
// else
|
||||||
// assert(false);
|
// assert(false);
|
||||||
|
|
||||||
if (wrongType)
|
if (wrongType)
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage(type + " expected");
|
setMessage(type + " expected");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkProperties(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkProperties(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isObject());
|
assert(schema.isObject());
|
||||||
|
|
||||||
if (!value.isObject())
|
if (!value.isObject())
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("properies attribute is only valid for objects");
|
setMessage("properies attribute is only valid for objects");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Json::Value::const_iterator i = schema.begin(); i != schema.end(); ++i)
|
for (Json::Value::const_iterator i = schema.begin(); i != schema.end(); ++i)
|
||||||
{
|
{
|
||||||
std::string property = i.memberName();
|
std::string property = i.memberName();
|
||||||
const Json::Value & propertyValue = *i;
|
const Json::Value & propertyValue = *i;
|
||||||
|
|
||||||
assert(propertyValue.isObject());
|
assert(propertyValue.isObject());
|
||||||
|
|
||||||
_currentPath.push_back(std::string(".") + property);
|
_currentPath.push_back(std::string(".") + property);
|
||||||
if (value.isMember(property))
|
if (value.isMember(property))
|
||||||
{
|
{
|
||||||
validate(value[property], propertyValue);
|
validate(value[property], propertyValue);
|
||||||
}
|
}
|
||||||
else if (propertyValue.get("required", false).asBool())
|
else if (propertyValue.get("required", false).asBool())
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("missing member");
|
setMessage("missing member");
|
||||||
}
|
}
|
||||||
_currentPath.pop_back();
|
_currentPath.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkAdditionalProperties(const Json::Value & value, const Json::Value & schema, const Json::Value::Members & ignoredProperties)
|
void JsonSchemaChecker::checkAdditionalProperties(const Json::Value & value, const Json::Value & schema, const Json::Value::Members & ignoredProperties)
|
||||||
{
|
{
|
||||||
if (!value.isObject())
|
if (!value.isObject())
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("additional properies attribute is only valid for objects");
|
setMessage("additional properies attribute is only valid for objects");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Json::Value::const_iterator i = value.begin(); i != value.end(); ++i)
|
for (Json::Value::const_iterator i = value.begin(); i != value.end(); ++i)
|
||||||
{
|
{
|
||||||
std::string property = i.memberName();
|
std::string property = i.memberName();
|
||||||
if (std::find(ignoredProperties.begin(), ignoredProperties.end(), property) == ignoredProperties.end())
|
if (std::find(ignoredProperties.begin(), ignoredProperties.end(), property) == ignoredProperties.end())
|
||||||
{
|
{
|
||||||
// property has no property definition. check against the definition for additional properties
|
// property has no property definition. check against the definition for additional properties
|
||||||
_currentPath.push_back(std::string(".") + property);
|
_currentPath.push_back(std::string(".") + property);
|
||||||
if (schema.isBool())
|
if (schema.isBool())
|
||||||
{
|
{
|
||||||
if (schema.asBool() == false)
|
if (schema.asBool() == false)
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("no schema definition");
|
setMessage("no schema definition");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
validate(value[property], schema);
|
validate(value[property], schema);
|
||||||
}
|
}
|
||||||
_currentPath.pop_back();
|
_currentPath.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkDependencies(const Json::Value & value, const Json::Value & schemaLink)
|
void JsonSchemaChecker::checkDependencies(const Json::Value & value, const Json::Value & schemaLink)
|
||||||
{
|
{
|
||||||
if (!value.isObject())
|
if (!value.isObject())
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("dependencies attribute is only valid for objects");
|
setMessage("dependencies attribute is only valid for objects");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(schemaLink.isString());
|
assert(schemaLink.isString());
|
||||||
std::map<std::string, const Json::Value *>::iterator iter = _references.find(schemaLink.asString());
|
std::map<std::string, const Json::Value *>::iterator iter = _references.find(schemaLink.asString());
|
||||||
if (iter == _references.end())
|
if (iter == _references.end())
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "reference " << schemaLink.asString() << " could not be resolved";
|
oss << "reference " << schemaLink.asString() << " could not be resolved";
|
||||||
setMessage(oss.str());
|
setMessage(oss.str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const Json::Value & schema = *(iter->second);
|
const Json::Value & schema = *(iter->second);
|
||||||
|
|
||||||
std::list<std::string> requiredProperties;
|
std::list<std::string> requiredProperties;
|
||||||
if (schema.isString())
|
if (schema.isString())
|
||||||
{
|
{
|
||||||
requiredProperties.push_back(schema.asString());
|
requiredProperties.push_back(schema.asString());
|
||||||
}
|
}
|
||||||
else if (schema.isArray())
|
else if (schema.isArray())
|
||||||
{
|
{
|
||||||
for (Json::UInt i = 0; i < schema.size(); ++i)
|
for (Json::UInt i = 0; i < schema.size(); ++i)
|
||||||
{
|
{
|
||||||
assert(schema[i].isString());
|
assert(schema[i].isString());
|
||||||
requiredProperties.push_back(schema[i].asString());
|
requiredProperties.push_back(schema[i].asString());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Exepected reference " << schemaLink.asString() << " to resolve to a string or array";
|
oss << "Exepected reference " << schemaLink.asString() << " to resolve to a string or array";
|
||||||
setMessage(oss.str());
|
setMessage(oss.str());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::list<std::string>::const_iterator i = requiredProperties.begin(); i != requiredProperties.end(); ++i)
|
for (std::list<std::string>::const_iterator i = requiredProperties.begin(); i != requiredProperties.end(); ++i)
|
||||||
{
|
{
|
||||||
if (!value.isMember(*i))
|
if (!value.isMember(*i))
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "missing member " << *i;
|
oss << "missing member " << *i;
|
||||||
setMessage(oss.str());
|
setMessage(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkMinimum(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkMinimum(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isNumeric());
|
assert(schema.isNumeric());
|
||||||
|
|
||||||
if (!value.isNumeric())
|
if (!value.isNumeric())
|
||||||
{
|
{
|
||||||
// only for numeric
|
// only for numeric
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("minimum check only for numeric fields");
|
setMessage("minimum check only for numeric fields");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.asDouble() < schema.asDouble())
|
if (value.asDouble() < schema.asDouble())
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "value is too small (minimum=" << schema.asDouble() << ")";
|
oss << "value is too small (minimum=" << schema.asDouble() << ")";
|
||||||
setMessage(oss.str());
|
setMessage(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkMaximum(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkMaximum(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isNumeric());
|
assert(schema.isNumeric());
|
||||||
|
|
||||||
if (!value.isNumeric())
|
if (!value.isNumeric())
|
||||||
{
|
{
|
||||||
// only for numeric
|
// only for numeric
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("maximum check only for numeric fields");
|
setMessage("maximum check only for numeric fields");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value.asDouble() > schema.asDouble())
|
if (value.asDouble() > schema.asDouble())
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "value is too large (maximum=" << schema.asDouble() << ")";
|
oss << "value is too large (maximum=" << schema.asDouble() << ")";
|
||||||
setMessage(oss.str());
|
setMessage(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkItems(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkItems(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isObject());
|
assert(schema.isObject());
|
||||||
|
|
||||||
if (!value.isArray())
|
if (!value.isArray())
|
||||||
{
|
{
|
||||||
// only for arrays
|
// only for arrays
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("items only valid for arrays");
|
setMessage("items only valid for arrays");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Json::ArrayIndex i = 0; i < value.size(); ++i)
|
for(Json::ArrayIndex i = 0; i < value.size(); ++i)
|
||||||
{
|
{
|
||||||
// validate each item
|
// validate each item
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "[" << i << "]";
|
oss << "[" << i << "]";
|
||||||
_currentPath.push_back(oss.str());
|
_currentPath.push_back(oss.str());
|
||||||
validate(value[i], schema);
|
validate(value[i], schema);
|
||||||
_currentPath.pop_back();
|
_currentPath.pop_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkMinItems(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkMinItems(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isIntegral());
|
assert(schema.isIntegral());
|
||||||
|
|
||||||
if (!value.isArray())
|
if (!value.isArray())
|
||||||
{
|
{
|
||||||
// only for arrays
|
// only for arrays
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("minItems only valid for arrays");
|
setMessage("minItems only valid for arrays");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int minimum = schema.asInt();
|
int minimum = schema.asInt();
|
||||||
|
|
||||||
if (static_cast<int>(value.size()) < minimum)
|
if (static_cast<int>(value.size()) < minimum)
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "array is too small (minimum=" << minimum << ")";
|
oss << "array is too small (minimum=" << minimum << ")";
|
||||||
setMessage(oss.str());
|
setMessage(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkMaxItems(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkMaxItems(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isIntegral());
|
assert(schema.isIntegral());
|
||||||
|
|
||||||
if (!value.isArray())
|
if (!value.isArray())
|
||||||
{
|
{
|
||||||
// only for arrays
|
// only for arrays
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("maxItems only valid for arrays");
|
setMessage("maxItems only valid for arrays");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int maximum = schema.asInt();
|
int maximum = schema.asInt();
|
||||||
|
|
||||||
if (static_cast<int>(value.size()) > maximum)
|
if (static_cast<int>(value.size()) > maximum)
|
||||||
{
|
{
|
||||||
_error = true;
|
_error = true;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "array is too large (maximum=" << maximum << ")";
|
oss << "array is too large (maximum=" << maximum << ")";
|
||||||
setMessage(oss.str());
|
setMessage(oss.str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkUniqueItems(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkUniqueItems(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isBool());
|
assert(schema.isBool());
|
||||||
|
|
||||||
if (!value.isArray())
|
if (!value.isArray())
|
||||||
{
|
{
|
||||||
// only for arrays
|
// only for arrays
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("uniqueItems only valid for arrays");
|
setMessage("uniqueItems only valid for arrays");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema.asBool() == true)
|
if (schema.asBool() == true)
|
||||||
{
|
{
|
||||||
// make sure no two items are identical
|
// make sure no two items are identical
|
||||||
|
|
||||||
for(Json::UInt i = 0; i < value.size(); ++i)
|
for(Json::UInt i = 0; i < value.size(); ++i)
|
||||||
{
|
{
|
||||||
for (Json::UInt j = i+1; j < value.size(); ++j)
|
for (Json::UInt j = i+1; j < value.size(); ++j)
|
||||||
{
|
{
|
||||||
if (value[i] == value[j])
|
if (value[i] == value[j])
|
||||||
{
|
{
|
||||||
// found a value twice
|
// found a value twice
|
||||||
_error = true;
|
_error = true;
|
||||||
setMessage("array must have unique values");
|
setMessage("array must have unique values");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void JsonSchemaChecker::checkEnum(const Json::Value & value, const Json::Value & schema)
|
void JsonSchemaChecker::checkEnum(const Json::Value & value, const Json::Value & schema)
|
||||||
{
|
{
|
||||||
assert(schema.isArray());
|
assert(schema.isArray());
|
||||||
|
|
||||||
for(Json::ArrayIndex i = 0; i < schema.size(); ++i)
|
for(Json::ArrayIndex i = 0; i < schema.size(); ++i)
|
||||||
{
|
{
|
||||||
if (schema[i] == value)
|
if (schema[i] == value)
|
||||||
{
|
{
|
||||||
// found enum value. done.
|
// found enum value. done.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// nothing found
|
// nothing found
|
||||||
_error = true;
|
_error = true;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << "Unknown enum value (allowed values are: ";
|
oss << "Unknown enum value (allowed values are: ";
|
||||||
std::string values = Json::FastWriter().write(schema);
|
std::string values = Json::FastWriter().write(schema);
|
||||||
oss << values.substr(0, values.size()-1); // The writer append a new line which we don't want
|
oss << values.substr(0, values.size()-1); // The writer append a new line which we don't want
|
||||||
oss << ")";
|
oss << ")";
|
||||||
setMessage(oss.str());
|
setMessage(oss.str());
|
||||||
}
|
}
|
||||||
|
@ -5,33 +5,33 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/xbmcvideochecker)
|
|||||||
|
|
||||||
# Group the headers that go through the MOC compiler
|
# Group the headers that go through the MOC compiler
|
||||||
SET(XBMCVideoChecker_QT_HEADERS
|
SET(XBMCVideoChecker_QT_HEADERS
|
||||||
${CURRENT_HEADER_DIR}/XBMCVideoChecker.h
|
${CURRENT_HEADER_DIR}/XBMCVideoChecker.h
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(XBMCVideoChecker_HEADERS
|
SET(XBMCVideoChecker_HEADERS
|
||||||
)
|
)
|
||||||
|
|
||||||
SET(XBMCVideoChecker_SOURCES
|
SET(XBMCVideoChecker_SOURCES
|
||||||
${CURRENT_SOURCE_DIR}/XBMCVideoChecker.cpp
|
${CURRENT_SOURCE_DIR}/XBMCVideoChecker.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
QT5_WRAP_CPP(XBMCVideoChecker_HEADERS_MOC ${XBMCVideoChecker_QT_HEADERS})
|
QT5_WRAP_CPP(XBMCVideoChecker_HEADERS_MOC ${XBMCVideoChecker_QT_HEADERS})
|
||||||
else(ENABLE_QT5)
|
else()
|
||||||
QT4_WRAP_CPP(XBMCVideoChecker_HEADERS_MOC ${XBMCVideoChecker_QT_HEADERS})
|
QT4_WRAP_CPP(XBMCVideoChecker_HEADERS_MOC ${XBMCVideoChecker_QT_HEADERS})
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
add_library(xbmcvideochecker
|
add_library(xbmcvideochecker
|
||||||
${XBMCVideoChecker_HEADERS}
|
${XBMCVideoChecker_HEADERS}
|
||||||
${XBMCVideoChecker_QT_HEADERS}
|
${XBMCVideoChecker_QT_HEADERS}
|
||||||
${XBMCVideoChecker_HEADERS_MOC}
|
${XBMCVideoChecker_HEADERS_MOC}
|
||||||
${XBMCVideoChecker_SOURCES}
|
${XBMCVideoChecker_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
if(ENABLE_QT5)
|
if(ENABLE_QT5)
|
||||||
qt5_use_modules(xbmcvideochecker Widgets)
|
qt5_use_modules(xbmcvideochecker Widgets)
|
||||||
endif(ENABLE_QT5)
|
endif()
|
||||||
|
|
||||||
target_link_libraries(xbmcvideochecker
|
target_link_libraries(xbmcvideochecker
|
||||||
hyperion
|
hyperion
|
||||||
${QT_LIBRARIES})
|
${QT_LIBRARIES})
|
||||||
|
@ -2,30 +2,27 @@ add_subdirectory(hyperiond)
|
|||||||
add_subdirectory(hyperion-remote)
|
add_subdirectory(hyperion-remote)
|
||||||
|
|
||||||
# The following clients depend on the protobuf library
|
# The following clients depend on the protobuf library
|
||||||
if(ENABLE_PROTOBUF)
|
if (ENABLE_AMLOGIC)
|
||||||
|
add_subdirectory(hyperion-aml)
|
||||||
if (ENABLE_AMLOGIC)
|
|
||||||
add_subdirectory(hyperion-aml)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_V4L2)
|
|
||||||
add_subdirectory(hyperion-v4l2)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_X11)
|
|
||||||
add_subdirectory(hyperion-x11)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_DISPMANX)
|
|
||||||
add_subdirectory(hyperion-dispmanx)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_FB)
|
|
||||||
add_subdirectory(hyperion-framebuffer)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(ENABLE_OSX)
|
|
||||||
add_subdirectory(hyperion-osx)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_V4L2)
|
||||||
|
add_subdirectory(hyperion-v4l2)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_X11)
|
||||||
|
add_subdirectory(hyperion-x11)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_DISPMANX)
|
||||||
|
add_subdirectory(hyperion-dispmanx)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_FB)
|
||||||
|
add_subdirectory(hyperion-framebuffer)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(ENABLE_OSX)
|
||||||
|
add_subdirectory(hyperion-osx)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
#include "AmlogicWrapper.h"
|
#include "AmlogicWrapper.h"
|
||||||
|
|
||||||
AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz) :
|
AmlogicWrapper::AmlogicWrapper(const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz) :
|
||||||
_timer(this),
|
_timer(this),
|
||||||
_grabber(grabWidth, grabHeight)
|
_grabber(grabWidth, grabHeight)
|
||||||
{
|
{
|
||||||
_timer.setSingleShot(false);
|
_timer.setSingleShot(false);
|
||||||
_timer.setInterval(updateRate_Hz);
|
_timer.setInterval(updateRate_Hz);
|
||||||
|
|
||||||
// Connect capturing to the timeout signal of the timer
|
// Connect capturing to the timeout signal of the timer
|
||||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Image<ColorRgb> & AmlogicWrapper::getScreenshot()
|
const Image<ColorRgb> & AmlogicWrapper::getScreenshot()
|
||||||
@ -21,12 +21,12 @@ const Image<ColorRgb> & AmlogicWrapper::getScreenshot()
|
|||||||
|
|
||||||
void AmlogicWrapper::start()
|
void AmlogicWrapper::start()
|
||||||
{
|
{
|
||||||
_timer.start();
|
_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmlogicWrapper::stop()
|
void AmlogicWrapper::stop()
|
||||||
{
|
{
|
||||||
_timer.stop();
|
_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AmlogicWrapper::capture()
|
void AmlogicWrapper::capture()
|
||||||
|
@ -7,16 +7,16 @@ DispmanxWrapper::DispmanxWrapper(const unsigned grabWidth, const unsigned grabHe
|
|||||||
const unsigned cropLeft, const unsigned cropRight,
|
const unsigned cropLeft, const unsigned cropRight,
|
||||||
const unsigned cropTop, const unsigned cropBottom,
|
const unsigned cropTop, const unsigned cropBottom,
|
||||||
const unsigned updateRate_Hz) :
|
const unsigned updateRate_Hz) :
|
||||||
_timer(this),
|
_timer(this),
|
||||||
_grabber(grabWidth, grabHeight)
|
_grabber(grabWidth, grabHeight)
|
||||||
{
|
{
|
||||||
_grabber.setVideoMode(videoMode);
|
_grabber.setVideoMode(videoMode);
|
||||||
_grabber.setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
_grabber.setCropping(cropLeft, cropRight, cropTop, cropBottom);
|
||||||
_timer.setSingleShot(false);
|
_timer.setSingleShot(false);
|
||||||
_timer.setInterval(updateRate_Hz);
|
_timer.setInterval(updateRate_Hz);
|
||||||
|
|
||||||
// Connect capturing to the timeout signal of the timer
|
// Connect capturing to the timeout signal of the timer
|
||||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Image<ColorRgb> & DispmanxWrapper::getScreenshot()
|
const Image<ColorRgb> & DispmanxWrapper::getScreenshot()
|
||||||
@ -27,12 +27,12 @@ const Image<ColorRgb> & DispmanxWrapper::getScreenshot()
|
|||||||
|
|
||||||
void DispmanxWrapper::start()
|
void DispmanxWrapper::start()
|
||||||
{
|
{
|
||||||
_timer.start();
|
_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispmanxWrapper::stop()
|
void DispmanxWrapper::stop()
|
||||||
{
|
{
|
||||||
_timer.stop();
|
_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void DispmanxWrapper::capture()
|
void DispmanxWrapper::capture()
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
#include "FramebufferWrapper.h"
|
#include "FramebufferWrapper.h"
|
||||||
|
|
||||||
FramebufferWrapper::FramebufferWrapper(const std::string & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz) :
|
FramebufferWrapper::FramebufferWrapper(const std::string & device, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz) :
|
||||||
_timer(this),
|
_timer(this),
|
||||||
_grabber(device,grabWidth, grabHeight)
|
_grabber(device,grabWidth, grabHeight)
|
||||||
{
|
{
|
||||||
_timer.setSingleShot(false);
|
_timer.setSingleShot(false);
|
||||||
_timer.setInterval(updateRate_Hz);
|
_timer.setInterval(updateRate_Hz);
|
||||||
|
|
||||||
// Connect capturing to the timeout signal of the timer
|
// Connect capturing to the timeout signal of the timer
|
||||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Image<ColorRgb> & FramebufferWrapper::getScreenshot()
|
const Image<ColorRgb> & FramebufferWrapper::getScreenshot()
|
||||||
@ -21,12 +21,12 @@ const Image<ColorRgb> & FramebufferWrapper::getScreenshot()
|
|||||||
|
|
||||||
void FramebufferWrapper::start()
|
void FramebufferWrapper::start()
|
||||||
{
|
{
|
||||||
_timer.start();
|
_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferWrapper::stop()
|
void FramebufferWrapper::stop()
|
||||||
{
|
{
|
||||||
_timer.stop();
|
_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FramebufferWrapper::capture()
|
void FramebufferWrapper::capture()
|
||||||
|
@ -3,14 +3,14 @@
|
|||||||
#include "OsxWrapper.h"
|
#include "OsxWrapper.h"
|
||||||
|
|
||||||
OsxWrapper::OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz) :
|
OsxWrapper::OsxWrapper(const unsigned display, const unsigned grabWidth, const unsigned grabHeight, const unsigned updateRate_Hz) :
|
||||||
_timer(this),
|
_timer(this),
|
||||||
_grabber(display,grabWidth, grabHeight)
|
_grabber(display,grabWidth, grabHeight)
|
||||||
{
|
{
|
||||||
_timer.setSingleShot(false);
|
_timer.setSingleShot(false);
|
||||||
_timer.setInterval(updateRate_Hz);
|
_timer.setInterval(updateRate_Hz);
|
||||||
|
|
||||||
// Connect capturing to the timeout signal of the timer
|
// Connect capturing to the timeout signal of the timer
|
||||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Image<ColorRgb> & OsxWrapper::getScreenshot()
|
const Image<ColorRgb> & OsxWrapper::getScreenshot()
|
||||||
|
@ -10,34 +10,34 @@ using namespace vlofgren;
|
|||||||
typedef vlofgren::PODParameter<PixelFormat> PixelFormatParameter;
|
typedef vlofgren::PODParameter<PixelFormat> PixelFormatParameter;
|
||||||
|
|
||||||
namespace vlofgren {
|
namespace vlofgren {
|
||||||
/// Translates a string (as passed on the commandline) to a pixel format
|
/// Translates a string (as passed on the commandline) to a pixel format
|
||||||
///
|
///
|
||||||
/// @param[in] s The string (as passed on the commandline)
|
/// @param[in] s The string (as passed on the commandline)
|
||||||
/// @return The pixel format
|
/// @return The pixel format
|
||||||
/// @throws Parameter::ParameterRejected If the string did not result in a pixel format
|
/// @throws Parameter::ParameterRejected If the string did not result in a pixel format
|
||||||
template<>
|
template<>
|
||||||
PixelFormat PixelFormatParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
PixelFormat PixelFormatParameter::validate(const std::string& s) throw (Parameter::ParameterRejected)
|
||||||
{
|
{
|
||||||
QString input = QString::fromStdString(s).toLower();
|
QString input = QString::fromStdString(s).toLower();
|
||||||
|
|
||||||
if (input == "yuyv")
|
if (input == "yuyv")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_YUYV;
|
return PIXELFORMAT_YUYV;
|
||||||
}
|
}
|
||||||
else if (input == "uyvy")
|
else if (input == "uyvy")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_UYVY;
|
return PIXELFORMAT_UYVY;
|
||||||
}
|
}
|
||||||
else if (input == "rgb32")
|
else if (input == "rgb32")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_RGB32;
|
return PIXELFORMAT_RGB32;
|
||||||
}
|
}
|
||||||
else if (input == "no-change")
|
else if (input == "no-change")
|
||||||
{
|
{
|
||||||
return PIXELFORMAT_NO_CHANGE;
|
return PIXELFORMAT_NO_CHANGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw Parameter::ParameterRejected("Invalid value for pixel format. Valid values are: YUYV, UYVY, RGB32, and NO-CHANGE");
|
throw Parameter::ParameterRejected("Invalid value for pixel format. Valid values are: YUYV, UYVY, RGB32, and NO-CHANGE");
|
||||||
return PIXELFORMAT_NO_CHANGE;
|
return PIXELFORMAT_NO_CHANGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include "ScreenshotHandler.h"
|
#include "ScreenshotHandler.h"
|
||||||
|
|
||||||
ScreenshotHandler::ScreenshotHandler(const std::string & filename) :
|
ScreenshotHandler::ScreenshotHandler(const std::string & filename) :
|
||||||
_filename(filename)
|
_filename(filename)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,150 +31,150 @@ using namespace vlofgren;
|
|||||||
// save the image as screenshot
|
// save the image as screenshot
|
||||||
void saveScreenshot(void *, const Image<ColorRgb> & image)
|
void saveScreenshot(void *, const Image<ColorRgb> & image)
|
||||||
{
|
{
|
||||||
// store as PNG
|
// store as PNG
|
||||||
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
|
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
|
||||||
pngImage.save("screenshot.png");
|
pngImage.save("screenshot.png");
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
<< "hyperion-v4l2:" << std::endl
|
<< "hyperion-v4l2:" << std::endl
|
||||||
<< "\tversion : " << HYPERION_VERSION_ID << std::endl
|
<< "\tversion : " << HYPERION_VERSION_ID << std::endl
|
||||||
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
||||||
|
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
// force the locale
|
// force the locale
|
||||||
setlocale(LC_ALL, "C");
|
setlocale(LC_ALL, "C");
|
||||||
QLocale::setDefault(QLocale::c());
|
QLocale::setDefault(QLocale::c());
|
||||||
|
|
||||||
// register the image type to use in signals
|
// register the image type to use in signals
|
||||||
qRegisterMetaType<Image<ColorRgb>>("Image<ColorRgb>");
|
qRegisterMetaType<Image<ColorRgb>>("Image<ColorRgb>");
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create the option parser and initialize all parameters
|
// create the option parser and initialize all parameters
|
||||||
OptionsParser optionParser("V4L capture application for Hyperion");
|
OptionsParser optionParser("V4L capture application for Hyperion");
|
||||||
ParameterSet & parameters = optionParser.getParameters();
|
ParameterSet & parameters = optionParser.getParameters();
|
||||||
|
|
||||||
StringParameter & argDevice = parameters.add<StringParameter> ('d', "device", "The device to use [default: /dev/video0]");
|
StringParameter & argDevice = parameters.add<StringParameter> ('d', "device", "The device to use [default: /dev/video0]");
|
||||||
VideoStandardParameter & argVideoStandard = parameters.add<VideoStandardParameter>('v', "video-standard", "The used video standard. Valid values are PAL or NTSC (optional)");
|
VideoStandardParameter & argVideoStandard = parameters.add<VideoStandardParameter>('v', "video-standard", "The used video standard. Valid values are PAL or NTSC (optional)");
|
||||||
PixelFormatParameter & argPixelFormat = parameters.add<PixelFormatParameter> (0x0, "pixel-format", "The use pixel format. Valid values are YUYV, UYVY, and RGB32 (optional)");
|
PixelFormatParameter & argPixelFormat = parameters.add<PixelFormatParameter> (0x0, "pixel-format", "The use pixel format. Valid values are YUYV, UYVY, and RGB32 (optional)");
|
||||||
IntParameter & argInput = parameters.add<IntParameter> (0x0, "input", "Input channel (optional)");
|
IntParameter & argInput = parameters.add<IntParameter> (0x0, "input", "Input channel (optional)");
|
||||||
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Try to set the width of the video input (optional)");
|
IntParameter & argWidth = parameters.add<IntParameter> (0x0, "width", "Try to set the width of the video input (optional)");
|
||||||
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "Try to set the height of the video input (optional)");
|
IntParameter & argHeight = parameters.add<IntParameter> (0x0, "height", "Try to set the height of the video input (optional)");
|
||||||
IntParameter & argCropWidth = parameters.add<IntParameter> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: 0]");
|
IntParameter & argCropWidth = parameters.add<IntParameter> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: 0]");
|
||||||
IntParameter & argCropHeight = parameters.add<IntParameter> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: 0]");
|
IntParameter & argCropHeight = parameters.add<IntParameter> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: 0]");
|
||||||
IntParameter & argCropLeft = parameters.add<IntParameter> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
|
IntParameter & argCropLeft = parameters.add<IntParameter> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
|
||||||
IntParameter & argCropRight = parameters.add<IntParameter> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
|
IntParameter & argCropRight = parameters.add<IntParameter> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
|
||||||
IntParameter & argCropTop = parameters.add<IntParameter> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
|
IntParameter & argCropTop = parameters.add<IntParameter> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
|
||||||
IntParameter & argCropBottom = parameters.add<IntParameter> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
|
IntParameter & argCropBottom = parameters.add<IntParameter> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
|
||||||
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=1]");
|
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=1]");
|
||||||
IntParameter & argFrameDecimation = parameters.add<IntParameter> ('f', "frame-decimator", "Decimation factor for the video frames [default=1]");
|
IntParameter & argFrameDecimation = parameters.add<IntParameter> ('f', "frame-decimator", "Decimation factor for the video frames [default=1]");
|
||||||
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
|
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
|
||||||
DoubleParameter & argSignalThreshold = parameters.add<DoubleParameter> ('t', "signal-threshold", "The signal threshold for detecting the presence of a signal. Value should be between 0.0 and 1.0.");
|
DoubleParameter & argSignalThreshold = parameters.add<DoubleParameter> ('t', "signal-threshold", "The signal threshold for detecting the presence of a signal. Value should be between 0.0 and 1.0.");
|
||||||
DoubleParameter & argRedSignalThreshold = parameters.add<DoubleParameter> (0x0, "red-threshold", "The red signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
|
DoubleParameter & argRedSignalThreshold = parameters.add<DoubleParameter> (0x0, "red-threshold", "The red signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
|
||||||
DoubleParameter & argGreenSignalThreshold = parameters.add<DoubleParameter> (0x0, "green-threshold", "The green signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
|
DoubleParameter & argGreenSignalThreshold = parameters.add<DoubleParameter> (0x0, "green-threshold", "The green signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
|
||||||
DoubleParameter & argBlueSignalThreshold = parameters.add<DoubleParameter> (0x0, "blue-threshold", "The blue signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
|
DoubleParameter & argBlueSignalThreshold = parameters.add<DoubleParameter> (0x0, "blue-threshold", "The blue signal threshold. Value should be between 0.0 and 1.0. (overrides --signal-threshold)");
|
||||||
SwitchParameter<> & arg3DSBS = parameters.add<SwitchParameter<>> (0x0, "3DSBS", "Interpret the incoming video stream as 3D side-by-side");
|
SwitchParameter<> & arg3DSBS = parameters.add<SwitchParameter<>> (0x0, "3DSBS", "Interpret the incoming video stream as 3D side-by-side");
|
||||||
SwitchParameter<> & arg3DTAB = parameters.add<SwitchParameter<>> (0x0, "3DTAB", "Interpret the incoming video stream as 3D top-and-bottom");
|
SwitchParameter<> & arg3DTAB = parameters.add<SwitchParameter<>> (0x0, "3DTAB", "Interpret the incoming video stream as 3D top-and-bottom");
|
||||||
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
|
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
|
||||||
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
|
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
|
||||||
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
|
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
|
||||||
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
|
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
argDevice.setDefault("/dev/video0");
|
argDevice.setDefault("/dev/video0");
|
||||||
argVideoStandard.setDefault(VIDEOSTANDARD_NO_CHANGE);
|
argVideoStandard.setDefault(VIDEOSTANDARD_NO_CHANGE);
|
||||||
argPixelFormat.setDefault(PIXELFORMAT_NO_CHANGE);
|
argPixelFormat.setDefault(PIXELFORMAT_NO_CHANGE);
|
||||||
argInput.setDefault(-1);
|
argInput.setDefault(-1);
|
||||||
argWidth.setDefault(-1);
|
argWidth.setDefault(-1);
|
||||||
argHeight.setDefault(-1);
|
argHeight.setDefault(-1);
|
||||||
argCropWidth.setDefault(0);
|
argCropWidth.setDefault(0);
|
||||||
argCropHeight.setDefault(0);
|
argCropHeight.setDefault(0);
|
||||||
argSizeDecimation.setDefault(1);
|
argSizeDecimation.setDefault(1);
|
||||||
argFrameDecimation.setDefault(1);
|
argFrameDecimation.setDefault(1);
|
||||||
argAddress.setDefault("127.0.0.1:19445");
|
argAddress.setDefault("127.0.0.1:19445");
|
||||||
argPriority.setDefault(800);
|
argPriority.setDefault(800);
|
||||||
argSignalThreshold.setDefault(-1);
|
argSignalThreshold.setDefault(-1);
|
||||||
|
|
||||||
// parse all options
|
// parse all options
|
||||||
optionParser.parse(argc, const_cast<const char **>(argv));
|
optionParser.parse(argc, const_cast<const char **>(argv));
|
||||||
|
|
||||||
// check if we need to display the usage. exit if we do.
|
// check if we need to display the usage. exit if we do.
|
||||||
if (argHelp.isSet())
|
if (argHelp.isSet())
|
||||||
{
|
{
|
||||||
optionParser.usage();
|
optionParser.usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cropping values if not defined
|
// cropping values if not defined
|
||||||
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
|
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
|
||||||
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
|
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
|
||||||
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
|
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
|
||||||
if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());
|
if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());
|
||||||
|
|
||||||
// initialize the grabber
|
// initialize the grabber
|
||||||
V4L2Grabber grabber(
|
V4L2Grabber grabber(
|
||||||
argDevice.getValue(),
|
argDevice.getValue(),
|
||||||
argInput.getValue(),
|
argInput.getValue(),
|
||||||
argVideoStandard.getValue(),
|
argVideoStandard.getValue(),
|
||||||
argPixelFormat.getValue(),
|
argPixelFormat.getValue(),
|
||||||
argWidth.getValue(),
|
argWidth.getValue(),
|
||||||
argHeight.getValue(),
|
argHeight.getValue(),
|
||||||
std::max(1, argFrameDecimation.getValue()),
|
std::max(1, argFrameDecimation.getValue()),
|
||||||
std::max(1, argSizeDecimation.getValue()),
|
std::max(1, argSizeDecimation.getValue()),
|
||||||
std::max(1, argSizeDecimation.getValue()));
|
std::max(1, argSizeDecimation.getValue()));
|
||||||
|
|
||||||
// set signal detection
|
// set signal detection
|
||||||
grabber.setSignalThreshold(
|
grabber.setSignalThreshold(
|
||||||
std::min(1.0, std::max(0.0, argRedSignalThreshold.isSet() ? argRedSignalThreshold.getValue() : argSignalThreshold.getValue())),
|
std::min(1.0, std::max(0.0, argRedSignalThreshold.isSet() ? argRedSignalThreshold.getValue() : argSignalThreshold.getValue())),
|
||||||
std::min(1.0, std::max(0.0, argGreenSignalThreshold.isSet() ? argGreenSignalThreshold.getValue() : argSignalThreshold.getValue())),
|
std::min(1.0, std::max(0.0, argGreenSignalThreshold.isSet() ? argGreenSignalThreshold.getValue() : argSignalThreshold.getValue())),
|
||||||
std::min(1.0, std::max(0.0, argBlueSignalThreshold.isSet() ? argBlueSignalThreshold.getValue() : argSignalThreshold.getValue())),
|
std::min(1.0, std::max(0.0, argBlueSignalThreshold.isSet() ? argBlueSignalThreshold.getValue() : argSignalThreshold.getValue())),
|
||||||
50);
|
50);
|
||||||
|
|
||||||
// set cropping values
|
// set cropping values
|
||||||
grabber.setCropping(
|
grabber.setCropping(
|
||||||
std::max(0, argCropLeft.getValue()),
|
std::max(0, argCropLeft.getValue()),
|
||||||
std::max(0, argCropRight.getValue()),
|
std::max(0, argCropRight.getValue()),
|
||||||
std::max(0, argCropTop.getValue()),
|
std::max(0, argCropTop.getValue()),
|
||||||
std::max(0, argCropBottom.getValue()));
|
std::max(0, argCropBottom.getValue()));
|
||||||
|
|
||||||
// set 3D mode if applicable
|
// set 3D mode if applicable
|
||||||
if (arg3DSBS.isSet())
|
if (arg3DSBS.isSet())
|
||||||
{
|
{
|
||||||
grabber.set3D(VIDEO_3DSBS);
|
grabber.set3D(VIDEO_3DSBS);
|
||||||
}
|
}
|
||||||
else if (arg3DTAB.isSet())
|
else if (arg3DTAB.isSet())
|
||||||
{
|
{
|
||||||
grabber.set3D(VIDEO_3DTAB);
|
grabber.set3D(VIDEO_3DTAB);
|
||||||
}
|
}
|
||||||
|
|
||||||
// run the grabber
|
// run the grabber
|
||||||
if (argScreenshot.isSet())
|
if (argScreenshot.isSet())
|
||||||
{
|
{
|
||||||
ScreenshotHandler handler("screenshot.png");
|
ScreenshotHandler handler("screenshot.png");
|
||||||
QObject::connect(&grabber, SIGNAL(newFrame(Image<ColorRgb>)), &handler, SLOT(receiveImage(Image<ColorRgb>)));
|
QObject::connect(&grabber, SIGNAL(newFrame(Image<ColorRgb>)), &handler, SLOT(receiveImage(Image<ColorRgb>)));
|
||||||
grabber.start();
|
grabber.start();
|
||||||
QCoreApplication::exec();
|
QCoreApplication::exec();
|
||||||
grabber.stop();
|
grabber.stop();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ProtoConnectionWrapper handler(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
|
ProtoConnectionWrapper handler(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
|
||||||
QObject::connect(&grabber, SIGNAL(newFrame(Image<ColorRgb>)), &handler, SLOT(receiveImage(Image<ColorRgb>)));
|
QObject::connect(&grabber, SIGNAL(newFrame(Image<ColorRgb>)), &handler, SLOT(receiveImage(Image<ColorRgb>)));
|
||||||
grabber.start();
|
grabber.start();
|
||||||
QCoreApplication::exec();
|
QCoreApplication::exec();
|
||||||
grabber.stop();
|
grabber.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::runtime_error & e)
|
catch (const std::runtime_error & e)
|
||||||
{
|
{
|
||||||
// An error occured. Display error and quit
|
// An error occured. Display error and quit
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -3,39 +3,39 @@
|
|||||||
#include "X11Wrapper.h"
|
#include "X11Wrapper.h"
|
||||||
|
|
||||||
X11Wrapper::X11Wrapper(int grabInterval, bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation) :
|
X11Wrapper::X11Wrapper(int grabInterval, bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation) :
|
||||||
_timer(this),
|
_timer(this),
|
||||||
_grabber(useXGetImage, cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation)
|
_grabber(useXGetImage, cropLeft, cropRight, cropTop, cropBottom, horizontalPixelDecimation, verticalPixelDecimation)
|
||||||
{
|
{
|
||||||
_timer.setSingleShot(false);
|
_timer.setSingleShot(false);
|
||||||
_timer.setInterval(grabInterval);
|
_timer.setInterval(grabInterval);
|
||||||
|
|
||||||
// Connect capturing to the timeout signal of the timer
|
// Connect capturing to the timeout signal of the timer
|
||||||
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
connect(&_timer, SIGNAL(timeout()), this, SLOT(capture()));
|
||||||
}
|
}
|
||||||
|
|
||||||
const Image<ColorRgb> & X11Wrapper::getScreenshot()
|
const Image<ColorRgb> & X11Wrapper::getScreenshot()
|
||||||
{
|
{
|
||||||
const Image<ColorRgb> & screenshot = _grabber.grab();
|
const Image<ColorRgb> & screenshot = _grabber.grab();
|
||||||
return screenshot;
|
return screenshot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Wrapper::start()
|
void X11Wrapper::start()
|
||||||
{
|
{
|
||||||
_timer.start();
|
_timer.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Wrapper::stop()
|
void X11Wrapper::stop()
|
||||||
{
|
{
|
||||||
_timer.stop();
|
_timer.stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool X11Wrapper::displayInit()
|
bool X11Wrapper::displayInit()
|
||||||
{
|
{
|
||||||
return _grabber.Setup();
|
return _grabber.Setup();
|
||||||
}
|
}
|
||||||
|
|
||||||
void X11Wrapper::capture()
|
void X11Wrapper::capture()
|
||||||
{
|
{
|
||||||
const Image<ColorRgb> & screenshot = _grabber.grab();
|
const Image<ColorRgb> & screenshot = _grabber.grab();
|
||||||
emit sig_screenshot(screenshot);
|
emit sig_screenshot(screenshot);
|
||||||
}
|
}
|
||||||
|
@ -7,35 +7,35 @@
|
|||||||
|
|
||||||
class X11Wrapper : public QObject
|
class X11Wrapper : public QObject
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
X11Wrapper(int grabInterval, bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation);
|
X11Wrapper(int grabInterval, bool useXGetImage, int cropLeft, int cropRight, int cropTop, int cropBottom, int horizontalPixelDecimation, int verticalPixelDecimation);
|
||||||
|
|
||||||
const Image<ColorRgb> & getScreenshot();
|
const Image<ColorRgb> & getScreenshot();
|
||||||
|
|
||||||
///
|
///
|
||||||
/// Starts the timed capturing of screenshots
|
/// Starts the timed capturing of screenshots
|
||||||
///
|
///
|
||||||
void start();
|
void start();
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
bool displayInit();
|
bool displayInit();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void sig_screenshot(const Image<ColorRgb> & screenshot);
|
void sig_screenshot(const Image<ColorRgb> & screenshot);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
///
|
///
|
||||||
/// Performs a single screenshot capture and publishes the capture screenshot on the screenshot
|
/// Performs a single screenshot capture and publishes the capture screenshot on the screenshot
|
||||||
/// signal.
|
/// signal.
|
||||||
///
|
///
|
||||||
void capture();
|
void capture();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The QT timer to generate capture-publish events
|
/// The QT timer to generate capture-publish events
|
||||||
QTimer _timer;
|
QTimer _timer;
|
||||||
|
|
||||||
/// The grabber for creating screenshots
|
/// The grabber for creating screenshots
|
||||||
X11Grabber _grabber;
|
X11Grabber _grabber;
|
||||||
};
|
};
|
||||||
|
@ -15,108 +15,108 @@ using namespace vlofgren;
|
|||||||
// save the image as screenshot
|
// save the image as screenshot
|
||||||
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
|
void saveScreenshot(const char * filename, const Image<ColorRgb> & image)
|
||||||
{
|
{
|
||||||
// store as PNG
|
// store as PNG
|
||||||
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
|
QImage pngImage((const uint8_t *) image.memptr(), image.width(), image.height(), 3*image.width(), QImage::Format_RGB888);
|
||||||
pngImage.save(filename);
|
pngImage.save(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char ** argv)
|
int main(int argc, char ** argv)
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
<< "hyperion-x11:" << std::endl
|
<< "hyperion-x11:" << std::endl
|
||||||
<< "\tversion : " << HYPERION_VERSION_ID << std::endl
|
<< "\tversion : " << HYPERION_VERSION_ID << std::endl
|
||||||
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
<< "\tbuild time: " << __DATE__ << " " << __TIME__ << std::endl;
|
||||||
|
|
||||||
QCoreApplication app(argc, argv);
|
QCoreApplication app(argc, argv);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// create the option parser and initialize all parameters
|
// create the option parser and initialize all parameters
|
||||||
OptionsParser optionParser("X11 capture application for Hyperion");
|
OptionsParser optionParser("X11 capture application for Hyperion");
|
||||||
ParameterSet & parameters = optionParser.getParameters();
|
ParameterSet & parameters = optionParser.getParameters();
|
||||||
|
|
||||||
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Capture frame rate [default: 10]");
|
IntParameter & argFps = parameters.add<IntParameter> ('f', "framerate", "Capture frame rate [default: 10]");
|
||||||
SwitchParameter<> & argXGetImage = parameters.add<SwitchParameter<>> ('x', "xgetimage", "Use XGetImage instead of XRender");
|
SwitchParameter<> & argXGetImage = parameters.add<SwitchParameter<>> ('x', "xgetimage", "Use XGetImage instead of XRender");
|
||||||
IntParameter & argCropWidth = parameters.add<IntParameter> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: 0]");
|
IntParameter & argCropWidth = parameters.add<IntParameter> (0x0, "crop-width", "Number of pixels to crop from the left and right sides of the picture before decimation [default: 0]");
|
||||||
IntParameter & argCropHeight = parameters.add<IntParameter> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: 0]");
|
IntParameter & argCropHeight = parameters.add<IntParameter> (0x0, "crop-height", "Number of pixels to crop from the top and the bottom of the picture before decimation [default: 0]");
|
||||||
IntParameter & argCropLeft = parameters.add<IntParameter> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
|
IntParameter & argCropLeft = parameters.add<IntParameter> (0x0, "crop-left", "Number of pixels to crop from the left of the picture before decimation (overrides --crop-width)");
|
||||||
IntParameter & argCropRight = parameters.add<IntParameter> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
|
IntParameter & argCropRight = parameters.add<IntParameter> (0x0, "crop-right", "Number of pixels to crop from the right of the picture before decimation (overrides --crop-width)");
|
||||||
IntParameter & argCropTop = parameters.add<IntParameter> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
|
IntParameter & argCropTop = parameters.add<IntParameter> (0x0, "crop-top", "Number of pixels to crop from the top of the picture before decimation (overrides --crop-height)");
|
||||||
IntParameter & argCropBottom = parameters.add<IntParameter> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
|
IntParameter & argCropBottom = parameters.add<IntParameter> (0x0, "crop-bottom", "Number of pixels to crop from the bottom of the picture before decimation (overrides --crop-height)");
|
||||||
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=8]");
|
IntParameter & argSizeDecimation = parameters.add<IntParameter> ('s', "size-decimator", "Decimation factor for the output size [default=8]");
|
||||||
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
|
SwitchParameter<> & argScreenshot = parameters.add<SwitchParameter<>> (0x0, "screenshot", "Take a single screenshot, save it to file and quit");
|
||||||
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
|
StringParameter & argAddress = parameters.add<StringParameter> ('a', "address", "Set the address of the hyperion server [default: 127.0.0.1:19445]");
|
||||||
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
|
IntParameter & argPriority = parameters.add<IntParameter> ('p', "priority", "Use the provided priority channel (the lower the number, the higher the priority) [default: 800]");
|
||||||
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
|
SwitchParameter<> & argSkipReply = parameters.add<SwitchParameter<>> (0x0, "skip-reply", "Do not receive and check reply messages from Hyperion");
|
||||||
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
|
SwitchParameter<> & argHelp = parameters.add<SwitchParameter<>> ('h', "help", "Show this help message and exit");
|
||||||
|
|
||||||
// set defaults
|
// set defaults
|
||||||
argFps.setDefault(10);
|
argFps.setDefault(10);
|
||||||
argCropWidth.setDefault(0);
|
argCropWidth.setDefault(0);
|
||||||
argCropHeight.setDefault(0);
|
argCropHeight.setDefault(0);
|
||||||
argSizeDecimation.setDefault(8);
|
argSizeDecimation.setDefault(8);
|
||||||
argAddress.setDefault("127.0.0.1:19445");
|
argAddress.setDefault("127.0.0.1:19445");
|
||||||
argPriority.setDefault(800);
|
argPriority.setDefault(800);
|
||||||
|
|
||||||
// parse all options
|
// parse all options
|
||||||
optionParser.parse(argc, const_cast<const char **>(argv));
|
optionParser.parse(argc, const_cast<const char **>(argv));
|
||||||
|
|
||||||
// check if we need to display the usage. exit if we do.
|
// check if we need to display the usage. exit if we do.
|
||||||
if (argHelp.isSet())
|
if (argHelp.isSet())
|
||||||
{
|
{
|
||||||
optionParser.usage();
|
optionParser.usage();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// cropping values if not defined
|
// cropping values if not defined
|
||||||
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
|
if (!argCropLeft.isSet()) argCropLeft.setDefault(argCropWidth.getValue());
|
||||||
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
|
if (!argCropRight.isSet()) argCropRight.setDefault(argCropWidth.getValue());
|
||||||
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
|
if (!argCropTop.isSet()) argCropTop.setDefault(argCropHeight.getValue());
|
||||||
if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());
|
if (!argCropBottom.isSet()) argCropBottom.setDefault(argCropHeight.getValue());
|
||||||
|
|
||||||
// Create the X11 grabbing stuff
|
// Create the X11 grabbing stuff
|
||||||
int grabInterval = 1000 / argFps.getValue();
|
int grabInterval = 1000 / argFps.getValue();
|
||||||
bool useXGetImage = argXGetImage.isSet();
|
bool useXGetImage = argXGetImage.isSet();
|
||||||
X11Wrapper x11Wrapper(
|
X11Wrapper x11Wrapper(
|
||||||
grabInterval,
|
grabInterval,
|
||||||
useXGetImage,
|
useXGetImage,
|
||||||
argCropLeft.getValue(),
|
argCropLeft.getValue(),
|
||||||
argCropRight.getValue(),
|
argCropRight.getValue(),
|
||||||
argCropTop.getValue(),
|
argCropTop.getValue(),
|
||||||
argCropBottom.getValue(),
|
argCropBottom.getValue(),
|
||||||
argSizeDecimation.getValue(), // horizontal decimation
|
argSizeDecimation.getValue(), // horizontal decimation
|
||||||
argSizeDecimation.getValue()); // vertical decimation
|
argSizeDecimation.getValue()); // vertical decimation
|
||||||
|
|
||||||
if (!x11Wrapper.displayInit())
|
if (!x11Wrapper.displayInit())
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (argScreenshot.isSet())
|
if (argScreenshot.isSet())
|
||||||
{
|
{
|
||||||
// Capture a single screenshot and finish
|
// Capture a single screenshot and finish
|
||||||
const Image<ColorRgb> & screenshot = x11Wrapper.getScreenshot();
|
const Image<ColorRgb> & screenshot = x11Wrapper.getScreenshot();
|
||||||
saveScreenshot("screenshot.png", screenshot);
|
saveScreenshot("screenshot.png", screenshot);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Create the Proto-connection with hyperiond
|
// Create the Proto-connection with hyperiond
|
||||||
ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
|
ProtoConnectionWrapper protoWrapper(argAddress.getValue(), argPriority.getValue(), 1000, argSkipReply.isSet());
|
||||||
|
|
||||||
// Connect the screen capturing to the proto processing
|
// Connect the screen capturing to the proto processing
|
||||||
QObject::connect(&x11Wrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));
|
QObject::connect(&x11Wrapper, SIGNAL(sig_screenshot(const Image<ColorRgb> &)), &protoWrapper, SLOT(receiveImage(Image<ColorRgb>)));
|
||||||
|
|
||||||
// Start the capturing
|
// Start the capturing
|
||||||
x11Wrapper.start();
|
x11Wrapper.start();
|
||||||
|
|
||||||
// Start the application
|
// Start the application
|
||||||
app.exec();
|
app.exec();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (const std::runtime_error & e)
|
catch (const std::runtime_error & e)
|
||||||
{
|
{
|
||||||
// An error occured. Display error and quit
|
// An error occured. Display error and quit
|
||||||
std::cerr << e.what() << std::endl;
|
std::cerr << e.what() << std::endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -51,10 +51,8 @@
|
|||||||
// JsonServer includes
|
// JsonServer includes
|
||||||
#include <jsonserver/JsonServer.h>
|
#include <jsonserver/JsonServer.h>
|
||||||
|
|
||||||
#ifdef ENABLE_PROTOBUF
|
|
||||||
// ProtoServer includes
|
// ProtoServer includes
|
||||||
#include <protoserver/ProtoServer.h>
|
#include <protoserver/ProtoServer.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
// BoblightServer includes
|
// BoblightServer includes
|
||||||
#include <boblightserver/BoblightServer.h>
|
#include <boblightserver/BoblightServer.h>
|
||||||
@ -208,7 +206,6 @@ int main(int argc, char** argv)
|
|||||||
std::cout << "INFO: Json server created and started on port " << jsonServer->getPort() << std::endl;
|
std::cout << "INFO: Json server created and started on port " << jsonServer->getPort() << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PROTOBUF
|
|
||||||
// Create Proto server if configuration is present
|
// Create Proto server if configuration is present
|
||||||
ProtoServer * protoServer = nullptr;
|
ProtoServer * protoServer = nullptr;
|
||||||
if (config.isMember("protoServer"))
|
if (config.isMember("protoServer"))
|
||||||
@ -217,7 +214,6 @@ int main(int argc, char** argv)
|
|||||||
protoServer = new ProtoServer(&hyperion, protoServerConfig["port"].asUInt() );
|
protoServer = new ProtoServer(&hyperion, protoServerConfig["port"].asUInt() );
|
||||||
std::cout << "INFO: Proto server created and started on port " << protoServer->getPort() << std::endl;
|
std::cout << "INFO: Proto server created and started on port " << protoServer->getPort() << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
// Create Boblight server if configuration is present
|
// Create Boblight server if configuration is present
|
||||||
BoblightServer * boblightServer = nullptr;
|
BoblightServer * boblightServer = nullptr;
|
||||||
@ -254,9 +250,7 @@ int main(int argc, char** argv)
|
|||||||
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), dispmanx, SLOT(setVideoMode(VideoMode)));
|
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), dispmanx, SLOT(setVideoMode(VideoMode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PROTOBUF
|
|
||||||
QObject::connect(dispmanx, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
QObject::connect(dispmanx, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||||
#endif
|
|
||||||
|
|
||||||
dispmanx->start();
|
dispmanx->start();
|
||||||
std::cout << "INFO: Frame grabber created and started" << std::endl;
|
std::cout << "INFO: Frame grabber created and started" << std::endl;
|
||||||
@ -297,9 +291,7 @@ int main(int argc, char** argv)
|
|||||||
grabberConfig.get("cropTop", 0).asInt(),
|
grabberConfig.get("cropTop", 0).asInt(),
|
||||||
grabberConfig.get("cropBottom", 0).asInt());
|
grabberConfig.get("cropBottom", 0).asInt());
|
||||||
|
|
||||||
#ifdef ENABLE_PROTOBUF
|
|
||||||
QObject::connect(v4l2Grabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
QObject::connect(v4l2Grabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||||
#endif
|
|
||||||
|
|
||||||
v4l2Grabber->start();
|
v4l2Grabber->start();
|
||||||
std::cout << "INFO: V4L2 grabber created and started" << std::endl;
|
std::cout << "INFO: V4L2 grabber created and started" << std::endl;
|
||||||
@ -331,9 +323,7 @@ int main(int argc, char** argv)
|
|||||||
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), amlGrabber, SLOT(setVideoMode(VideoMode)));
|
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), amlGrabber, SLOT(setVideoMode(VideoMode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PROTOBUF
|
|
||||||
QObject::connect(amlGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
QObject::connect(amlGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||||
#endif
|
|
||||||
|
|
||||||
amlGrabber->start();
|
amlGrabber->start();
|
||||||
std::cout << "INFO: AMLOGIC grabber created and started" << std::endl;
|
std::cout << "INFO: AMLOGIC grabber created and started" << std::endl;
|
||||||
@ -365,9 +355,7 @@ int main(int argc, char** argv)
|
|||||||
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), fbGrabber, SLOT(setVideoMode(VideoMode)));
|
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), fbGrabber, SLOT(setVideoMode(VideoMode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PROTOBUF
|
|
||||||
QObject::connect(fbGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
QObject::connect(fbGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||||
#endif
|
|
||||||
|
|
||||||
fbGrabber->start();
|
fbGrabber->start();
|
||||||
std::cout << "INFO: Framebuffer grabber created and started" << std::endl;
|
std::cout << "INFO: Framebuffer grabber created and started" << std::endl;
|
||||||
@ -405,9 +393,7 @@ int main(int argc, char** argv)
|
|||||||
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), osxGrabber, SLOT(setVideoMode(VideoMode)));
|
QObject::connect(xbmcVideoChecker, SIGNAL(videoMode(VideoMode)), osxGrabber, SLOT(setVideoMode(VideoMode)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ENABLE_PROTOBUF
|
|
||||||
QObject::connect(osxGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
QObject::connect(osxGrabber, SIGNAL(emitImage(int, const Image<ColorRgb>&, const int)), protoServer, SLOT(sendImageToProtoSlaves(int, const Image<ColorRgb>&, const int)) );
|
||||||
#endif
|
|
||||||
|
|
||||||
osxGrabber->start();
|
osxGrabber->start();
|
||||||
std::cout << "INFO: OSX grabber created and started" << std::endl;
|
std::cout << "INFO: OSX grabber created and started" << std::endl;
|
||||||
@ -445,9 +431,7 @@ int main(int argc, char** argv)
|
|||||||
#endif
|
#endif
|
||||||
delete xbmcVideoChecker;
|
delete xbmcVideoChecker;
|
||||||
delete jsonServer;
|
delete jsonServer;
|
||||||
#ifdef ENABLE_PROTOBUF
|
|
||||||
delete protoServer;
|
delete protoServer;
|
||||||
#endif
|
|
||||||
delete boblightServer;
|
delete boblightServer;
|
||||||
|
|
||||||
// leave application
|
// leave application
|
||||||
|
Loading…
Reference in New Issue
Block a user