Merge remote-tracking branch 'refs/remotes/origin/Beta'

Former-commit-id: 55e158c5cc
This commit is contained in:
brindosch 2016-06-11 10:43:19 +02:00
commit d2f47251f5
182 changed files with 8866 additions and 6977 deletions

3
.gitmodules vendored
View File

@ -3,4 +3,5 @@
url = https://github.com/tvdzwan/protobuf.git
[submodule "dependencies/external/rpi_ws281x"]
path = dependencies/external/rpi_ws281x
url = https://github.com/jgarff/rpi_ws281x
url = https://github.com/penfold42/rpi_ws281x.git
branch = sk6812

View File

@ -1,28 +1,63 @@
# Define the main-project name
project(Hyperion)
project(hyperion)
# define the minimum cmake version (as required by cmake)
cmake_minimum_required(VERSION 2.8)
#set(CMAKE_TOOLCHAIN_FILE /opt/raspberrypi/Toolchain-RaspberryPi.cmake)
IF ( POLICY CMP0026 )
CMAKE_POLICY( SET CMP0026 OLD )
ENDIF()
SET ( DEFAULT_AMLOGIC OFF )
SET ( DEFAULT_DISPMANX OFF )
SET ( DEFAULT_FB OFF )
SET ( DEFAULT_OSX OFF )
SET ( DEFAULT_X11 OFF )
SET ( DEFAULT_SPIDEV OFF )
SET ( DEFAULT_WS2812BPWM OFF )
SET ( DEFAULT_WS281XPWM OFF )
SET ( DEFAULT_ZEROCONF OFF )
if (APPLE)
SET ( DEFAULT_OSX ON )
else ()
if ( "${PLATFORM}" STREQUAL "rpi" )
SET ( DEFAULT_DISPMANX ON )
SET ( DEFAULT_SPIDEV ON )
elseif ( "${PLATFORM}" STREQUAL "rpi-pwm" )
SET ( DEFAULT_DISPMANX ON )
SET ( DEFAULT_WS2812BPWM ON )
SET ( DEFAULT_WS281XPWM ON )
SET ( DEFAULT_SPIDEV ON )
elseif ( "${PLATFORM}" STREQUAL "wetek" )
SET ( DEFAULT_AMLOGIC ON )
SET ( DEFAULT_FB ON )
elseif ( "${PLATFORM}" STREQUAL "x86" )
SET ( DEFAULT_X11 ON )
SET ( DEFAULT_FB ON )
elseif ( "${PLATFORM}" STREQUAL "imx6" )
SET ( DEFAULT_FB ON )
endif()
endif ()
# set the build options
option(ENABLE_AMLOGIC "Enable the AMLOGIC video grabber" OFF)
option(ENABLE_ZEROCONF "Enable the avahi/zeroconf announce" ${DEFAULT_ZEROCONF} )
message(STATUS "ENABLE_ZEROCONF = " ${ENABLE_ZEROCONF})
option(ENABLE_AMLOGIC "Enable the AMLOGIC video grabber" ${DEFAULT_AMLOGIC} )
message(STATUS "ENABLE_AMLOGIC = " ${ENABLE_AMLOGIC})
option(ENABLE_DISPMANX "Enable the RPi dispmanx grabber" ON)
option(ENABLE_DISPMANX "Enable the RPi dispmanx grabber" ${DEFAULT_DISPMANX} )
message(STATUS "ENABLE_DISPMANX = " ${ENABLE_DISPMANX})
option(ENABLE_FB "Enable the framebuffer grabber" OFF)
option(ENABLE_FB "Enable the framebuffer grabber" ${DEFAULT_FB} )
message(STATUS "ENABLE_FB = " ${ENABLE_FB})
option(ENABLE_OSX "Enable the osx grabber" OFF)
option(ENABLE_OSX "Enable the osx grabber" ${DEFAULT_OSX} )
message(STATUS "ENABLE_OSX = " ${ENABLE_OSX})
option(ENABLE_PROTOBUF "Enable PROTOBUF server" ON)
message(STATUS "ENABLE_PROTOBUF = " ${ENABLE_PROTOBUF})
option(ENABLE_SPIDEV "Enable the SPIDEV device" ON)
option(ENABLE_SPIDEV "Enable the SPIDEV device" ${DEFAULT_SPIDEV} )
message(STATUS "ENABLE_SPIDEV = " ${ENABLE_SPIDEV})
option(ENABLE_TINKERFORGE "Enable the TINKERFORGE device" ON)
@ -31,13 +66,13 @@ message(STATUS "ENABLE_TINKERFORGE = " ${ENABLE_TINKERFORGE})
option(ENABLE_V4L2 "Enable the V4L2 grabber" ON)
message(STATUS "ENABLE_V4L2 = " ${ENABLE_V4L2})
option(ENABLE_WS2812BPWM "Enable the WS2812b-PWM device" OFF)
option(ENABLE_WS2812BPWM "Enable the WS2812b-PWM device" ${DEFAULT_WS2812BPWM} )
message(STATUS "ENABLE_WS2812BPWM = " ${ENABLE_WS2812BPWM})
option(ENABLE_WS281XPWM "Enable the WS281x-PWM device" OFF)
option(ENABLE_WS281XPWM "Enable the WS281x-PWM device" ${DEFAULT_WS281XPWM} )
message(STATUS "ENABLE_WS281XPWM = " ${ENABLE_WS281XPWM})
option(ENABLE_X11 "Enable the X11 grabber" OFF)
option(ENABLE_X11 "Enable the X11 grabber" ${DEFAULT_X11})
message(STATUS "ENABLE_X11 = " ${ENABLE_X11})
option(ENABLE_QT5 "Enable QT5" OFF)
@ -46,22 +81,21 @@ message(STATUS "ENABLE_QT5 = " ${ENABLE_QT5})
option(ENABLE_TESTS "Compile additional test applications" OFF)
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(ENABLE_V4L2 AND NOT ENABLE_PROTOBUF)
option(ENABLE_PROFILER "enable profiler capabilities - not for release code" OFF)
message(STATUS "ENABLE_PROFILER = " ${ENABLE_PROFILER})
if(ENABLE_FB AND ENABLE_DISPMANX)
message(FATAL_ERROR "dispmanx grabber and framebuffer grabber cannot be used at the same time")
endif(ENABLE_FB AND ENABLE_DISPMANX)
endif()
if(ENABLE_FB AND ENABLE_OSX)
message(FATAL_ERROR "osx grabber and framebuffer grabber cannot be used at the same time")
endif(ENABLE_FB AND ENABLE_OSX)
endif()
if(ENABLE_OSX AND ENABLE_DISPMANX)
message(FATAL_ERROR "dispmanx grabber and osx grabber cannot be used at the same time")
endif(ENABLE_OSX AND ENABLE_DISPMANX)
endif()
SET ( PROTOBUF_INSTALL_BIN_DIR ${CMAKE_BINARY_DIR}/proto )
SET ( PROTOBUF_INSTALL_LIB_DIR ${CMAKE_BINARY_DIR}/proto )
@ -85,10 +119,10 @@ include_directories("${PROJECT_BINARY_DIR}")
if(ENABLE_QT5)
ADD_DEFINITIONS ( -DENABLE_QT5 )
#find_package(Qt5Widgets)
else(ENABLE_QT5)
else()
# Add specific cmake modules to find qt4 (default version finds first available QT which might not be qt4)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake/qt4)
endif(ENABLE_QT5)
endif()
# Define the global output path of binaries
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
@ -113,10 +147,10 @@ if(ENABLE_QT5)
find_package(Qt5 COMPONENTS Core Gui Widgets Network REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS}")
# set(CMAKE_CXX_FLAGS "-fPIC")
else(ENABLE_QT5)
else()
# Configure the use of QT4
find_package(Qt4 COMPONENTS QtCore QtNetwork QtGui REQUIRED QUIET)
endif(ENABLE_QT5)
endif()
#add libusb and pthreads
find_package(libusb-1.0 REQUIRED)
@ -124,10 +158,10 @@ find_package(Threads REQUIRED)
if(ENABLE_QT5)
#include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
else(ENABLE_QT5)
else()
include(${QT_USE_FILE})
add_definitions(${QT_DEFINITIONS})
endif(ENABLE_QT5)
endif()
# TODO[TvdZ]: This linking directory should only be added if we are cross compiling
if(NOT APPLE)
@ -138,18 +172,21 @@ if(ENABLE_OSX)
set(CMAKE_EXE_LINKER_FLAGS "-framework CoreGraphics")
endif()
configure_file(bin/install_hyperion.sh ${LIBRARY_OUTPUT_PATH} @ONLY)
configure_file(config/hyperion.config.json ${LIBRARY_OUTPUT_PATH} @ONLY)
configure_file(config/hyperion_x86.config.json ${LIBRARY_OUTPUT_PATH} @ONLY)
# Add the source/lib directories
add_subdirectory(dependencies)
add_subdirectory(libsrc)
add_subdirectory(src)
if (ENABLE_TESTS)
add_subdirectory(test)
endif (ENABLE_TESTS)
endif ()
# Add the doxygen generation directory
add_subdirectory(doc)
# uninstall target
configure_file( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY)
add_custom_target(uninstall COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
# enable make package - no code after this line !
include (${CMAKE_CURRENT_SOURCE_DIR}/cmake/packages.cmake)

19
CODING_STYLE.md Normal file
View File

@ -0,0 +1,19 @@
### Please use the following code style/guidelines
- use QT wherever it's possible (except there is a good reason)
- use unix line endings (not windows)
- indent your code with TABs instead of spaces
- follow this rule for curly brackets
```
bad:
if (conditon) {
code
}
good:
if (condition)
{
code
}
```

View File

@ -18,9 +18,6 @@
// Define to enable the spi-device
#cmakedefine ENABLE_TINKERFORGE
// Define to enable PROTOBUF server
#cmakedefine ENABLE_PROTOBUF
// Define to enable the framebuffer grabber
#cmakedefine ENABLE_FB
@ -30,4 +27,11 @@
// Define to enable the osx grabber
#cmakedefine ENABLE_OSX
// Define to enable the bonjour/zeroconf publishing
#cmakedefine ENABLE_ZEROCONF
// Define to enable profiler for development purpose
#cmakedefine ENABLE_PROFILER
// the hyperion build id string
#define HYPERION_VERSION_ID "${HYPERION_VERSION_ID}"

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2014 hyperion team
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,8 +1,8 @@
#!/bin/sh
if [ "$#" -ne 2 ] || ! [ -d "$1" ] || ! [ -d "$2" ]; then
echo "Usage: $0 <BUILD-DIR> <REPO-DIR>" >&2
exit 1
echo "Usage: $0 <BUILD-DIR> <REPO-DIR>" >&2
exit 1
fi
builddir="$1"

View File

@ -1,43 +1,34 @@
#!/bin/sh
# create all directly for release with -DCMAKE_BUILD_TYPE=Release -Wno-dev
# Create the x64 build
mkdir build-x86x64
cd build-x86x64
cmake -DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
make -j 4
cd ..
# Create the x32 build
#mkdir build-x32
#cd build-x32
#cmake -DIMPORT_PROTOC=../build-x64/protoc_export.cmake -DENABLE_DISPMANX=OFF -DENABLE_X11=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
#make -j 4
#cd ..
# make_release <release name> <platform> [<cmake args ...>]
make_release()
{
echo
echo "--- build release for $1 ---"
echo
RELEASE=$1
PLATFORM=$2
shift 2
# Create the RPI build
mkdir build-rpi
cd build-rpi
cmake -DCMAKE_TOOLCHAIN_FILE="../Toolchain-rpi.cmake" -DIMPORT_PROTOC=../build-x86x64/protoc_export.cmake -DENABLE_WS2812BPWM=ON -DENABLE_WS281XPWM=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
make -j 4
cd ..
mkdir -p build-${RELEASE}
mkdir -p deploy/${RELEASE}
cd build-${RELEASE}
cmake -DCMAKE_INSTALL_PREFIX=/usr -DPLATFORM=${PLATFORM} $@ -DCMAKE_BUILD_TYPE=Release -Wno-dev .. || exit 1
make -j $(nproc) || exit 1
#strip bin/*
make package -j $(nproc)
mv hyperion-*-ambilight.* ../deploy/${RELEASE}
cd ..
bin/create_release.sh . ${RELEASE}
}
# Create the WETEK build
mkdir build-wetek
cd build-wetek
cmake -DCMAKE_TOOLCHAIN_FILE="../Toolchain-rpi.cmake" -DIMPORT_PROTOC=../build-x86x64/protoc_export.cmake -DENABLE_DISPMANX=OFF -DENABLE_FB=ON -DENABLE_AMLOGIC=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
make -j 4
cd ..
export PATH="$PATH:$HOME/raspberrypi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin"
CMAKE_PROTOC_FLAG="-DIMPORT_PROTOC=../build-x86x64/protoc_export.cmake"
# Create the IMX6 build
#mkdir build-imx6
#cd build-imx6
#cmake -DCMAKE_TOOLCHAIN_FILE="../Toolchain-imx6.cmake" -DIMPORT_PROTOC=../build-x32x64/protoc_export.cmake -DENABLE_DISPMANX=OFF -DENABLE_FB=ON -DCMAKE_BUILD_TYPE=Release -Wno-dev ..
#make -j 4
#cd ..
make_release x86x64 x86
#make_release x32 x86 ${CMAKE_PROTOC_FLAG}
make_release rpi rpi-pwm -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-rpi.cmake" ${CMAKE_PROTOC_FLAG}
make_release wetek wetek -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-rpi.cmake" ${CMAKE_PROTOC_FLAG}
#make_release imx6 imx6 -DCMAKE_TOOLCHAIN_FILE="../cmake/Toolchain-imx6.cmake" ${CMAKE_PROTOC_FLAG}
bin/create_release.sh . x86x64
#bin/create_release.sh . x32
bin/create_release.sh . rpi
bin/create_release.sh . wetek
#bin/create_release.sh . imx6

View File

@ -23,18 +23,14 @@ tar --create --gzip --absolute-names --show-transformed-names --ignore-failed-re
--transform "s:$builddir/bin/:hyperion/bin/:" \
--transform "s:$repodir/effects/:hyperion/effects/:" \
--transform "s:$repodir/config/:hyperion/config/:" \
--transform "s:$repodir/bin/service/hyperion.init.sh:hyperion/init.d/hyperion.init.sh:" \
--transform "s:$repodir/bin/service/hyperion.systemd.sh:hyperion/init.d/hyperion.systemd.sh:" \
--transform "s:$repodir/bin/service/hyperion.initctl.sh:hyperion/init.d/hyperion.initctl.sh:" \
--transform "s:$repodir/bin/service/hyperion.init.sh:hyperion/services/hyperion.init.sh:" \
--transform "s:$repodir/bin/service/hyperion.systemd.sh:hyperion/services/hyperion.systemd.sh:" \
--transform "s:$repodir/bin/service/hyperion.initctl.sh:hyperion/services/hyperion.initctl.sh:" \
--transform "s://:/:g" \
"$builddir/bin/hyperiond" \
"$builddir/bin/hyperion-remote" \
"$builddir/bin/hyperion-v4l2" \
"$builddir/bin/hyperion-x11" \
"$builddir/bin/hyperion-dispmanx" \
"$builddir/bin/hyperion"* \
"$repodir/effects/"* \
"$repodir/bin/service/hyperion.init.sh" \
"$repodir/bin/service/hyperion.systemd.sh" \
"$repodir/bin/service/hyperion.initctl.sh" \
"$repodir/config/hyperion.config.json"
"$repodir/config/hyperion.config.json.example"

View File

@ -23,7 +23,7 @@ fi
#Set welcome message
if [ $BETA -eq 1 ]; then
WMESSAGE="echo This script will update Hyperion to the latest BETA"
else WMESSAGE="echo This script will install/update Hyperion Ambilight"
else WMESSAGE="echo This script will install/update Hyperion Ambient Light"
fi
#Welcome message
@ -74,24 +74,34 @@ if [ $BOBLIGHT_PROCNR -eq 1 ]; then
exit 1
fi
# Stop hyperion daemon if it is running
#set service script path
SERVICEL="/usr/share/hyperion/services"
# Stop hyperion daemon if it is running and set service path
echo '---> Stop Hyperion, if necessary'
if [ $OS_OPENELEC -eq 1 ]; then
killall hyperiond 2>/dev/null
elif [ $USE_INITCTL -eq 1 ]; then
/sbin/initctl stop hyperion 2>/dev/null
elif [ $USE_SERVICE -eq 1 ]; then
/usr/sbin/service hyperion stop 2>/dev/null
SERVICEP="/etc/init"
elif [ $USE_SYSTEMD -eq 1 ]; then
service hyperion stop 2>/dev/null
SERVICEP="/etc/systemd/system"
#many people installed with the official script and this just uses service, if both registered -> dead
/usr/sbin/service hyperion stop 2>/dev/null
#Bad workaround for Jessie (systemd) users that used the old official script for install
update-rc.d -f hyperion remove 2>/dev/null
rm /etc/init.d/hyperion 2>/dev/null
elif [ $USE_SERVICE -eq 1 ]; then
/usr/sbin/service hyperion stop 2>/dev/null
SERVICEP="/etc/init.d"
fi
#Install dependencies for Hyperion
#Install dependencies for Hyperion and setup preperation
if [ $OS_OPENELEC -ne 1 ]; then
echo '---> Install/Update Hyperion dependencies (This may take a while)'
apt-get -qq update && apt-get -qq --yes install libqtcore4 libqtgui4 libqt4-network libusb-1.0-0 ca-certificates
mkdir /etc/hyperion 2>/dev/null
fi
#Check, if dtparam=spi=on is in place (not for OPENELEC)
@ -119,15 +129,37 @@ if [ $CPU_RPI -eq 1 ] && [ $OS_OPENELEC -eq 1 ]; then
fi
fi
fi
#Backup the .conf files, if present
echo '---> Backup Hyperion configuration(s), if present'
rm -f /tmp/*.json 2>/dev/null
if [ $OS_OPENELEC -eq 1 ]; then
cp -v /storage/.config/*.json /tmp 2>/dev/null
else cp -v /opt/hyperion/config/*.json /tmp 2>/dev/null
fi
# compatibility layer to move old configs to new config dir
if [ -f "/opt/hyperion/bin/hyperiond" ]; then
echo '---> Old installation found, move configs to /etc/hyperion/ and move hyperion to /usr/share/hyperion/'
mv /opt/hyperion/config/*.json /etc/hyperion 2>/dev/null
sed -i "s|/opt/hyperion/effects|/usr/share/hyperion/effects|g" /etc/hyperion/*.json
CPO1=/etc/hyperion.config.json
CPO2=/opt/hyperion/config/hyperion.config.json
CPN=/etc/hyperion/hyperion.config.json
BPO=/opt/hyperion/bin/hyperiond
BPN=/usr/bin/hyperiond
if [ $USE_INITCTL -eq 1 ]; then
sed -i "s|$BPO|$BPN|g" $SERVICEP/hyperion.conf
sed -i "s|$CPO1|$CPN|g" $SERVICEP/hyperion.conf
sed -i "s|$CPO2|$CPN|g" $SERVICEP/hyperion.conf
initctl reload-configuration
elif [ $OS_OPENELEC -eq 1 ]; then
sleep 0
elif [ $USE_SYSTEMD -eq 1 ]; then
sed -i "s|$BPO|$BPN|g" $SERVICEP/hyperion.service
sed -i "s|$CPO1|$CPN|g" $SERVICEP/hyperion.service
sed -i "s|$CPO2|$CPN|g" $SERVICEP/hyperion.service
systemctl -q daemon-reload
elif [ $USE_SERVICE -eq 1 ]; then
sed -i "s|$BPO|$BPN|g" $SERVICEP/hyperion
sed -i "s|$CPO1|$CPN|g" $SERVICEP/hyperion
sed -i "s|$CPO2|$CPN|g" $SERVICEP/hyperion
update-rc.d hyperion defaults 98 02
fi
fi
# Select the appropriate download path
if [ $BETA -eq 1 ]; then
HYPERION_ADDRESS=https://sourceforge.net/projects/hyperion-project/files/beta
@ -191,34 +223,25 @@ if [ $OS_OPENELEC -eq 1 ]; then
curl -# -L --get $OE_DEPENDECIES | tar -C /storage/hyperion/bin -xz
#set the executen bit (failsave)
chmod +x -R /storage/hyperion/bin
# modify the default config to have a correct effect path
sed -i 's:/opt:/storage:g' /storage/hyperion/config/hyperion.config.json
# /storage/.config is available as samba share. A symbolic link would not be working
false | cp -i /storage/hyperion/config/hyperion.config.json /storage/.config/hyperion.config.json 2>/dev/null
else
wget -nv $HYPERION_RELEASE -O - | tar -C /opt -xz
#set the executen bit (failsave)
chmod +x -R /opt/hyperion/bin
BINSP=/usr/share/hyperion/bin
BINTP=/usr/bin
wget -nv $HYPERION_RELEASE -O - | tar -C /usr/share -xz
#set the executen bit (failsave) and move config to /etc/hyperion
chmod +x -R $BINSP
# create links to the binaries
ln -fs /opt/hyperion/bin/hyperiond /usr/bin/hyperiond
ln -fs /opt/hyperion/bin/hyperion-remote /usr/bin/hyperion-remote
ln -fs /opt/hyperion/bin/hyperion-v4l2 /usr/bin/hyperion-v4l2
ln -fs /opt/hyperion/bin/hyperion-dispmanx /usr/bin/hyperion-dispmanx 2>/dev/null
ln -fs /opt/hyperion/bin/hyperion-x11 /usr/bin/hyperion-x11 2>/dev/null
fi
# Restore backup of .conf files, if present
echo '---> Restore Hyperion configuration(s), if present'
if [ $OS_OPENELEC -eq 1 ]; then
mv -v /tmp/*.json /storage/.config/ 2>/dev/null
else mv -v /tmp/*.json /opt/hyperion/config/ 2>/dev/null
ln -fs $BINSP/hyperiond $BINTP/hyperiond
ln -fs $BINSP/hyperion-remote $BINTP/hyperion-remote
ln -fs $BINSP/hyperion-v4l2 $BINTP/hyperion-v4l2
ln -fs $BINSP/hyperion-dispmanx $BINTP/hyperion-dispmanx 2>/dev/null
ln -fs $BINSP/hyperion-x11 $BINTP/hyperion-x11 2>/dev/null
ln -fs $BINSP/hyperion-aml $BINTP/hyperion-aml 2>/dev/null
fi
# Copy the service control configuration to /etc/int (-n to respect user modified scripts)
# Copy the service control configuration to /etc/init (-n to respect user modified scripts)
if [ $USE_INITCTL -eq 1 ]; then
echo '---> Installing initctl script'
cp -n /opt/hyperion/init.d/hyperion.initctl.sh /etc/init/hyperion.conf 2>/dev/null
cp -n $SERVICEL/hyperion.initctl.sh $SERVICEP/hyperion.conf 2>/dev/null
initctl reload-configuration
elif [ $OS_OPENELEC -eq 1 ]; then
#modify all old installs with a logfile output
@ -239,34 +262,35 @@ elif [ $OS_OPENELEC -eq 1 ]; then
elif [ $USE_SYSTEMD -eq 1 ]; then
echo '---> Installing systemd script'
#place startup script for systemd and activate
#Problem with systemd to enable symlinks - Bug? Workaround cp -n (overwrite never)
#Bad workaround for Jessie (systemd) users that used the official script for install
update-rc.d -f hyperion remove 2>/dev/null
rm /etc/init.d/hyperion 2>/dev/null
cp -n /opt/hyperion/init.d/hyperion.systemd.sh /etc/systemd/system/hyperion.service
cp -n $SERVICEL/hyperion.systemd.sh $SERVICEP/hyperion.service
systemctl -q enable hyperion.service
if [ $OS_OSMC -eq 1 ]; then
echo '---> Modify systemd script for OSMC usage'
# Wait until kodi is sarted (for kodi checker)
sed -i '/After = mediacenter.service/d' /etc/systemd/system/hyperion.service
sed -i '/Unit/a After = mediacenter.service' /etc/systemd/system/hyperion.service
sed -i 's/User=osmc/User=root/g' /etc/systemd/system/hyperion.service
sed -i 's/Group=osmc/Group=root/g' /etc/systemd/system/hyperion.service
# Wait until kodi is sarted
sed -i '/After = mediacenter.service/d' $SERVICEP/hyperion.service
sed -i '/Unit/a After = mediacenter.service' $SERVICEP/hyperion.service
systemctl -q daemon-reload
fi
elif [ $USE_SERVICE -eq 1 ]; then
echo '---> Installing startup script in init.d'
# place startup script in init.d and add it to upstart (-s to respect user modified scripts)
ln -s /opt/hyperion/init.d/hyperion.init.sh /etc/init.d/hyperion 2>/dev/null
chmod +x /etc/init.d/hyperion
ln -s $SERVICEL/hyperion.init.sh $SERVICEP/hyperion 2>/dev/null && chmod +x $SERVICEP/hyperion
update-rc.d hyperion defaults 98 02
fi
#remove unwanted files/dirs
if [ $OS_OPENELEC -eq 1 ]; then
rm -r /storage/hyperion/services
else
rm -r /usr/share/hyperion/services
rm -r /opt/hyperion 2>/dev/null
fi
#chown the /config/ dir and all configs inside for hypercon config upload for non-root logins
if [ $OS_OSMC -eq 1 ]; then
chown -R osmc:osmc /opt/hyperion/config
chown -R osmc:osmc /etc/hyperion
elif [ $OS_RASPBIAN -eq 1 ]; then
chown -R pi:pi /opt/hyperion/config
chown -R pi:pi /etc/hyperion
fi
# Start the hyperion daemon
@ -313,4 +337,4 @@ if [ $CPU_RPI -eq 1 ] && [ $SPIOK -ne 1 ]; then
reboot
fi
exit 0
exit 0

View File

@ -6,15 +6,15 @@ PATH="/sbin:$PATH"
#Check if HyperCon is logged in as root
if [ $(id -u) != 0 ] && [ "$1" = "HyperConRemove" ]; then
echo '---> Critical Error: Please connect as user "root" through HyperCon'
echo '---> We need admin privileges to remove your Hyperion! -> abort'
exit 1
echo '---> Critical Error: Please connect as user "root" through HyperCon'
echo '---> We need admin privileges to remove your Hyperion! -> abort'
exit 1
fi
#Check, if script is running as root
if [ $(id -u) != 0 ]; then
echo '---> Critical Error: Please run the script as root (sudo sh ./remove_hyperion.sh)'
exit 1
echo '---> Critical Error: Please run the script as root (sudo sh ./remove_hyperion.sh)'
exit 1
fi
#Welcome message
@ -26,22 +26,23 @@ echo '**************************************************************************
#Skip the prompt if HyperCon Remove
if [ "$1" = "" ]; then
#Prompt for confirmation to proceed
while true
do
echo -n "---> Do you really want to remove Hyperion and it´s services? (y or n) :"
read CONFIRM
case $CONFIRM in
y|Y|YES|yes|Yes) break ;;
n|N|no|NO|No)
echo "---> Aborting - you entered \"$CONFIRM\""
exit
;;
*) echo "-> Please enter only y or n"
esac
done
echo "---> You entered \"$CONFIRM\". Remove Hyperion!"
#Prompt for confirmation to proceed
while true
do
echo -n "---> Do you really want to remove Hyperion and it´s services? (y or n) :"
read CONFIRM
case $CONFIRM in
y|Y|YES|yes|Yes) break ;;
n|N|no|NO|No)
echo "---> Aborting - you entered \"$CONFIRM\""
exit
;;
*) echo "-> Please enter only y or n"
esac
done
echo "---> You entered \"$CONFIRM\". Remove Hyperion!"
fi
# Find out if we are on OpenElec or RasPlex
OS_OPENELEC=`grep -m1 -c 'OpenELEC\|RasPlex\|LibreELEC' /etc/issue`
@ -63,10 +64,6 @@ elif [ $USE_SERVICE -eq 1 ]; then
/usr/sbin/service hyperion stop 2>/dev/null
elif [ $USE_SYSTEMD -eq 1 ]; then
service hyperion stop 2>/dev/null
# while [ $SERVICEC -le 20 ]; do
# service hyperion_fw$SERVICEC stop 2>/dev/null
# ((SERVICEC++))
# done
fi
#reset count
@ -86,19 +83,11 @@ elif [ $USE_SYSTEMD -eq 1 ]; then
# Delete and disable Hyperion systemd script
echo '---> Delete and disable Hyperion systemd script'
systemctl disable hyperion.service
# while [ $SERVICEC -le 20 ]; do
# systemctl -q disable hyperion_fw$SERVICEC.service 2>/dev/null
# ((SERVICEC++))
# done
rm -v /etc/systemd/system/hyperion* 2>/dev/null
elif [ $USE_SERVICE -eq 1 ]; then
# Delete and disable Hyperion init.d script
echo '---> Delete and disable Hyperion init.d script'
update-rc.d -f hyperion remove
# while [ $SERVICEC -le 20 ]; do
# update-rc.d -f hyperion_fw$SERVICEC remove 2>/dev/null
# ((SERVICEC++))
# done
rm /etc/init.d/hyperion* 2>/dev/null
fi
@ -116,9 +105,12 @@ else
rm -v /usr/bin/hyperion-v4l2 2>/dev/null
rm -v /usr/bin/hyperion-dispmanx 2>/dev/null
rm -v /usr/bin/hyperion-x11 2>/dev/null
rm -v /usr/bin/hyperion-aml 2>/dev/null
rm -v /etc/hyperion.config.json 2>/dev/null
echo "---> Remove binaries"
rm -rv /opt/hyperion 2>/dev/null
rm -rv /etc/hyperion 2>/dev/null
rm -rv /usr/share/hyperion 2>/dev/null
fi
echo '*******************************************************************************'
echo 'Hyperion successful removed!'

View File

@ -0,0 +1,165 @@
#!/bin/bash
# Script to add a second or more hyperion instance(s) to the corresponding system service
# Make sure /sbin is on the path (for service to find sub scripts)
PATH="/sbin:$PATH"
#Check, if script is running as root
if [ $(id -u) != 0 ]; then
echo '---> Critical Error: Please run the script as root (sudo sh ./setup_hyperion_forward.sh) -> abort'
exit 1
fi
#Welcome message
echo '*******************************************************************************'
echo 'This setup script will duplicate the hyperion service'
echo 'Choose the name(s) for one or more config files - one service for each config'
echo 'Created by brindosch - hyperion-project.org - the official Hyperion source.'
echo '*******************************************************************************'
#Prompt for confirmation to proceed
while true
do
echo -n "---> Do you really want to proceed? (y or n) :"
read CONFIRM
case $CONFIRM in
y|Y|YES|yes|Yes) break ;;
n|N|no|NO|No)
echo "---> Aborting - you entered \"$CONFIRM\""
exit
;;
*) echo "-> Please enter only y or n"
esac
done
echo "---> You entered \"$CONFIRM\". We will proceed!"
echo ""
#Check which system we are on
OS_OPENELEC=`grep -m1 -c 'OpenELEC\|RasPlex\|LibreELEC' /etc/issue`
USE_SYSTEMD=`grep -m1 -c systemd /proc/1/comm`
USE_INITCTL=`which /sbin/initctl | wc -l`
USE_SERVICE=`which /usr/sbin/service | wc -l`
#Setting up the paths to service files
if [ $USE_INITCTL -eq 1 ]; then
SERVICEPATH=/etc/init
elif [ $OS_OPENELEC -eq 1 ]; then
SERVICEPATH=/storage/.config
elif [ $USE_SYSTEMD -eq 1 ]; then
SERVICEPATH=/etc/systemd/system
elif [ $USE_SERVICE -eq 1 ]; then
SERVICEPATH/etc/init.d
fi
#Setting up the default PROTO/JSON ports
JSONPORT=19444
PROTOPORT=19445
# and service count
SERVICEC=1
#Setting up the paths to config files
if [ $OS_OPENELEC -eq 1 ]; then
CONFIGPATH=/storage/.config
else CONFIGPATH=/opt/hyperion/config
fi
#Ask the user for some informations regarding the setup
echo "---> Please enter the config name(s) you want to create"
echo "---> Information: One name creates one service and two names two services etc"
echo '---> Please enter them seperated with a space in a one line row!'
echo '---> example: hyperion.philipshue_1.json hyperion.AtmoOrb_2.json hypthreeconf.json'
echo '---> In any case, add ".json" at the end of each file name'
read -p 'Config file name(s): ' FILENAMES
echo '---> Thank you, we will modify your Hyperion installation now'
sleep 2
#Processing input
set $FILENAMES
FWCOUNT=${#}
#Convert all old config file paths to make sure this script is working (default for new installs with 1.02.0 and higher)
if [ $USE_INITCTL -eq 1 ]; then
sed -i "s|/etc/hyperion.config.json|/etc/hyperion/hyperion.config.json|g" $SERVICEPATH/hyperion.conf
elif [ $OS_OPENELEC -eq 1 ]; then
sleep 0
elif [ $USE_SYSTEMD -eq 1 ]; then
sed -i "s|/etc/hyperion.config.json|/etc/hyperion/hyperion.config.json|g" $SERVICEPATH/hyperion.service
elif [ $USE_SERVICE -eq 1 ]; then
sed -i "s|/etc/hyperion.config.json|/etc/hyperion/hyperion.config.json|g" $SERVICEPATH/hyperion
fi
#Processing service files
if [ $USE_INITCTL -eq 1 ]; then
echo "---> Initctl detected, processing service files"
while [ $SERVICEC -le $FWCOUNT ]; do
echo "Processing service ${SERVICEC}: \"hyperion_fw${SERVICEC}.conf\""
if [ -e "${SERVICEPATH}/hyperion_fw${SERVICEC}.conf" ]; then
echo "Service was already created - skipped"
echo "Input \"${1}\" was skipped"
else
echo "Create ${SERVICEPATH}/hyperion_fw${SERVICEC}.conf"
cp -s $SERVICEPATH/hyperion.conf $SERVICEPATH/hyperion_fw$SERVICEC.conf
echo "Config name changed to \"${1}\" inside \"hyperion_fw${SERVICEC}.conf\""
sed -i "s/hyperion.config.json/$1/g" $SERVICEPATH/hyperion_fw$SERVICEC.conf
initctl reload-configuration
fi
shift
SERVICEC=$((SERVICEC + 1))
done
elif [ $OS_OPENELEC -eq 1 ]; then
echo "---> OE/LE detected, processing autostart.sh"
while [ $SERVICEC -le $FWCOUNT ]; do
echo "${SERVICEC}. processing OE autostart.sh entry \"${1}\""
OE=`grep -m1 -c ${1} $SERVICEPATH/autostart.sh`
if [ $OE -eq 0 ]; then
echo "Add config name \"${1}\" to \"autostart.sh\""
echo "/storage/hyperion/bin/hyperiond.sh /storage/.config/${1} > /storage/logfiles/hyperion_fw${SERVICEC}.log 2>&1 &" >> /storage/.config/autostart.sh
else
echo "\"${1}\" was already added - skipped"
fi
shift
SERVICEC=$((SERVICEC + 1))
done
elif [ $USE_SYSTEMD -eq 1 ]; then
echo "---> Systemd detected, processing service files"
while [ $SERVICEC -le $FWCOUNT ]; do
echo "Processing service ${SERVICEC}: \"hyperion_fw${SERVICEC}.service\""
if [ -e "${SERVICEPATH}/hyperion_fw${SERVICEC}.service" ]; then
echo "Service was already created - skipped"
echo "Input \"${1}\" was skipped"
else
echo "Create ${SERVICEPATH}/hyperion_fw${SERVICEC}.service"
cp -s $SERVICEPATH/hyperion.service $SERVICEPATH/hyperion_fw$SERVICEC.service
echo "Config name changed to \"${1}\" inside \"hyperion_fw${SERVICEC}.service\""
sed -i "s/hyperion.config.json/$1/g" $SERVICEPATH/hyperion_fw$SERVICEC.service
systemctl -q enable hyperion_fw$SERVICEC.service
fi
shift
SERVICEC=$((SERVICEC + 1))
done
elif [ $USE_SERVICE -eq 1 ]; then
echo "---> Init.d detected, processing service files"
while [ $SERVICEC -le $FWCOUNT ]; do
echo "Processing service ${SERVICEC}: \"hyperion_fw${SERVICEC}\""
if [ -e "${SERVICEPATH}/hyperion_fw${SERVICEC}" ]; then
echo "Service was already created - skipped"
echo "Input \"${1}\" was skipped"
else
echo "Create ${SERVICEPATH}/hyperion_fw${SERVICEC}"
cp -s $SERVICEPATH/hyperion $SERVICEPATH/hyperion_fw$SERVICEC
echo "Config name changed to \"${1}\" inside \"hyperion_fw${SERVICEC}\""
sed -i "s/hyperion.config.json/$1/g" $SERVICEPATH/hyperion_fw$SERVICEC
update-rc.d hyperion_fw$SERVICEC defaults 98 02
fi
shift
SERVICEC=$((SERVICEC + 1))
done
fi
#Service creation done
echo '*******************************************************************************'
echo 'Script done all actions - all input processed'
echo 'Now upload your configuration(s) with HyperCon at the SSH Tab'
echo 'All created Hyperion services will start with your chosen confignames'
echo 'Wiki: wiki.hyperion-project.org Webpage: www.hyperion-project.org'
echo '*******************************************************************************'

View File

@ -13,7 +13,7 @@
### END INIT INFO
DAEMON=hyperiond
DAEMONOPTS="/opt/hyperion/config/hyperion.config.json"
DAEMONOPTS="/etc/hyperion/hyperion.config.json"
DAEMON_PATH="/usr/bin"
NAME=$DAEMON

View File

@ -8,4 +8,4 @@ stop on (runlevel [!2345])
respawn
exec /usr/bin/hyperiond /opt/hyperion/config/hyperion.config.json
exec /usr/bin/hyperiond /etc/hyperion/hyperion.config.json

View File

@ -6,7 +6,7 @@ Type=simple
User=root
Group=root
UMask=007
ExecStart=/opt/hyperion/bin/hyperiond /opt/hyperion/config/hyperion.config.json
ExecStart=/usr/bin/hyperiond /etc/hyperion/hyperion.config.json
ExecReload=/bin/kill -HUP $MAINPID
Restart=on-failure
TimeoutStopSec=10

View File

@ -8,16 +8,16 @@
#
FIND_PATH(BCM_INCLUDE_DIR
bcm_host.h
/usr/include
/usr/local/include
/opt/vc/include)
bcm_host.h
/usr/include
/usr/local/include
/opt/vc/include)
SET(BCM_INCLUDE_DIRS
${BCM_INCLUDE_DIR}
${BCM_INCLUDE_DIR}/interface/vcos/pthreads
${BCM_INCLUDE_DIR}/interface/vmcs_host/linux)
${BCM_INCLUDE_DIR}
${BCM_INCLUDE_DIR}/interface/vcos/pthreads
${BCM_INCLUDE_DIR}/interface/vmcs_host/linux)
FIND_LIBRARY(BCM_LIBRARIES
NAMES bcm_host
PATHS /usr/lib /usr/local/lib /opt/vc/lib)
NAMES bcm_host
PATHS /usr/lib /usr/local/lib /opt/vc/lib)

View File

@ -17,5 +17,5 @@ if(APPLE)
set(CoreFoundation_FOUND true)
set(CoreFoundation_INCLUDE_DIR ${CoreFoundation})
set(CoreFoundation_LIBRARY ${CoreFoundation})
endif(CoreFoundation)
endif(APPLE)
endif()
endif()

View File

@ -13,9 +13,9 @@ set(IOKit_LIBRARY)
if(APPLE)
# The only platform it makes sense to check for IOKit
find_library(IOKit IOKit)
if(IOKit)
set(IOKit_FOUND true)
if(IOKit)
set(IOKit_FOUND true)
set(IOKit_INCLUDE_DIR ${IOKit})
set(IOKit_LIBRARY ${IOKit})
endif(IOKit)
set(IOKit_LIBRARY ${IOKit})
endif(IOKit)
endif(APPLE)

View File

@ -10,44 +10,44 @@
#
FIND_PATH(
UDEV_INCLUDE_DIR
libudev.h
/usr/include
/usr/local/include
${UDEV_PATH_INCLUDES}
UDEV_INCLUDE_DIR
libudev.h
/usr/include
/usr/local/include
${UDEV_PATH_INCLUDES}
)
FIND_LIBRARY(
UDEV_LIBRARIES
NAMES udev libudev
PATHS
/usr/lib${LIB_SUFFIX}
/usr/local/lib${LIB_SUFFIX}
${UDEV_PATH_LIB}
UDEV_LIBRARIES
NAMES udev libudev
PATHS
/usr/lib${LIB_SUFFIX}
/usr/local/lib${LIB_SUFFIX}
${UDEV_PATH_LIB}
)
IF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
SET(UDEV_FOUND "YES")
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...
if (UDEV_STABLE)
set(UDEV_STABLE 0)
else (UDEV_STABLE)
set(UDEV_STABLE 1)
endif (UDEV_STABLE)
message(STATUS "libudev stable: ${UDEV_STABLE}")
ENDIF (UDEV_LIBRARIES AND UDEV_INCLUDE_DIR)
SET(UDEV_FOUND "YES")
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...
if (UDEV_STABLE)
set(UDEV_STABLE 0)
else ()
set(UDEV_STABLE 1)
endif ()
message(STATUS "libudev stable: ${UDEV_STABLE}")
ENDIF ()
IF (UDEV_FOUND)
MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}")
MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}")
ELSE (UDEV_FOUND)
MESSAGE(STATUS "UDev not found.")
MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include")
MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}")
MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib")
MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}")
IF (UDev_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find UDev library")
ENDIF (UDev_FIND_REQUIRED)
ENDIF (UDEV_FOUND)
MESSAGE(STATUS "Found UDev: ${UDEV_LIBRARIES}")
MESSAGE(STATUS " include: ${UDEV_INCLUDE_DIR}")
ELSE ()
MESSAGE(STATUS "UDev not found.")
MESSAGE(STATUS "UDev: You can specify includes: -DUDEV_PATH_INCLUDES=/opt/udev/include")
MESSAGE(STATUS " currently found includes: ${UDEV_INCLUDE_DIR}")
MESSAGE(STATUS "UDev: You can specify libs: -DUDEV_PATH_LIB=/opt/udev/lib")
MESSAGE(STATUS " currently found libs: ${UDEV_LIBRARIES}")
IF (UDev_FIND_REQUIRED)
MESSAGE(FATAL_ERROR "Could not find UDev library")
ENDIF ()
ENDIF ()

View File

@ -44,56 +44,52 @@
if (LIBUSB_1_LIBRARIES AND LIBUSB_1_INCLUDE_DIRS)
# in cache already
set(LIBUSB_FOUND TRUE)
# in cache already
set(LIBUSB_FOUND TRUE)
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
libusb.h
usb-1.0 usb
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
PATH_SUFFIXES
libusb-1.0
)
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
find_library(LIBUSB_1_LIBRARY
NAMES
usb-1.0 usb
PATHS
/usr/lib
/usr/local/lib
/opt/local/lib
/sw/lib
)
set(LIBUSB_1_INCLUDE_DIRS ${LIBUSB_1_INCLUDE_DIR} )
set(LIBUSB_1_LIBRARIES ${LIBUSB_1_LIBRARY} )
set(LIBUSB_1_INCLUDE_DIRS
${LIBUSB_1_INCLUDE_DIR}
)
set(LIBUSB_1_LIBRARIES
${LIBUSB_1_LIBRARY}
)
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
set(LIBUSB_1_FOUND TRUE)
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
if (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
set(LIBUSB_1_FOUND TRUE)
endif (LIBUSB_1_INCLUDE_DIRS AND LIBUSB_1_LIBRARIES)
if (LIBUSB_1_FOUND)
if (NOT libusb_1_FIND_QUIETLY)
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)
if (NOT libusb_1_FIND_QUIETLY)
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)
# 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)

View File

@ -0,0 +1,22 @@
if(NOT EXISTS "@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")
file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval
)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif(NOT "${rm_retval}" STREQUAL 0)
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
endforeach(file)

87
cmake/debian/postinst Normal file
View File

@ -0,0 +1,87 @@
#!/bin/sh
install_file()
{
src="$1"
dest="$2"
if [ -e "$dest" ] && ! cmp --quiet "$src" "$dest"
then
echo "INFO: $dest exists, new version copied to ${dest}.new"
cp "$src" "${dest}.new"
return 1
fi
cp "$src" "${dest}"
return 0
}
echo "--- hyperion ambilight postinstall ---"
echo "- install configuration template"
mkdir -p /etc/hyperion
install_file /usr/share/hyperion/config/hyperion.config.json /etc/hyperion/hyperion.config.json
HYPERION_RUNNING=false
pgrep hyperiond > /dev/null 2>&1 && HYPERION_RUNNING=true
start_msg=""
restart_msg=""
SERVICE_POSTFIX=""
if [ -e /sbin/initctl ]
then
echo "- init deamon: upstart"
# upstart
$HYPERION_RUNNING && initctl stop hyperion
install_file /usr/share/hyperion/service/hyperion.initctl.sh /etc/init/hyperion.conf || SERVICE_POSTFIX=".new"
initctl reload-configuration
start_msg="initctl start hyperion"
$HYPERION_RUNNING && initctl start hyperion
elif grep -m1 systemd /proc/1/comm > /dev/null
then
echo "- init deamon: systemd"
# systemd
$HYPERION_RUNNING && systemctl stop hyperion 2> /dev/null
install_file /usr/share/hyperion/service/hyperion.systemd.sh /etc/systemd/system/hyperion.service || SERVICE_POSTFIX=".new"
systemctl -q enable hyperion.service
start_msg="systemctl start hyperion"
$HYPERION_RUNNING && systemctl start hyperion
# if [ $OS_OSMC -eq 1 ]; then
# echo '---> Modify systemd script for OSMC usage'
# # Wait until kodi is sarted (for kodi checker)
# sed -i '/After = mediacenter.service/d' /etc/systemd/system/hyperion.service
# sed -i '/Unit/a After = mediacenter.service' /etc/systemd/system/hyperion.service
# sed -i 's/User=osmc/User=root/g' /etc/systemd/system/hyperion.service
# sed -i 's/Group=osmc/Group=root/g' /etc/systemd/system/hyperion.service
# systemctl -q daemon-reload
# fi
# systemctl start hyperion
else
echo "- init deamon: sysV"
# sysV
$HYPERION_RUNNING && service hyperion stop 2>/dev/null
install_file /usr/share/hyperion/service/hyperion.init.sh /etc/init.d/hyperion || SERVICE_POSTFIX=".new"
chmod +x /etc/init.d/hyperion
update-rc.d hyperion defaults 98 02
start_msg="service hyperion start"
$HYPERION_RUNNING && service hyperion start
fi
echo "-----------------------------------------------------------------------------"
echo "- hyperion is installed, please check your configuration in /etc/hyperion/ -"
echo "-----------------------------------------------------------------------------"
if [ -e /opt/hyperion/ ]
then
echo
echo "---------------------------------------------------------------------------------"
echo "- It seemd that you have an older version of hyperion installed in /opt/hyerion -"
echo "- please remove it and check your config to avoid problems -"
echo "---------------------------------------------------------------------------------"
fi

32
cmake/packages.cmake Normal file
View File

@ -0,0 +1,32 @@
# cmake file for generating distribution packages
SET ( CPACK_GENERATOR "DEB" "TGZ" "STGZ" ) # "RPM"
SET ( CPACK_PACKAGE_NAME "hyperion" )
SET ( CPACK_PACKAGE_DESCRIPTION_SUMMARY "Hyperion is an opensource 'AmbiLight' implementation" )
SET ( CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/README.md" )
SET ( CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" )
SET ( CPACK_DEBIAN_PACKAGE_MAINTAINER "hyperion team")
SET ( CPACK_DEBIAN_PACKAGE_NAME "hyperion" )
SET ( CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA "${CMAKE_CURRENT_SOURCE_DIR}/cmake/debian/postinst" )
SET ( CPACK_DEBIAN_PACKAGE_HOMEPAGE "https://github.com/hyperion-project/hyperion" )
SET ( CPACK_DEBIAN_PACKAGE_DEPENDS "libqtcore4 (>= 4:4.8.0), libqt4-network (>= 4:4.8.0), libusb-1.0-0, libpython2.7, libc6" )
SET ( CPACK_DEBIAN_PACKAGE_SECTION "Miscellaneous" )
SET ( CPACK_RPM_PACKAGE_NAME "hyperion" )
SET ( CPACK_RPM_PACKAGE_URL "https://github.com/hyperion-project/hyperion" )
SET ( CPACK_RPM_POST_INSTALL_SCRIPT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/rpm/postinst" )
SET(CPACK_PACKAGE_VERSION_MAJOR "1")
SET(CPACK_PACKAGE_VERSION_MINOR "3")
SET(CPACK_PACKAGE_VERSION_PATCH "0")
SET ( CPACK_COMPONENTS_ALL ambilight )
SET ( CPACK_ARCHIVE_COMPONENT_INSTALL ON )
SET ( CPACK_DEB_COMPONENT_INSTALL ON )
SET ( CPACK_RPM_COMPONENT_INSTALL ON )
SET ( CPACK_STRIP_FILES ON )
# no code after following line!
INCLUDE ( CPack )

View File

@ -202,7 +202,7 @@ macro (QT4_ADD_RESOURCES outfiles )
# let's make a configured file and add it as a dependency so cmake is run
# again when dependencies need to be recomputed.
QT4_MAKE_OUTPUT_FILE("${infile}" "" "qrc.depends" out_depends)
configure_file("${infile}" "${out_depends}" COPY_ONLY)
configure_file("${infile}" "${out_depends}" COPYONLY)
else()
# The .qrc file does not exist (yet). Let's add a dependency and hope
# that it will be generated later

57
cmake/rpm/postinst Normal file
View File

@ -0,0 +1,57 @@
#!/bin/sh
install_file()
{
src="$1"
dest="$2"
if [ -e "$dest" ] && ! cmp --quiet "$src" "$dest"
then
cp "$src" "${dest}.new"
else
cp "$src" "${dest}"
fi
}
echo "--- hyperion ambilight postinstall ---"
echo "- install configuration template"
mkdir -p /etc/hyperion
install_file /usr/share/hyperion/config/hyperion.config.json /etc/hyperion/hyperion.config.json
if grep -m1 systemd /proc/1/comm > /dev/null
then
# systemd
echo
systemctl stop hyperion 2> /dev/null
install_file /usr/share/hyperion/service/hyperion.systemd.sh /etc/systemd/system/hyperion.service
systemctl -q enable hyperion.service
# if [ $OS_OSMC -eq 1 ]; then
# echo '---> Modify systemd script for OSMC usage'
# # Wait until kodi is sarted (for kodi checker)
# sed -i '/After = mediacenter.service/d' /etc/systemd/system/hyperion.service
# sed -i '/Unit/a After = mediacenter.service' /etc/systemd/system/hyperion.service
# sed -i 's/User=osmc/User=root/g' /etc/systemd/system/hyperion.service
# sed -i 's/Group=osmc/Group=root/g' /etc/systemd/system/hyperion.service
# systemctl -q daemon-reload
# fi
systemctl start hyperion
elif [ -e /sbin/initctl ]
then
# upstart
install_file /usr/share/hyperion/service/hyperion.initctl.sh /etc/init/hyperion.conf
initctl reload-configuration
initctl start hyperion
else
# sysV
service hyperion stop 2>/dev/null
install_file /usr/share/hyperion/service/hyperion.init.sh /etc/init.d/hyperion
chmod +x /etc/init.d/hyperion
update-rc.d hyperion defaults 98 02
service hyperion start
fi
echo "- done"

View File

@ -1,12 +1,13 @@
// Automatically generated configuration file for 'Hyperion daemon'
// Generated by: HyperCon (The Hyperion deamon configuration file builder)
// Created with HyperCon V1.02.0 (30.04.2016)
// This is a example config (hyperion.config.json) with comments, in any case you need to create your own one with HyperCon!
// location of all configs: /etc/hyperion
// Webpage: https://www.hyperion-project.org
{
/// Device configuration contains the following fields:
/// * 'name' : The user friendly name of the device (only used for display purposes)
/// * 'type' : The type of the device or leds (known types for now are
/// ---------SPI---------, APA102, WS2801, P9813, LPD6803, LPD8806, ---------PWM---------, WS2812b (just RPi1), WS281X (RPi1, RPi2, RPi3), --------OTHER--------, PhilipsHUE, AtmoOrb, PiBlaster, Tinkerforge, FadeCandy, RawHID (USB), UDP, SEDU, TPM2, USBASP-WS2801, USBASP-WS2812, ------3rd PARTY------, Adalight, AdalightAPA102, AmbiLed, Atmo, Lightpack, Multi-Lightpack, Paintpack, Test (file), None)
/// APA102, WS2801, P9813, LPD6803, LPD8806, ---------PWM---------, WS2812b (just RPi1), WS281X (RPi1, RPi2, RPi3), --------OTHER--------, PhilipsHUE, AtmoOrb, PiBlaster, Tinkerforge, FadeCandy, RawHID (USB), UDP, SEDU, TPM2, USBASP-WS2801, USBASP-WS2812, ------3rd PARTY------, Adalight, AdalightAPA102, AmbiLed, Atmo, Lightpack, Multi-Lightpack, Paintpack, Test (file), None)
/// * [device type specific configuration]
/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.).
"device" :
@ -41,6 +42,7 @@
/// tuning parameters:
/// - 'saturationGain' The gain adjustement of the saturation
/// - 'luminanceGain' The gain adjustement of the luminance
/// - 'luminanceMinimum' The minimum luminance (backlight)
/// * 'red'/'green'/'blue' : The manipulation in the Red-Green-Blue color domain with the
/// following tuning parameters for each channel:
/// - 'threshold' The minimum required input value for the channel to be on
@ -102,7 +104,8 @@
"hsl" :
{
"saturationGain" : 1.0000,
"luminanceGain" : 1.0000
"luminanceGain" : 1.0000,
"luminanceMinimum" : 0.0000
},
"red" :
{
@ -178,11 +181,11 @@
/// * json : Json server adress and port of your target. Syntax:[IP:PORT] -> ["127.0.0.1:19446"] or more instances to forward ["127.0.0.1:19446","192.168.0.24:19448"]
/// HINT: If you redirect to "127.0.0.1" (localhost) you could start a second hyperion with another device/led config!
/// Be sure your client(s) is/are listening on the configured ports. The second Hyperion (if used) also needs to be configured! (HyperCon -> External -> Json Server/Proto Server)
// "forwarder" :
// {
// "proto" : ["127.0.0.1:19447"],
// "json" : ["127.0.0.1:19446"]
// },
"forwarder" :
{
"proto" : ["127.0.0.1:19447"],
"json" : ["127.0.0.1:19446"]
},
/// The configuration for the frame-grabber, contains the following items:
/// * width : The width of the grabbed frames [pixels]
@ -205,19 +208,21 @@
/// * grabPictures : Flag indicating that the frame-grabber is on(true) during picture show
/// * grabAudio : Flag indicating that the frame-grabber is on(true) during audio playback
/// * grabMenu : Flag indicating that the frame-grabber is on(true) at the Kodi menu
/// * grabPause : Flag indicating that the frame-grabber is on(true) at player state "pause"
/// * grabScreensaver : Flag indicating that the frame-grabber is on(true) when Kodi is on screensaver
/// * enable3DDetection : Flag indicating that the frame-grabber should switch to a 3D compatible modus if a 3D video is playing
// "xbmcVideoChecker" :
// {
// "xbmcAddress" : "127.0.0.1",
// "xbmcTcpPort" : 9090,
// "grabVideo" : true,
// "grabPictures" : true,
// "grabAudio" : true,
// "grabMenu" : false,
// "grabScreensaver" : true,
// "enable3DDetection" : true
// },
"xbmcVideoChecker" :
{
"xbmcAddress" : "127.0.0.1",
"xbmcTcpPort" : 9090,
"grabVideo" : true,
"grabPictures" : true,
"grabAudio" : true,
"grabMenu" : false,
"grabPause" : false,
"grabScreensaver" : true,
"enable3DDetection" : true
},
/// The configuration of the Json server which enables the json remote interface
/// * port : Port at which the json server is started
@ -236,11 +241,11 @@
/// The configuration of the boblight server which enables the boblight remote interface
/// * port : Port at which the boblight server is started
/// * priority: Priority of the boblight server (Default=900) HINT: lower value result in HIGHER priority!
// "boblightServer" :
// {
// "port" : 19333,
// "priority" : 900
// },
"boblightServer" :
{
"port" : 19333,
"priority" : 900
},
/// Configuration for the embedded V4L2 grabber
/// * device : V4L2 Device to use [default="/dev/video0"]
@ -259,25 +264,25 @@
/// * redSignalThreshold : Signal threshold for the red channel between 0.0 and 1.0 [default=0.0]
/// * greenSignalThreshold : Signal threshold for the green channel between 0.0 and 1.0 [default=0.0]
/// * blueSignalThreshold : Signal threshold for the blue channel between 0.0 and 1.0 [default=0.0]
// "grabber-v4l2" :
// {
// "device" : "/dev/video0",
// "input" : 0,
// "standard" : "no-change",
// "width" : -1,
// "height" : -1,
// "frameDecimation" : 2,
// "sizeDecimation" : 8,
// "priority" : 900,
// "mode" : "2D",
// "cropLeft" : 0,
// "cropRight" : 0,
// "cropTop" : 0,
// "cropBottom" : 0,
// "redSignalThreshold" : 0.0,
// "greenSignalThreshold" : 0.0,
// "blueSignalThreshold" : 0.0
// },
"grabber-v4l2" :
{
"device" : "/dev/video0",
"input" : 0,
"standard" : "no-change",
"width" : -1,
"height" : -1,
"frameDecimation" : 2,
"sizeDecimation" : 8,
"priority" : 900,
"mode" : "2D",
"cropLeft" : 0,
"cropRight" : 0,
"cropTop" : 0,
"cropBottom" : 0,
"redSignalThreshold" : 0.0,
"greenSignalThreshold" : 0.0,
"blueSignalThreshold" : 0.0
},
/// The configuration for each individual led. This contains the specification of the area
/// averaged of an input image for each led to determine its color. Each item in the list

View File

@ -1,430 +0,0 @@
// Automatically generated configuration file for 'Hyperion daemon'
// Generated by: HyperCon (The Hyperion deamon configuration file builder
{
/// Device configuration contains the following fields:
/// * 'name' : The user friendly name of the device (only used for display purposes)
/// * 'type' : The type of the device or leds (known types for now are 'ws2801', 'ldp8806',
/// 'lpd6803', 'sedu', 'adalight', 'lightpack', 'test' and 'none')
/// * 'output' : The output specification depends on selected device. This can for example be the
/// device specifier, device serial number, or the output file name
/// * 'rate' : The baudrate of the output to the device
/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.).
"device" :
{
"name" : "MyPi",
"type" : "adalight",
"output" : "/dev/ttyUSB0",
"rate" : 115200,
"colorOrder" : "rgb"
},
/// Color manipulation configuration used to tune the output colors to specific surroundings.
/// The configuration contains a list of color-transforms. Each transform contains the
/// following fields:
/// * 'id' : The unique identifier of the color transformation (eg 'device_1') /// * 'leds' : The indices (or index ranges) of the leds to which this color transform applies
/// (eg '0-5, 9, 11, 12-17'). The indices are zero based. /// * 'hsv' : The manipulation in the Hue-Saturation-Value color domain with the following
/// tuning parameters:
/// - 'saturationGain' The gain adjustement of the saturation
/// - 'valueGain' The gain adjustement of the value
/// * 'red'/'green'/'blue' : The manipulation in the Red-Green-Blue color domain with the
/// following tuning parameters for each channel:
/// - 'threshold' The minimum required input value for the channel to be on
/// (else zero)
/// - 'gamma' The gamma-curve correction factor
/// - 'blacklevel' The lowest possible value (when the channel is black)
/// - 'whitelevel' The highest possible value (when the channel is white)
///
/// Next to the list with color transforms there is also a smoothing option.
/// * 'smoothing' : Smoothing of the colors in the time-domain with the following tuning
/// parameters:
/// - 'type' The type of smoothing algorithm ('linear' or 'none')
/// - 'time_ms' The time constant for smoothing algorithm in milliseconds
/// - 'updateFrequency' The update frequency of the leds in Hz
"color" :
{
"transform" :
[
{
"id" : "default",
"leds" : "*",
"hsv" :
{
"saturationGain" : 1.0000,
"valueGain" : 1.0000
},
"red" :
{
"threshold" : 0.0000,
"gamma" : 1.0000,
"blacklevel" : 0.0000,
"whitelevel" : 1.0000
},
"green" :
{
"threshold" : 0.0000,
"gamma" : 1.0000,
"blacklevel" : 0.0000,
"whitelevel" : 1.0000
},
"blue" :
{
"threshold" : 0.0000,
"gamma" : 1.0000,
"blacklevel" : 0.0000,
"whitelevel" : 1.0000
}
}
],
"smoothing" :
{
"type" : "none",
"time_ms" : 200,
"updateFrequency" : 20.0000
}
},
/// The configuration for each individual led. This contains the specification of the area
/// averaged of an input image for each led to determine its color. Each item in the list
/// contains the following fields:
/// * index: The index of the led. This determines its location in the string of leds; zero
/// being the first led.
/// * hscan: The fractional part of the image along the horizontal used for the averaging
/// (minimum and maximum inclusive)
/// * vscan: The fractional part of the image along the vertical used for the averaging
/// (minimum and maximum inclusive)
"leds" :
[
{
"index" : 0,
"hscan" : { "minimum" : 0.4375, "maximum" : 0.5000 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 1,
"hscan" : { "minimum" : 0.3750, "maximum" : 0.4375 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 2,
"hscan" : { "minimum" : 0.3125, "maximum" : 0.3750 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 3,
"hscan" : { "minimum" : 0.2500, "maximum" : 0.3125 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 4,
"hscan" : { "minimum" : 0.1875, "maximum" : 0.2500 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 5,
"hscan" : { "minimum" : 0.1250, "maximum" : 0.1875 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 6,
"hscan" : { "minimum" : 0.0625, "maximum" : 0.1250 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 7,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0625 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 8,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 9,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.8571, "maximum" : 1.0000 }
},
{
"index" : 10,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.7143, "maximum" : 0.8571 }
},
{
"index" : 11,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.5714, "maximum" : 0.7143 }
},
{
"index" : 12,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.4286, "maximum" : 0.5714 }
},
{
"index" : 13,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.2857, "maximum" : 0.4286 }
},
{
"index" : 14,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.1429, "maximum" : 0.2857 }
},
{
"index" : 15,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.1429 }
},
{
"index" : 16,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0500 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 17,
"hscan" : { "minimum" : 0.0000, "maximum" : 0.0625 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 18,
"hscan" : { "minimum" : 0.0625, "maximum" : 0.1250 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 19,
"hscan" : { "minimum" : 0.1250, "maximum" : 0.1875 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 20,
"hscan" : { "minimum" : 0.1875, "maximum" : 0.2500 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 21,
"hscan" : { "minimum" : 0.2500, "maximum" : 0.3125 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 22,
"hscan" : { "minimum" : 0.3125, "maximum" : 0.3750 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 23,
"hscan" : { "minimum" : 0.3750, "maximum" : 0.4375 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 24,
"hscan" : { "minimum" : 0.4375, "maximum" : 0.5000 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 25,
"hscan" : { "minimum" : 0.5000, "maximum" : 0.5625 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 26,
"hscan" : { "minimum" : 0.5625, "maximum" : 0.6250 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 27,
"hscan" : { "minimum" : 0.6250, "maximum" : 0.6875 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 28,
"hscan" : { "minimum" : 0.6875, "maximum" : 0.7500 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 29,
"hscan" : { "minimum" : 0.7500, "maximum" : 0.8125 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 30,
"hscan" : { "minimum" : 0.8125, "maximum" : 0.8750 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 31,
"hscan" : { "minimum" : 0.8750, "maximum" : 0.9375 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 32,
"hscan" : { "minimum" : 0.9375, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 33,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.0800 }
},
{
"index" : 34,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.0000, "maximum" : 0.1429 }
},
{
"index" : 35,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.1429, "maximum" : 0.2857 }
},
{
"index" : 36,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.2857, "maximum" : 0.4286 }
},
{
"index" : 37,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.4286, "maximum" : 0.5714 }
},
{
"index" : 38,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.5714, "maximum" : 0.7143 }
},
{
"index" : 39,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.7143, "maximum" : 0.8571 }
},
{
"index" : 40,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.8571, "maximum" : 1.0000 }
},
{
"index" : 41,
"hscan" : { "minimum" : 0.9500, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 42,
"hscan" : { "minimum" : 0.9375, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 43,
"hscan" : { "minimum" : 0.8750, "maximum" : 0.9375 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 44,
"hscan" : { "minimum" : 0.8125, "maximum" : 0.8750 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 45,
"hscan" : { "minimum" : 0.7500, "maximum" : 0.8125 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 46,
"hscan" : { "minimum" : 0.6875, "maximum" : 0.7500 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 47,
"hscan" : { "minimum" : 0.6250, "maximum" : 0.6875 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 48,
"hscan" : { "minimum" : 0.5625, "maximum" : 0.6250 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
},
{
"index" : 49,
"hscan" : { "minimum" : 0.5000, "maximum" : 0.5625 },
"vscan" : { "minimum" : 0.9200, "maximum" : 1.0000 }
}
],
/// The black border configuration, contains the following items:
/// * enable : true if the detector should be activated
/// * threshold : Value below which a pixel is regarded as black (value between 0.0 and 1.0)
"blackborderdetector" :
{
"enable" : true,
"threshold" : 0.01
},
/// The configuration of the effect engine, contains the following items:
/// * paths : An array with absolute location(s) of directories with effects
/// * bootsequence : The effect selected as 'boot sequence'
"effects" :
{
"paths" :
[
"/home/dincs/projects/hyperion/effects"
]
},
"bootsequence" :
{
"effect" : "Rainbow swirl fast",
"duration_ms" : 3000
},
/// The configuration for the frame-grabber, contains the following items:
/// * width : The width of the grabbed frames [pixels]
/// * height : The height of the grabbed frames [pixels]
/// * frequency_Hz : The frequency of the frame grab [Hz]
// "framegrabber" :
// {
// "width" : 64,
// "height" : 64,
// "frequency_Hz" : 10.0
// },
/// The configuration of the XBMC connection used to enable and disable the frame-grabber. Contains the following fields:
/// * xbmcAddress : The IP address of the XBMC-host
/// * xbmcTcpPort : The TCP-port of the XBMC-server
/// * grabVideo : Flag indicating that the frame-grabber is on(true) during video playback
/// * grabPictures : Flag indicating that the frame-grabber is on(true) during picture show
/// * grabAudio : Flag indicating that the frame-grabber is on(true) during audio playback
/// * grabMenu : Flag indicating that the frame-grabber is on(true) in the XBMC menu
/// * grabScreensaver : Flag indicating that the frame-grabber is on(true) when XBMC is on screensaver
/// * enable3DDetection : Flag indicating that the frame-grabber should switch to a 3D compatible modus if a 3D video is playing
// "xbmcVideoChecker" :
// {
// "xbmcAddress" : "127.0.0.1",
// "xbmcTcpPort" : 9090,
// "grabVideo" : true,
// "grabPictures" : true,
// "grabAudio" : true,
// "grabMenu" : false,
// "grabScreensaver" : true,
// "enable3DDetection" : true
// },
/// The configuration of the Json server which enables the json remote interface
/// * port : Port at which the json server is started
"jsonServer" :
{
"port" : 19444
},
/// The configuration of the Proto server which enables the protobuffer remote interface
/// * port : Port at which the protobuffer server is started
"protoServer" :
{
"port" : 19445
},
/// The configuration of the boblight server which enables the boblight remote interface
/// * port : Port at which the boblight server is started
// "boblightServer" :
// {
// "port" : 19333
// },
"endOfJson" : "endOfJson"
}

View File

@ -1,110 +1,108 @@
add_subdirectory(build/getoptPlusPlus)
add_subdirectory(build/hidapi)
add_subdirectory(build/jsoncpp)
add_subdirectory(build/serial)
add_subdirectory(build/tinkerforge)
if(ENABLE_WS281XPWM)
add_library(ws281x
external/rpi_ws281x/mailbox.c external/rpi_ws281x/ws2811.c
external/rpi_ws281x/pwm.c external/rpi_ws281x/dma.c
external/rpi_ws281x/rpihw.c)
endif(ENABLE_WS281XPWM)
if(ENABLE_PROTOBUF)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared protobuf library")
add_subdirectory(external/protobuf)
if(CMAKE_CROSSCOMPILING)
# when crosscompiling import the protoc executable targets from a file generated by a native build
option(IMPORT_PROTOC "Protoc export file (protoc_export.cmake) from a native build" "IMPORT_PROTOC-FILE_NOT_FOUND")
include(${IMPORT_PROTOC})
else()
# export the protoc compiler so it can be used when cross compiling
export(TARGETS protoc_compiler FILE "${CMAKE_BINARY_DIR}/protoc_export.cmake")
endif()
# define the include for the protobuf library at the parent scope
set(PROTOBUF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/protobuf/src")
set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE)
# define the protoc executable at the parent scope
get_property(PROTOBUF_PROTOC_EXECUTABLE TARGET protoc_compiler PROPERTY LOCATION)
set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE} PARENT_SCOPE)
message(STATUS "Using protobuf compiler: " ${PROTOBUF_PROTOC_EXECUTABLE})
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2009-2011 Philip Lowman <philip@yhbt.com>
# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
return()
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
# Create an include path for each file specified
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
else()
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(DEFINED PROTOBUF_IMPORT_DIRS)
foreach(DIR ${PROTOBUF_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
endif()
if(CMAKE_CROSSCOMPILING)
set(PROTOC_DEPENDENCY ${PROTOBUF_PROTOC_EXECUTABLE})
else()
set(PROTOC_DEPENDENCY protoc_compiler)
endif()
set(${SRCS})
set(${HDRS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
DEPENDS ${ABS_FIL} ${PROTOC_DEPENDENCY}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM
)
endforeach()
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()
endif()
add_subdirectory(build/getoptPlusPlus)
add_subdirectory(build/hidapi)
add_subdirectory(build/jsoncpp)
add_subdirectory(build/serial)
add_subdirectory(build/tinkerforge)
if(ENABLE_WS281XPWM)
add_library(ws281x
external/rpi_ws281x/mailbox.c external/rpi_ws281x/ws2811.c
external/rpi_ws281x/pwm.c external/rpi_ws281x/dma.c
external/rpi_ws281x/rpihw.c)
endif(ENABLE_WS281XPWM)
set(BUILD_SHARED_LIBS OFF CACHE BOOL "Build shared protobuf library")
add_subdirectory(external/protobuf)
if(CMAKE_CROSSCOMPILING)
# when crosscompiling import the protoc executable targets from a file generated by a native build
option(IMPORT_PROTOC "Protoc export file (protoc_export.cmake) from a native build" "IMPORT_PROTOC-FILE_NOT_FOUND")
include(${IMPORT_PROTOC})
else()
# export the protoc compiler so it can be used when cross compiling
export(TARGETS protoc_compiler FILE "${CMAKE_BINARY_DIR}/protoc_export.cmake")
endif()
# define the include for the protobuf library at the parent scope
set(PROTOBUF_INCLUDE_DIRS "${CMAKE_CURRENT_SOURCE_DIR}/external/protobuf/src")
set(PROTOBUF_INCLUDE_DIRS ${PROTOBUF_INCLUDE_DIRS} PARENT_SCOPE)
# define the protoc executable at the parent scope
get_property(PROTOBUF_PROTOC_EXECUTABLE TARGET protoc_compiler PROPERTY LOCATION)
set(PROTOBUF_PROTOC_EXECUTABLE ${PROTOBUF_PROTOC_EXECUTABLE} PARENT_SCOPE)
message(STATUS "Using protobuf compiler: " ${PROTOBUF_PROTOC_EXECUTABLE})
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2009-2011 Philip Lowman <philip@yhbt.com>
# Copyright 2008 Esben Mose Hansen, Ange Optimization ApS
#
# Distributed under the OSI-approved BSD License (the "License");
# see accompanying file Copyright.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
# (To distribute this file outside of CMake, substitute the full
# License text for the above reference.)
function(PROTOBUF_GENERATE_CPP SRCS HDRS)
if(NOT ARGN)
message(SEND_ERROR "Error: PROTOBUF_GENERATE_CPP() called without any proto files")
return()
endif()
if(PROTOBUF_GENERATE_CPP_APPEND_PATH)
# Create an include path for each file specified
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(ABS_PATH ${ABS_FIL} PATH)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
else()
set(_protobuf_include_path -I ${CMAKE_CURRENT_SOURCE_DIR})
endif()
if(DEFINED PROTOBUF_IMPORT_DIRS)
foreach(DIR ${PROTOBUF_IMPORT_DIRS})
get_filename_component(ABS_PATH ${DIR} ABSOLUTE)
list(FIND _protobuf_include_path ${ABS_PATH} _contains_already)
if(${_contains_already} EQUAL -1)
list(APPEND _protobuf_include_path -I ${ABS_PATH})
endif()
endforeach()
endif()
if(CMAKE_CROSSCOMPILING)
set(PROTOC_DEPENDENCY ${PROTOBUF_PROTOC_EXECUTABLE})
else()
set(PROTOC_DEPENDENCY protoc_compiler)
endif()
set(${SRCS})
set(${HDRS})
foreach(FIL ${ARGN})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
list(APPEND ${SRCS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND ${HDRS} "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND ${PROTOBUF_PROTOC_EXECUTABLE}
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} ${_protobuf_include_path} ${ABS_FIL}
DEPENDS ${ABS_FIL} ${PROTOC_DEPENDENCY}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM
)
endforeach()
set_source_files_properties(${${SRCS}} ${${HDRS}} PROPERTIES GENERATED TRUE)
set(${SRCS} ${${SRCS}} PARENT_SCOPE)
set(${HDRS} ${${HDRS}} PARENT_SCOPE)
endfunction()

@ -1 +1 @@
Subproject commit e053bc9be127d1f4f0cffd10e7892cd32657ecf7
Subproject commit dfcf740848898b432fe3a3170417de60f81521ee

File diff suppressed because it is too large Load Diff

View File

@ -1,57 +0,0 @@
BACKGROUND
---------------------------------------------------------
The UDP led device type can be used to send LED data over UDP packets.
It was originally designed to support an ESP8266 Wifi module based WS2812
LED strip controller.
I've used this to support :
- A string of 600 LEDs as xmas decorations
The effects development kit is great for these scenarios
- a 61 LED collection of concentric circles
This has been used as a "night light" and a super lo-res
TV
In each of these cases, the hyperion-remote iOS app is a great way to
control the effects.
CONFIG
---------------------------------------------------------
Simple example for devices that support a raw binary protocol.
"device" :
{
"name" : "MyPi",
"type" : "udp",
"output" : "esp201-0.home:2391", "protocol" : 0,
"rate" : 1000000,
"colorOrder" : "grb"
},
If you are using an ESP8266/Arduino device with a long LED strip, you chould use this alternate protocol.
The ESP8266/Arduino doesnt support datagram re-assembly so will never see any udp packets greater than 1450.
"device" :
{
"name" : "MyPi",
"type" : "udp",
// "output" : "esp201-0.home:2392", "protocol" : 2, "maxpacket" : 1450,
"rate" : 1000000,
"colorOrder" : "rgb"
},
PROTOCOL
---------------------------------------------------------
Simple UDP packets are sent.
Packet Format protocol 0:
3 bytes per LED as R, G, B
Packet Format protocol 2:
0: update number & 0xf;
1: fragment of this update
2: 1st led# of this update - high byte
3: 1st led# of this update - low byte
4..n 3 bytes per LED as R, G, B

Binary file not shown.

View File

@ -1,165 +0,0 @@
// Automatically generated configuration file for 'Hyperion daemon'
// Generated by: HyperCon (The Hyperion deamon configuration file builder)
// Created with HyperCon V1.00.0 (11.03.2016)
{
/// Device configuration contains the following fields:
/// * 'name' : The user friendly name of the device (only used for display purposes)
/// * 'type' : The type of the device or leds (known types for now are
/// APA102, Adalight, AdalightAPA102, AmbiLed, Atmo, Hyperion-USBASP-WS2801, Hyperion-USBASP-WS2812, Lightberry, Lightpack, LPD6803, LPD8806, Multi-Lightpack, P9813, Paintpack, PhilipsHUE, PiBlaster, SEDU, Test, ThinkerForge, TPM2, WS2801, WS2812b, None)
/// * [device type specific configuration]
/// * 'colorOrder' : The order of the color bytes ('rgb', 'rbg', 'bgr', etc.).
///
/// * 'Specific for AtmoOrb:
/// * 'transitiontime' : Set the time of transition between color of Orb (not implemented)
/// * 'port' : Multicast UDP port
/// * 'numLeds' : Number of leds in Orb
/// * 'orbIds' : The Orb ids to use
/// * 'switchOffOnBlack': Define if Orb is to switch off when black is detected
"device" :
{
"name" : "MyPi",
"type" : "atmoorb",
"output" : "239.15.18.2",
"transitiontime" : 0,
"port" : 49692,
"numLeds" : 24,
"orbIds" : "1",
"switchOffOnBlack" : true,
"colorOrder" : "rgb"
},
/// Color manipulation configuration used to tune the output colors to specific surroundings.
/// The configuration contains a list of color-transforms. Each transform contains the
/// following fields:
/// * 'id' : The unique identifier of the color transformation (eg 'device_1') /// * 'leds' : The indices (or index ranges) of the leds to which this color transform applies
/// (eg '0-5, 9, 11, 12-17'). The indices are zero based. /// * 'hsv' : The manipulation in the Hue-Saturation-Value color domain with the following
/// tuning parameters:
/// - 'saturationGain' The gain adjustement of the saturation
/// - 'valueGain' The gain adjustement of the value
/// * 'red'/'green'/'blue' : The manipulation in the Red-Green-Blue color domain with the
/// following tuning parameters for each channel:
/// - 'threshold' The minimum required input value for the channel to be on
/// (else zero)
/// - 'gamma' The gamma-curve correction factor
/// - 'blacklevel' The lowest possible value (when the channel is black)
/// - 'whitelevel' The highest possible value (when the channel is white)
///
/// Next to the list with color transforms there is also a smoothing option.
/// * 'smoothing' : Smoothing of the colors in the time-domain with the following tuning
/// parameters:
/// - 'type' The type of smoothing algorithm ('linear' or 'none')
/// - 'time_ms' The time constant for smoothing algorithm in milliseconds
/// - 'updateFrequency' The update frequency of the leds in Hz
/// - 'updateDelay' The delay of the output to leds (in periods of smoothing)
"color" :
{
"transform" :
[
{
"id" : "default",
"leds" : "*",
"hsv" :
{
"saturationGain" : 1.0000,
"valueGain" : 1.0000
},
"red" :
{
"threshold" : 0.0000,
"gamma" : 2.2000,
"blacklevel" : 0.0000,
"whitelevel" : 1.0000
},
"green" :
{
"threshold" : 0.0000,
"gamma" : 2.2000,
"blacklevel" : 0.0000,
"whitelevel" : 1.0000
},
"blue" :
{
"threshold" : 0.0000,
"gamma" : 2.2000,
"blacklevel" : 0.0000,
"whitelevel" : 1.0000
}
}
],
"smoothing" :
{
"type" : "linear",
"time_ms" : 100,
"updateFrequency" : 60.0000,
"updateDelay" : 0
}
},
/// The black border configuration, contains the following items:
/// * enable : true if the detector should be activated
/// * threshold : Value below which a pixel is regarded as black (value between 0.0 and 1.0)
/// * unknownFrameCnt : Number of frames without any detection before the border is set to 0 (default 600)
/// * borderFrameCnt : Number of frames before a consistent detected border gets set (default 50)
/// * maxInconsistentCnt : Number of inconsistent frames that are ignored before a new border gets a chance to proof consistency
/// * blurRemoveCnt : Number of pixels that get removed from the detected border to cut away blur (default 1)
/// * mode : Border detection mode (values=default,classic,osd)
"blackborderdetector" :
{
"enable" : false,
"threshold" : 0.01,
"unknownFrameCnt" : 600,
"borderFrameCnt" : 50,
"maxInconsistentCnt" : 10,
"blurRemoveCnt" : 1,
"mode" : "default"
},
/// The configuration of the effect engine, contains the following items:
/// * paths : An array with absolute location(s) of directories with effects
/// * color : Set static color after boot -> set effect to "" (empty) and input the values [R,G,B] and set duration_ms NOT to 0 (use 1) instead
/// * effect : The effect selected as 'boot sequence'
/// * duration_ms : The duration of the selected effect (0=endless)
/// * priority : The priority of the selected effect/static color (default=990) HINT: lower value result in HIGHER priority!
"effects" :
{
"paths" :
[
"/opt/hyperion/effects"
]
},
/// The configuration of the Json server which enables the json remote interface
/// * port : Port at which the json server is started
"jsonServer" :
{
"port" : 19446
},
/// The configuration of the Proto server which enables the protobuffer remote interface
/// * port : Port at which the protobuffer server is started
"protoServer" :
{
"port" : 19447
},
/// The configuration for each individual led. This contains the specification of the area
/// averaged of an input image for each led to determine its color. Each item in the list
/// contains the following fields:
/// * index: The index of the led. This determines its location in the string of leds; zero
/// being the first led.
/// * hscan: The fractional part of the image along the horizontal used for the averaging
/// (minimum and maximum inclusive)
/// * vscan: The fractional part of the image along the vertical used for the averaging
/// (minimum and maximum inclusive)
"leds" :
[
{
"index" : 0,
"hscan" : { "minimum" : 0.0000, "maximum" : 1.0000 },
"vscan" : { "minimum" : 0.0000, "maximum" : 1.0000 }
}
],
"endOfJson" : "endOfJson"
}

Binary file not shown.

Binary file not shown.

View File

@ -1,79 +0,0 @@
Fadecandy: Open Pixel Control Protocol
======================================
The Fadecandy Server (`fcserver`) operates as a bridge between LED controllers attached over USB, and visual effects that communicate via a TCP socket.
The primary protocol supported by `fcserver` is [Open Pixel Control](http://openpixelcontrol.org), a super simple way to send RGB values over a socket. We support the standard Open Pixel Control commands, as well as some Fadecandy extensions.
Socket
------
Open Pixel Control uses a TCP socket, by default on port 7890. For the best performance, remember to set TCP_NODELAY socket option.
Command Format
--------------
All OPC commands follow the same general format. All multi-byte values in Open Pixel Control are in network byte order, high byte followed by low byte.
Channel | Command | Length (N) | Data
---------- | --------- | ---------- | --------------------------
1 byte | 1 byte | 2 bytes | N bytes of message data
Set Pixel Colors
----------------
Video data arrives in a **Set Pixel Colors** command:
Byte | **Set Pixel Colors** command
------ | --------------------------------
0 | Channel Number
1 | Command (0x00)
2 - 3 | Data length
4 | Pixel #0, Red
5 | Pixel #0, Green
6 | Pixel #0, Blue
7 | Pixel #1, Red
8 | Pixel #1, Green
9 | Pixel #1, Blue
… | …
As soon as a complete Set Pixel Colors command is received, a new frame of video will be broadcast simultaneously to all attached Fadecandy devices.
Set Global Color Correction
---------------------------
The color correction data (from the 'color' configuration key) can also be changed at runtime, by sending a new blob of JSON text in a Fadecandy-specific command. Fadecandy's 16-bit System ID for Open Pixel Control's System Exclusive (0xFF) command is **0x0001**.
Byte | **Set Global Color Correction** command
------ | ------------------------------------------
0 | Channel Number (0x00, reserved)
1 | Command (0xFF, System Exclusive)
2 - 3 | Data length (JSON Length + 4)
4 - 5 | System ID (0x0001, Fadecandy)
6 - 7 | SysEx ID (0x0001, Set Global Color Correction)
8 - … | JSON Text
Set Firmware Configuration
--------------------------
The firmware supports some runtime configuration options. Any OPC client can send a new firmware configuration packet using this command. If the supplied data is shorter than the firmware's configuration buffer, only the provided bytes will be changed.
Byte | **Set Firmware Configuration** command
------ | ------------------------------------------
0 | Channel Number (0x00, reserved)
1 | Command (0xFF, System Exclusive)
2 - 3 | Data length (Configuration Length + 4)
4 - 5 | System ID (0x0001, Fadecandy)
6 - 7 | SysEx ID (0x0002, Set Firmware Configuration)
8 - … | Configuration Data
Current firmwares support the following configuration options:
Byte Offset | Bits | Description
----------- | ------ | ------------
0 | 7 … 4 | (reserved)
0 | 3 | Manual LED control bit
0 | 2 | 0 = LED shows USB activity, 1 = LED under manual control
0 | 1 | Disable keyframe interpolation
0 | 0 | Disable dithering
1 … 62 | 7 … 0 | (reserved)

View File

@ -1,10 +1,10 @@
{
"name" : "Knight rider",
"script" : "knight-rider.py",
"args" :
{
"speed" : 1.0,
"fadeFactor" : 0.7,
"color" : [255,0,0]
}
}
{
"name" : "Knight rider",
"script" : "knight-rider.py",
"args" :
{
"speed" : 1.0,
"fadeFactor" : 0.7,
"color" : [255,0,0]
}
}

View File

@ -1,12 +1,12 @@
{
"name" : "Blue mood blobs",
"script" : "mood-blobs.py",
"args" :
{
"rotationTime" : 60.0,
"color" : [0,0,255],
"hueChange" : 60.0,
"blobs" : 5,
"reverse" : false
}
}
{
"name" : "Blue mood blobs",
"script" : "mood-blobs.py",
"args" :
{
"rotationTime" : 60.0,
"color" : [0,0,255],
"hueChange" : 60.0,
"blobs" : 5,
"reverse" : false
}
}

View File

@ -4,7 +4,7 @@
"args" :
{
"rotationTime" : 60.0,
"color" : [0,0,255],
"colorRandom" : true,
"hueChange" : 30.0,
"blobs" : 5,
"reverse" : false,

View File

@ -1,12 +1,12 @@
{
"name" : "Green mood blobs",
"script" : "mood-blobs.py",
"args" :
{
"rotationTime" : 60.0,
"color" : [0,255,0],
"hueChange" : 60.0,
"blobs" : 5,
"reverse" : false
}
}
{
"name" : "Green mood blobs",
"script" : "mood-blobs.py",
"args" :
{
"rotationTime" : 60.0,
"color" : [0,255,0],
"hueChange" : 60.0,
"blobs" : 5,
"reverse" : false
}
}

View File

@ -1,12 +1,12 @@
{
"name" : "Red mood blobs",
"script" : "mood-blobs.py",
"args" :
{
"rotationTime" : 60.0,
"color" : [255,0,0],
"hueChange" : 60.0,
"blobs" : 5,
"reverse" : false
}
}
{
"name" : "Red mood blobs",
"script" : "mood-blobs.py",
"args" :
{
"rotationTime" : 60.0,
"color" : [255,0,0],
"hueChange" : 60.0,
"blobs" : 5,
"reverse" : false
}
}

View File

@ -2,10 +2,12 @@ import hyperion
import time
import colorsys
import math
from random import random
# Get the parameters
rotationTime = float(hyperion.args.get('rotationTime', 20.0))
color = hyperion.args.get('color', (0,0,255))
colorRandom = bool(hyperion.args.get('colorRandom', False))
hueChange = float(hyperion.args.get('hueChange', 60.0))
blobs = int(hyperion.args.get('blobs', 5))
reverse = bool(hyperion.args.get('reverse', False))
@ -34,6 +36,9 @@ baseColorChangeRate = max(0, baseColorChangeRate) # > 0
# Calculate the color data
baseHsv = colorsys.rgb_to_hsv(color[0]/255.0, color[1]/255.0, color[2]/255.0)
if colorRandom:
baseHsv = (random(), baseHsv[1], baseHsv[2])
colorData = bytearray()
for i in range(hyperion.ledCount):
hue = (baseHsv[0] + hueChange * math.sin(2*math.pi * i / hyperion.ledCount)) % 1.0

View File

@ -1,10 +1,10 @@
{
"name" : "Rainbow mood",
"script" : "rainbow-mood.py",
"args" :
{
"rotation-time" : 60.0,
"brightness" : 1.0,
"reverse" : false
}
}
{
"name" : "Rainbow mood",
"script" : "rainbow-mood.py",
"args" :
{
"rotation-time" : 60.0,
"brightness" : 1.0,
"reverse" : false
}
}

View File

@ -1,10 +1,10 @@
{
"name" : "Rainbow swirl fast",
"script" : "rainbow-swirl.py",
"args" :
{
"rotation-time" : 3.0,
"brightness" : 1.0,
"reverse" : false
}
}
{
"name" : "Rainbow swirl fast",
"script" : "rainbow-swirl.py",
"args" :
{
"rotation-time" : 3.0,
"brightness" : 1.0,
"reverse" : false
}
}

View File

@ -1,10 +1,10 @@
{
"name" : "Rainbow swirl",
"script" : "rainbow-swirl.py",
"args" :
{
"rotation-time" : 20.0,
"brightness" : 1.0,
"reverse" : false
}
}
{
"name" : "Rainbow swirl",
"script" : "rainbow-swirl.py",
"args" :
{
"rotation-time" : 20.0,
"brightness" : 1.0,
"reverse" : false
}
}

View File

@ -1,10 +1,10 @@
{
"name" : "Snake",
"script" : "snake.py",
"args" :
{
"rotation-time" : 12.0,
"color" : [255, 0, 0],
"percentage" : 10
}
}
{
"name" : "Snake",
"script" : "snake.py",
"args" :
{
"rotation-time" : 12.0,
"color" : [255, 0, 0],
"percentage" : 10
}
}

9
effects/udp-mcast.json Normal file
View File

@ -0,0 +1,9 @@
{
"name" : "UDP multicast listener",
"script" : "udp.py",
"args" :
{
"ListenPort" : 2801,
"ListenIP" : "239.255.28.01"
}
}

View File

@ -1,8 +1,8 @@
{
"name" : "UDP listener",
"script" : "udp.py",
"args" :
{
"udpPort" : 2391
}
}
{
"name" : "UDP listener",
"script" : "udp.py",
"args" :
{
"ListenPort" : 2391
}
}

View File

@ -3,17 +3,33 @@ import time
import colorsys
import socket
import errno
import struct
# Get the parameters
udpPort = int(hyperion.args.get('udpPort', 2812))
ListenPort = int(hyperion.args.get('ListenPort', 2801))
ListenIP = hyperion.args.get('ListenIP', "")
octets = ListenIP.split('.');
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
UDPSock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM, socket.IPPROTO_UDP)
UDPSock.setblocking(False)
listen_addr = ("",udpPort)
print "udp.py: bind socket port:",udpPort
listen_addr = (ListenIP,ListenPort)
UDPSock.bind(listen_addr)
if ListenIP == "":
print "udp.py: Listening on *.*.*.*:"+str(ListenPort)
else:
print "udp.py: Listening on "+ListenIP+":"+str(ListenPort)
if len(octets) == 4 and int(octets[0]) >= 224 and int(octets[0]) < 240:
print "ListenIP is a multicast address\n"
# Multicast handling
try:
mreq = struct.pack("4sl", socket.inet_aton(ListenIP), socket.INADDR_ANY)
UDPSock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
except socket.error:
print "ERROR enabling multicast\n"
hyperion.setColor(hyperion.ledCount * bytearray((int(0), int(0), int(0))) )
# Start the write data loop

60
include/bonjour/bonjourrecord.h Executable file
View File

@ -0,0 +1,60 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BONJOURRECORD_H
#define BONJOURRECORD_H
#include <QtCore/QMetaType>
#include <QtCore/QString>
class BonjourRecord
{
public:
BonjourRecord() {}
BonjourRecord(const QString &name, const QString &regType, const QString &domain)
: serviceName(name), registeredType(regType), replyDomain(domain)
{}
BonjourRecord(const char *name, const char *regType, const char *domain)
{
serviceName = QString::fromUtf8(name);
registeredType = QString::fromUtf8(regType);
replyDomain = QString::fromUtf8(domain);
}
QString serviceName;
QString registeredType;
QString replyDomain;
bool operator==(const BonjourRecord &other) const {
return serviceName == other.serviceName
&& registeredType == other.registeredType
&& replyDomain == other.replyDomain;
}
};
Q_DECLARE_METATYPE(BonjourRecord)
#endif // BONJOURRECORD_H

View File

@ -0,0 +1,66 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef BONJOURSERVICEREGISTER_H
#define BONJOURSERVICEREGISTER_H
#include <QtCore/QObject>
#include "bonjourrecord.h"
class QSocketNotifier;
#include <dns_sd.h>
class BonjourServiceRegister : public QObject
{
Q_OBJECT
public:
BonjourServiceRegister(QObject *parent = 0);
~BonjourServiceRegister();
void registerService(const BonjourRecord &record, quint16 servicePort);
inline BonjourRecord registeredRecord() const {return finalRecord; }
signals:
void error(DNSServiceErrorType error);
void serviceRegistered(const BonjourRecord &record);
private slots:
void bonjourSocketReadyRead();
private:
static void DNSSD_API bonjourRegisterService(DNSServiceRef sdRef, DNSServiceFlags,
DNSServiceErrorType errorCode, const char *name,
const char *regtype, const char *domain,
void *context);
DNSServiceRef dnssref;
QSocketNotifier *bonjourSocket;
BonjourRecord finalRecord;
};
#endif // BONJOURSERVICEREGISTER_H

View File

@ -41,6 +41,9 @@ public:
///
void setVideoMode(const VideoMode videoMode);
void setCropping(const unsigned cropLeft, const unsigned cropRight,
const unsigned cropTop, const unsigned cropBottom);
///
/// Captures a single snapshot of the display and writes the data to the given image. The
/// provided image should have the same dimensions as the configured values (_width and
@ -68,4 +71,17 @@ private:
const unsigned _width;
/// Height of the captured snapshot [pixels]
const unsigned _height;
// the selected VideoMode
VideoMode _videoMode;
// number of pixels to crop after capturing
unsigned _cropLeft, _cropRight, _cropTop, _cropBottom;
// temp buffer when capturing with unsupported pitch size or
// when we need to crop the image
ColorRgba* _captureBuffer;
// size of the capture buffer in Pixels
unsigned _captureBufferSize;
};

View File

@ -56,6 +56,9 @@ public slots:
///
void stop();
void setCropping(const unsigned cropLeft, const unsigned cropRight,
const unsigned cropTop, const unsigned cropBottom);
///
/// Set the grabbing mode
/// @param[in] mode The new grabbing mode

View File

@ -23,103 +23,103 @@
/// @see http://linuxtv.org/downloads/v4l-dvb-apis/capture-example.html
class V4L2Grabber : public QObject
{
Q_OBJECT
Q_OBJECT
public:
V4L2Grabber(const std::string & device,
int input,
VideoStandard videoStandard, PixelFormat pixelFormat,
int width,
int height,
int frameDecimation,
int horizontalPixelDecimation,
int verticalPixelDecimation);
virtual ~V4L2Grabber();
V4L2Grabber(const std::string & device,
int input,
VideoStandard videoStandard, PixelFormat pixelFormat,
int width,
int height,
int frameDecimation,
int horizontalPixelDecimation,
int verticalPixelDecimation);
virtual ~V4L2Grabber();
public slots:
void setCropping(int cropLeft,
int cropRight,
int cropTop,
int cropBottom);
void setCropping(int cropLeft,
int cropRight,
int cropTop,
int cropBottom);
void set3D(VideoMode mode);
void set3D(VideoMode mode);
void setSignalThreshold(double redSignalThreshold,
double greenSignalThreshold,
double blueSignalThreshold,
int noSignalCounterThreshold);
void setSignalThreshold(double redSignalThreshold,
double greenSignalThreshold,
double blueSignalThreshold,
int noSignalCounterThreshold);
void start();
void start();
void stop();
void stop();
signals:
void newFrame(const Image<ColorRgb> & image);
void newFrame(const Image<ColorRgb> & image);
private slots:
int read_frame();
int read_frame();
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:
enum io_method {
IO_METHOD_READ,
IO_METHOD_MMAP,
IO_METHOD_USERPTR
};
enum io_method {
IO_METHOD_READ,
IO_METHOD_MMAP,
IO_METHOD_USERPTR
};
struct buffer {
void *start;
size_t length;
};
struct buffer {
void *start;
size_t length;
};
private:
const std::string _deviceName;
const io_method _ioMethod;
int _fileDescriptor;
std::vector<buffer> _buffers;
const std::string _deviceName;
const io_method _ioMethod;
int _fileDescriptor;
std::vector<buffer> _buffers;
PixelFormat _pixelFormat;
int _width;
int _height;
int _lineLength;
int _frameByteSize;
int _frameDecimation;
int _noSignalCounterThreshold;
PixelFormat _pixelFormat;
int _width;
int _height;
int _lineLength;
int _frameByteSize;
int _frameDecimation;
int _noSignalCounterThreshold;
ColorRgb _noSignalThresholdColor;
ColorRgb _noSignalThresholdColor;
int _currentFrame;
int _noSignalCounter;
int _currentFrame;
int _noSignalCounter;
QSocketNotifier * _streamNotifier;
QSocketNotifier * _streamNotifier;
ImageResampler _imageResampler;
ImageResampler _imageResampler;
};

View File

@ -6,7 +6,6 @@
// X11 includes
#include <X11/Xlib.h>
#include <X11/extensions/Xrender.h>
#include <X11/extensions/XShm.h>
#include <sys/ipc.h>
@ -16,31 +15,43 @@ class X11Grabber
{
public:
X11Grabber(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();
int open();
///
/// Set the video mode (2D/3D)
/// @param[in] mode The new video mode
///
void setVideoMode(const VideoMode videoMode);
bool Setup();
Image<ColorRgb> & grab();
private:
ImageResampler _imageResampler;
int _cropLeft;
int _cropRight;
int _cropTop;
int _cropBottom;
XImage* _xImage;
XShmSegmentInfo _shminfo;
ImageResampler _imageResampler;
bool _useXGetImage, _XShmAvailable, _XShmPixmapAvailable, _XRenderAvailable;
int _cropLeft;
int _cropRight;
int _cropTop;
int _cropBottom;
XImage* _xImage;
XShmSegmentInfo _shminfo;
/// Reference to the X11 display (nullptr if not opened)
Display* _x11Display;
Window _window;
XWindowAttributes _windowAttr;
Pixmap _pixmap;
XRenderPictFormat* _srcFormat;
XRenderPictFormat* _dstFormat;
XRenderPictureAttributes _pictAttr;
Picture _srcPicture;
Picture _dstPicture;
unsigned _screenWidth;
unsigned _screenHeight;

View File

@ -78,7 +78,13 @@ public:
/// Returns the number of attached leds
///
unsigned getLedCount() const;
///
/// Returns the current priority
///
/// @return The current priority
///
int getCurrentPriority() const;
///
/// Returns a list of active priorities
///

View File

@ -5,6 +5,8 @@
// Utility includes
#include <utils/ColorRgb.h>
#include <utils/ColorRgbw.h>
#include <utils/RgbToRgbw.h>
///
/// Interface (pure virtual base class) for LedDevices.

View File

@ -13,6 +13,8 @@
// hyperion util
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
// jsoncpp includes
#include <message.pb.h>
@ -23,90 +25,105 @@
class ProtoConnection : public QObject
{
Q_OBJECT
Q_OBJECT
public:
///
/// Constructor
///
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
///
ProtoConnection(const std::string & address);
///
/// Constructor
///
/// @param address The address of the Hyperion server (for example "192.168.0.32:19444)
///
ProtoConnection(const std::string & address);
///
/// Destructor
///
~ProtoConnection();
///
/// Destructor
///
~ProtoConnection();
/// Do not read reply messages from Hyperion if set to true
void setSkipReply(bool skip);
/// Do not read reply messages from Hyperion if set to true
void setSkipReply(bool skip);
///
/// Set all leds to the specified color
///
/// @param color The color
/// @param priority The priority
/// @param duration The duration in milliseconds
///
void setColor(const ColorRgb & color, int priority, int duration = 1);
///
/// Set all leds to the specified color
///
/// @param color The color
/// @param priority The priority
/// @param duration The duration in milliseconds
///
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)
///
/// @param image The image
/// @param priority The priority
/// @param duration The duration in milliseconds
///
void setImage(const Image<ColorRgb> & image, int priority, int duration = -1);
///
/// Set the leds according to the given image (assume the image is stretched to the display size)
///
/// @param image The image
/// @param priority The priority
/// @param duration The duration in milliseconds
///
void setImage(const Image<ColorRgb> & image, int priority, int duration = -1);
///
/// Clear the given priority channel
///
/// @param priority The priority
///
void clear(int priority);
///
/// Clear the given priority channel
///
/// @param priority The priority
///
void clear(int priority);
///
/// Clear all priority channels
///
void clearAll();
///
/// Clear all priority channels
///
void clearAll();
///
/// Send a command message and receive its reply
///
/// @param message The message to send
///
void sendMessage(const proto::HyperionRequest & message);
///
/// Send a command message and receive its reply
///
/// @param message The message to send
///
void sendMessage(const proto::HyperionRequest & message);
private slots:
/// Try to connect to the Hyperion host
void connectToHost();
/// Try to connect to the Hyperion host
void connectToHost();
///
/// Slot called when new data has arrived
///
void readData();
signals:
///
/// XBMC Video Checker Message
///
void setGrabbingMode(const GrabbingMode mode);
void setVideoMode(const VideoMode videoMode);
private:
///
/// Parse a reply message
///
/// @param reply The received reply
///
/// @return true if the reply indicates success
///
bool parseReply(const proto::HyperionReply & reply);
///
/// Parse a reply message
///
/// @param reply The received reply
///
/// @return true if the reply indicates success
///
bool parseReply(const proto::HyperionReply & reply);
private:
/// The TCP-Socket with the connection to the server
QTcpSocket _socket;
/// The TCP-Socket with the connection to the server
QTcpSocket _socket;
/// Host address
QString _host;
/// Host address
QString _host;
/// Host port
uint16_t _port;
/// Host port
uint16_t _port;
/// Skip receiving reply messages from Hyperion if set
bool _skipReply;
/// Skip receiving reply messages from Hyperion if set
bool _skipReply;
QTimer _timer;
QAbstractSocket::SocketState _prevSocketState;
QTimer _timer;
QAbstractSocket::SocketState _prevSocketState;
/// The buffer used for reading data from the socket
QByteArray _receiveBuffer;
};

View File

@ -4,31 +4,40 @@
// hyperion includes
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
// hyperion proto includes
#include "protoserver/ProtoConnection.h"
/// This class handles callbacks from the V4L2 grabber
/// This class handles callbacks from the V4L2 and X11 grabber
class ProtoConnectionWrapper : public QObject
{
Q_OBJECT
Q_OBJECT
public:
ProtoConnectionWrapper(const std::string & address, int priority, int duration_ms, bool skipProtoReply);
virtual ~ProtoConnectionWrapper();
ProtoConnectionWrapper(const std::string & address, int priority, int duration_ms, bool skipProtoReply);
virtual ~ProtoConnectionWrapper();
signals:
///
/// Forwarding XBMC Video Checker Message
///
void setGrabbingMode(const GrabbingMode mode);
void setVideoMode(const VideoMode videoMode);
public slots:
/// Handle a single image
/// @param image The image to process
void receiveImage(const Image<ColorRgb> & image);
/// Handle a single image
/// @param image The image to process
void receiveImage(const Image<ColorRgb> & image);
private:
/// Priority for calls to Hyperion
const int _priority;
/// Priority for calls to Hyperion
const int _priority;
/// Duration for color calls to Hyperion
const int _duration_ms;
/// Duration for color calls to Hyperion
const int _duration_ms;
/// Hyperion proto connection object
ProtoConnection _connection;
/// Hyperion proto connection object
ProtoConnection _connection;
};

View File

@ -15,6 +15,8 @@
// hyperion includes
#include <utils/Image.h>
#include <utils/ColorRgb.h>
#include <utils/GrabbingMode.h>
#include <utils/VideoMode.h>
// forward decl
class ProtoClientConnection;
@ -50,6 +52,13 @@ public:
public slots:
void sendImageToProtoSlaves(int priority, const Image<ColorRgb> & image, int duration_ms);
signals:
///
/// Forwarding XBMC Checker
///
void grabbingMode(const GrabbingMode mode);
void videoMode(const VideoMode VideoMode);
private slots:
///
/// Slot which is called when a client tries to create a new connection

65
include/utils/ColorRgbw.h Normal file
View File

@ -0,0 +1,65 @@
#pragma once
// STL includes
#include <cstdint>
#include <iostream>
struct ColorRgbw;
///
/// Plain-Old-Data structure containing the red-green-blue color specification. Size of the
/// structure is exactly 3-bytes for easy writing to led-device
///
struct ColorRgbw
{
/// The red color channel
uint8_t red;
/// The green color channel
uint8_t green;
/// The blue color channel
uint8_t blue;
/// The white color channel
uint8_t white;
/// 'Black' RgbColor (0, 0, 0, 0)
static ColorRgbw BLACK;
/// 'Red' RgbColor (255, 0, 0, 0)
static ColorRgbw RED;
/// 'Green' RgbColor (0, 255, 0, 0)
static ColorRgbw GREEN;
/// 'Blue' RgbColor (0, 0, 255, 0)
static ColorRgbw BLUE;
/// 'Yellow' RgbColor (255, 255, 0, 0)
static ColorRgbw YELLOW;
/// 'White' RgbColor (0, 0, 0, 255)
static ColorRgbw WHITE;
};
/// Assert to ensure that the size of the structure is 'only' 4 bytes
static_assert(sizeof(ColorRgbw) == 4, "Incorrect size of ColorRgbw");
///
/// Stream operator to write ColorRgb to an outputstream (format "'{'[red]','[green]','[blue]'}'")
///
/// @param os The output stream
/// @param color The color to write
/// @return The output stream (with the color written to it)
///
inline std::ostream& operator<<(std::ostream& os, const ColorRgbw& color)
{
os << "{" << unsigned(color.red) << "," << unsigned(color.green) << "," << unsigned(color.blue) << "," << unsigned(color.white) << "}";
return os;
}
/// Compare operator to check if a color is 'smaller' than another color
inline bool operator<(const ColorRgbw & lhs, const ColorRgbw & rhs)
{
return (lhs.red < rhs.red) && (lhs.green < rhs.green) && (lhs.blue < rhs.blue) && (lhs.white < rhs.white);
}
/// Compare operator to check if a color is 'smaller' than or 'equal' to another color
inline bool operator<=(const ColorRgbw & lhs, const ColorRgbw & rhs)
{
return (lhs.red <= rhs.red) && (lhs.green <= rhs.green) && (lhs.blue <= rhs.blue) && (lhs.white < rhs.white);
}

View File

@ -9,6 +9,7 @@ enum GrabbingMode
GRABBINGMODE_OFF,
/** Frame grabbing during video */
GRABBINGMODE_VIDEO,
GRABBINGMODE_PAUSE,
GRABBINGMODE_PHOTO,
GRABBINGMODE_AUDIO,
GRABBINGMODE_MENU,

View File

@ -20,7 +20,7 @@ public:
/// @param saturationGain The used saturation gain
/// @param luminanceGain The used luminance gain
///
HslTransform(double saturationGain, double luminanceGain);
HslTransform(double saturationGain, double luminanceGain, double luminanceMinimum);
///
/// Destructor
@ -55,6 +55,20 @@ public:
///
double getLuminanceGain() const;
///
/// Updates the luminance minimum
///
/// @param luminanceMinimum New luminance minimum
///
void setLuminanceMinimum(double luminanceMinimum);
///
/// Returns the luminance minimum
///
/// @return The current luminance minimum
///
double getLuminanceMinimum() const;
///
/// Apply the transform the the given RGB values.
///
@ -97,4 +111,6 @@ private:
double _saturationGain;
/// The luminance gain
double _luminanceGain;
/// The luminance minimum
double _luminanceMinimum;
};

View File

@ -13,221 +13,221 @@ class Image
{
public:
typedef Pixel_T pixel_type;
typedef Pixel_T pixel_type;
///
/// Default constructor for an image
///
Image() :
_width(1),
_height(1),
_pixels(new Pixel_T[2]),
_endOfPixels(_pixels + 1)
{
memset(_pixels, 0, 2*sizeof(Pixel_T));
}
///
/// Default constructor for an image
///
Image() :
_width(1),
_height(1),
_pixels(new Pixel_T[2]),
_endOfPixels(_pixels + 1)
{
memset(_pixels, 0, 2*sizeof(Pixel_T));
}
///
/// Constructor for an image with specified width and height
///
/// @param width The width of the image
/// @param height The height of the image
///
Image(const unsigned width, const unsigned height) :
_width(width),
_height(height),
_pixels(new Pixel_T[width * height + 1]),
_endOfPixels(_pixels + width * height)
{
memset(_pixels, 0, (_width*_height+1)*sizeof(Pixel_T));
}
///
/// Constructor for an image with specified width and height
///
/// @param width The width of the image
/// @param height The height of the image
///
Image(const unsigned width, const unsigned height) :
_width(width),
_height(height),
_pixels(new Pixel_T[width * height + 1]),
_endOfPixels(_pixels + width * height)
{
memset(_pixels, 0, (_width*_height+1)*sizeof(Pixel_T));
}
///
/// Constructor for an image with specified width and height
///
/// @param width The width of the image
/// @param height The height of the image
/// @param background The color of the image
///
Image(const unsigned width, const unsigned height, const Pixel_T background) :
_width(width),
_height(height),
_pixels(new Pixel_T[width * height + 1]),
_endOfPixels(_pixels + width * height)
{
std::fill(_pixels, _endOfPixels, background);
}
///
/// Constructor for an image with specified width and height
///
/// @param width The width of the image
/// @param height The height of the image
/// @param background The color of the image
///
Image(const unsigned width, const unsigned height, const Pixel_T background) :
_width(width),
_height(height),
_pixels(new Pixel_T[width * height + 1]),
_endOfPixels(_pixels + width * height)
{
std::fill(_pixels, _endOfPixels, background);
}
///
/// Copy constructor for an image
///
Image(const Image & other) :
_width(other._width),
_height(other._height),
_pixels(new Pixel_T[other._width * other._height + 1]),
_endOfPixels(_pixels + other._width * other._height)
{
memcpy(_pixels, other._pixels, other._width * other._height * sizeof(Pixel_T));
}
///
/// Copy constructor for an image
///
Image(const Image & other) :
_width(other._width),
_height(other._height),
_pixels(new Pixel_T[other._width * other._height + 1]),
_endOfPixels(_pixels + other._width * other._height)
{
memcpy(_pixels, other._pixels, other._width * other._height * sizeof(Pixel_T));
}
///
/// Destructor
///
~Image()
{
delete[] _pixels;
}
///
/// Destructor
///
~Image()
{
delete[] _pixels;
}
///
/// Returns the width of the image
///
/// @return The width of the image
///
inline unsigned width() const
{
return _width;
}
///
/// Returns the width of the image
///
/// @return The width of the image
///
inline unsigned width() const
{
return _width;
}
///
/// Returns the height of the image
///
/// @return The height of the image
///
inline unsigned height() const
{
return _height;
}
///
/// Returns the height of the image
///
/// @return The height of the image
///
inline unsigned height() const
{
return _height;
}
uint8_t red(const unsigned pixel) const
{
return (_pixels + pixel)->red;
}
uint8_t red(const unsigned pixel) const
{
return (_pixels + pixel)->red;
}
uint8_t green(const unsigned pixel) const
{
return (_pixels + pixel)->green;
}
uint8_t green(const unsigned pixel) const
{
return (_pixels + pixel)->green;
}
uint8_t blue(const unsigned pixel) const
{
return (_pixels + pixel)->blue;
}
uint8_t blue(const unsigned pixel) const
{
return (_pixels + pixel)->blue;
}
///
/// Returns a const reference to a specified pixel in the image
///
/// @param x The x index
/// @param y The y index
///
/// @return const reference to specified pixel
///
const Pixel_T& operator()(const unsigned x, const unsigned y) const
{
return _pixels[toIndex(x,y)];
}
///
/// Returns a const reference to a specified pixel in the image
///
/// @param x The x index
/// @param y The y index
///
/// @return const reference to specified pixel
///
const Pixel_T& operator()(const unsigned x, const unsigned y) const
{
return _pixels[toIndex(x,y)];
}
///
/// Returns a reference to a specified pixel in the image
///
/// @param x The x index
/// @param y The y index
///
/// @return reference to specified pixel
///
Pixel_T& operator()(const unsigned x, const unsigned y)
{
return _pixels[toIndex(x,y)];
}
///
/// Returns a reference to a specified pixel in the image
///
/// @param x The x index
/// @param y The y index
///
/// @return reference to specified pixel
///
Pixel_T& operator()(const unsigned x, const unsigned y)
{
return _pixels[toIndex(x,y)];
}
/// Resize the image
/// @param width The width of the image
/// @param height The height of the image
void resize(const unsigned width, const unsigned height)
{
if ((width*height) > unsigned((_endOfPixels-_pixels)))
{
delete[] _pixels;
_pixels = new Pixel_T[width*height + 1];
_endOfPixels = _pixels + width*height;
}
/// Resize the image
/// @param width The width of the image
/// @param height The height of the image
void resize(const unsigned width, const unsigned height)
{
if ((width*height) > unsigned((_endOfPixels-_pixels)))
{
delete[] _pixels;
_pixels = new Pixel_T[width*height + 1];
_endOfPixels = _pixels + width*height;
}
_width = width;
_height = height;
}
_width = width;
_height = height;
}
///
/// Copies another image into this image. The images should have exactly the same size.
///
/// @param other The image to copy into this
///
void copy(const Image<Pixel_T>& other)
{
assert(other._width == _width);
assert(other._height == _height);
///
/// Copies another image into this image. The images should have exactly the same size.
///
/// @param other The image to copy into this
///
void copy(const Image<Pixel_T>& other)
{
assert(other._width == _width);
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
/// @return The memory pointer to the first pixel
///
Pixel_T* memptr()
{
return _pixels;
}
///
/// Returns a memory pointer to the first pixel in the image
/// @return The memory pointer to the first pixel
///
Pixel_T* memptr()
{
return _pixels;
}
///
/// Returns a const memory pointer to the first pixel in the image
/// @return The const memory pointer to the first pixel
///
const Pixel_T* memptr() const
{
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;
///
/// Returns a const memory pointer to the first pixel in the image
/// @return The const memory pointer to the first pixel
///
const Pixel_T* memptr() const
{
return _pixels;
}
for (unsigned idx=0; idx<imageSize; idx++)
{
const Pixel_T color = memptr()[idx];
image.memptr()[idx] = ColorRgb{color.red, color.green, color.blue};
}
}
///
/// 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];
image.memptr()[idx] = ColorRgb{color.red, color.green, color.blue};
}
}
private:
///
/// Translate x and y coordinate to index of the underlying vector
///
/// @param x The x index
/// @param y The y index
///
/// @return The index into the underlying data-vector
///
inline unsigned toIndex(const unsigned x, const unsigned y) const
{
return y*_width + x;
}
///
/// Translate x and y coordinate to index of the underlying vector
///
/// @param x The x index
/// @param y The y index
///
/// @return The index into the underlying data-vector
///
inline unsigned toIndex(const unsigned x, const unsigned y) const
{
return y*_width + x;
}
private:
/// The width of the image
unsigned _width;
/// The height of the image
unsigned _height;
/// The width of the image
unsigned _width;
/// The height of the image
unsigned _height;
/// The pixels of the image
Pixel_T* _pixels;
/// The pixels of the image
Pixel_T* _pixels;
/// Pointer to the last(extra) pixel
Pixel_T* _endOfPixels;
/// Pointer to the last(extra) pixel
Pixel_T* _endOfPixels;
};

View File

@ -8,22 +8,21 @@
class ImageResampler
{
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,
int cropRight,
int cropTop,
int cropBottom);
void setCropping(int cropLeft,
int cropRight,
int cropTop,
int cropBottom);
void set3D(VideoMode mode);
void set3D(VideoMode mode);
void processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat,
Image<ColorRgb> & outputImage) const;
void processImage(const uint8_t * data, int width, int height, int lineLength, PixelFormat pixelFormat, Image<ColorRgb> & outputImage) const;
private:
static inline uint8_t clamp(int x);

48
include/utils/Logger.h Normal file
View File

@ -0,0 +1,48 @@
#pragma once
#include <string>
#include <stdio.h>
#include <stdarg.h>
#include <map>
// standard log messages
//#define _FUNCNAME_ __PRETTY_FUNCTION__
#define _FUNCNAME_ __FUNCTION__
#define Debug(logger, ...) { (logger)->Message(Logger::DEBUG , __FILE__, _FUNCNAME_, __LINE__, __VA_ARGS__); }
#define Info(logger, ...) { (logger)->Message(Logger::INFO , __FILE__, _FUNCNAME_, __LINE__, __VA_ARGS__); }
#define Warning(logger, ...) { (logger)->Message(Logger::WARNING, __FILE__, _FUNCNAME_, __LINE__, __VA_ARGS__); }
#define Error(logger, ...) { (logger)->Message(Logger::ERROR , __FILE__, _FUNCNAME_, __LINE__, __VA_ARGS__); }
// conditional log messages
#define DebugIf(condition, logger, ...) { if (condition) {(logger)->Message(Logger::DEBUG , __FILE__, _FUNCNAME_, __LINE__, __VA_ARGS__);} }
#define InfoIf(condition, logger, ...) { if (condition) {(logger)->Message(Logger::INFO , __FILE__, _FUNCNAME_, __LINE__, __VA_ARGS__);} }
#define WarningIf(condition, logger, ...) { if (condition) {(logger)->Message(Logger::WARNING , __FILE__, _FUNCNAME_, __LINE__, __VA_ARGS__);} }
#define ErrorIf(condition, logger, ...) { if (condition) {(logger)->Message(Logger::ERROR , __FILE__, _FUNCNAME_, __LINE__, __VA_ARGS__);} }
// ================================================================
class Logger
{
public:
enum LogLevel { DEBUG=0, INFO=1,WARNING=2,ERROR=3 };
static Logger* getInstance(std::string name="", LogLevel minLevel=Logger::INFO);
void Message(LogLevel level, const char* sourceFile, const char* func, unsigned int line, const char* fmt, ...);
void setMinLevel(LogLevel level) { _minLevel = level; };
protected:
Logger( std::string name="", LogLevel minLevel=INFO);
~Logger();
private:
static std::map<std::string,Logger*> *LoggerMap;
std::string _name;
std::string _appname;
LogLevel _minLevel;
bool _syslogEnabled;
unsigned int _loggerId;
};

View File

@ -11,9 +11,9 @@ enum PixelFormat {
PIXELFORMAT_UYVY,
PIXELFORMAT_BGR16,
PIXELFORMAT_BGR24,
PIXELFORMAT_RGB32,
PIXELFORMAT_BGR32,
PIXELFORMAT_NO_CHANGE
PIXELFORMAT_RGB32,
PIXELFORMAT_BGR32,
PIXELFORMAT_NO_CHANGE
};
inline PixelFormat parsePixelFormat(std::string pixelFormat)
@ -29,22 +29,22 @@ inline PixelFormat parsePixelFormat(std::string pixelFormat)
{
return PIXELFORMAT_UYVY;
}
else if (pixelFormat == "bgr16")
{
return PIXELFORMAT_BGR16;
}
else if (pixelFormat == "bgr24")
{
return PIXELFORMAT_BGR24;
}
else if (pixelFormat == "rgb32")
{
return PIXELFORMAT_RGB32;
}
else if (pixelFormat == "bgr32")
{
return PIXELFORMAT_BGR32;
}
else if (pixelFormat == "bgr16")
{
return PIXELFORMAT_BGR16;
}
else if (pixelFormat == "bgr24")
{
return PIXELFORMAT_BGR24;
}
else if (pixelFormat == "rgb32")
{
return PIXELFORMAT_RGB32;
}
else if (pixelFormat == "bgr32")
{
return PIXELFORMAT_BGR32;
}
// return the default NO_CHANGE
return PIXELFORMAT_NO_CHANGE;

37
include/utils/Profiler.h Normal file
View File

@ -0,0 +1,37 @@
#include "utils/Logger.h"
#include <string>
#include <stdio.h>
#include <stdarg.h>
#include <time.h>
#include <map>
#ifndef ENABLE_PROFILER
#error "Profiler is not for productive code, enable it via cmake or remove header include"
#endif
// profiler
#define PROFILER_BLOCK_EXECUTION_TIME Profiler DEBUG_PROFILE__BLOCK__EXECUTION__TIME_messure_object(__FILE__, _FUNCNAME_, __LINE__ );
#define PROFILER_TIMER_START(stopWatchName) Profiler::TimerStart(stopWatchName, __FILE__, _FUNCNAME_, __LINE__);
#define PROFILER_TIMER_GET(stopWatchName) Profiler::TimerGetTime(stopWatchName, __FILE__, _FUNCNAME_, __LINE__);
#define PROFILER_TIMER_GET_IF(condition, stopWatchName) { if (condition) {Profiler::TimerGetTime(stopWatchName, __FILE__, _FUNCNAME_, __LINE__);} }
class Profiler
{
public:
Profiler(const char* sourceFile, const char* func, unsigned int line);
~Profiler();
static void TimerStart(const std::string stopWatchName, const char* sourceFile, const char* func, unsigned int line);
static void TimerGetTime(const std::string stopWatchName, const char* sourceFile, const char* func, unsigned int line);
private:
static void initLogger();
static Logger* _logger;
const char* _file;
const char* _func;
unsigned int _line;
unsigned int _blockId;
clock_t _startTime;
};

View File

@ -0,0 +1,4 @@
#include <utils/ColorRgb.h>
#include <utils/ColorRgbw.h>
void Rgb_to_Rgbw(ColorRgb input, ColorRgbw * output, std::string _whiteAlgorithm);

View File

@ -4,7 +4,7 @@
class Sleep : protected QThread {
public:
static inline void msleep(unsigned long msecs) {
QThread::msleep(msecs);
}
static inline void msleep(unsigned long msecs) {
QThread::msleep(msecs);
}
};

View File

@ -1,192 +1,192 @@
#pragma once
// stl includes
#include <string>
#include <list>
// jsoncpp includes
#include <json/json.h>
/// JsonSchemaChecker is a very basic implementation of json schema.
/// The json schema definition draft can be found at
/// http://tools.ietf.org/html/draft-zyp-json-schema-03
///
/// The following keywords are supported:
/// - type
/// - required
/// - properties
/// - items
/// - enum
/// - minimum
/// - maximum
/// - addtionalProperties
/// - minItems
/// - maxItems
///
/// And the non-standard:
/// - dependencies
class JsonSchemaChecker
{
public:
JsonSchemaChecker();
virtual ~JsonSchemaChecker();
///
/// @param schema The schema to use
/// @return true upon succes
///
bool setSchema(const Json::Value & schema);
///
/// @brief Validate a JSON structure
/// @param value The JSON value to check
/// @return true when the arguments is valid according to the schema
///
bool validate(const Json::Value & value);
///
/// @return A list of error messages
///
const std::list<std::string> & getMessages() const;
private:
///
/// Validates a json-value against a given schema. Results are stored in the members of this
/// class (_error & _messages)
///
/// @param[in] value The value to validate
/// @param[in] schema The schema against which the value is validated
///
void validate(const Json::Value &value, const Json::Value & schema);
///
/// Adds the given message to the message-queue (with reference to current line-number)
///
/// @param[in] message The message to add to the queue
///
void setMessage(const std::string & message);
///
/// Retrieves all references from the json-value as specified by the schema
///
/// @param[in] value The json-value
/// @param[in] schema The schema
///
void collectDependencies(const Json::Value & value, const Json::Value &schema);
private:
// attribute check functions
///
/// 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
///
/// @param[in] value The given value
/// @param[in] schema The specified type (as json-value)
///
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
/// correct format. If this is not the case _error is set to true and an error-message is added
/// to the message-queue.
///
/// @param[in] value The given json-object
/// @param[in] schema The schema of the json-object
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The given json-object
/// @param schema The schema for the json-object
/// @param ignoredProperties The properties that were ignored
///
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
/// to true and an error-message is added to the message-queue.
///
/// @param value The given json-object
/// @param schemaLink The schema of the json-object
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param[in] value The given value
/// @param[in] schema The minimum value (as json-value)
///
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
/// case _error is set to true and an error-message is added to the message-queue.
///
/// @param[in] value The given value
/// @param[in] schema The maximum value (as json-value)
///
void checkMaximum(const Json::Value & value, const Json::Value & schema);
///
/// Validates all the items of an array.
///
/// @param value The json-array
/// @param schema The schema for the items in the array
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The json-array
/// @param schema The minimum size specification (as json-value)
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The json-array
/// @param schema The maximum size specification (as json-value)
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The json-array
/// @param schema Bool to enable the check (as json-value)
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The enum value
/// @param schema The enum schema definition
///
void checkEnum(const Json::Value & value, const Json::Value & schema);
private:
/// The schema of the entire json-configuration
Json::Value _schema;
/// The current location into a json-configuration structure being checked
std::list<std::string> _currentPath;
/// The result messages collected during the schema verification
std::list<std::string> _messages;
/// Flag indicating an error occured during validation
bool _error;
/// A list with references (string => json-value)
std::map<std::string, const Json::Value *> _references; // ref 2 value
};
#pragma once
// stl includes
#include <string>
#include <list>
// jsoncpp includes
#include <json/json.h>
/// JsonSchemaChecker is a very basic implementation of json schema.
/// The json schema definition draft can be found at
/// http://tools.ietf.org/html/draft-zyp-json-schema-03
///
/// The following keywords are supported:
/// - type
/// - required
/// - properties
/// - items
/// - enum
/// - minimum
/// - maximum
/// - addtionalProperties
/// - minItems
/// - maxItems
///
/// And the non-standard:
/// - dependencies
class JsonSchemaChecker
{
public:
JsonSchemaChecker();
virtual ~JsonSchemaChecker();
///
/// @param schema The schema to use
/// @return true upon succes
///
bool setSchema(const Json::Value & schema);
///
/// @brief Validate a JSON structure
/// @param value The JSON value to check
/// @return true when the arguments is valid according to the schema
///
bool validate(const Json::Value & value);
///
/// @return A list of error messages
///
const std::list<std::string> & getMessages() const;
private:
///
/// Validates a json-value against a given schema. Results are stored in the members of this
/// class (_error & _messages)
///
/// @param[in] value The value to validate
/// @param[in] schema The schema against which the value is validated
///
void validate(const Json::Value &value, const Json::Value & schema);
///
/// Adds the given message to the message-queue (with reference to current line-number)
///
/// @param[in] message The message to add to the queue
///
void setMessage(const std::string & message);
///
/// Retrieves all references from the json-value as specified by the schema
///
/// @param[in] value The json-value
/// @param[in] schema The schema
///
void collectDependencies(const Json::Value & value, const Json::Value &schema);
private:
// attribute check functions
///
/// 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
///
/// @param[in] value The given value
/// @param[in] schema The specified type (as json-value)
///
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
/// correct format. If this is not the case _error is set to true and an error-message is added
/// to the message-queue.
///
/// @param[in] value The given json-object
/// @param[in] schema The schema of the json-object
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The given json-object
/// @param schema The schema for the json-object
/// @param ignoredProperties The properties that were ignored
///
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
/// to true and an error-message is added to the message-queue.
///
/// @param value The given json-object
/// @param schemaLink The schema of the json-object
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param[in] value The given value
/// @param[in] schema The minimum value (as json-value)
///
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
/// case _error is set to true and an error-message is added to the message-queue.
///
/// @param[in] value The given value
/// @param[in] schema The maximum value (as json-value)
///
void checkMaximum(const Json::Value & value, const Json::Value & schema);
///
/// Validates all the items of an array.
///
/// @param value The json-array
/// @param schema The schema for the items in the array
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The json-array
/// @param schema The minimum size specification (as json-value)
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The json-array
/// @param schema The maximum size specification (as json-value)
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The json-array
/// @param schema Bool to enable the check (as json-value)
///
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
/// _error is set to true and an error-message is added to the message-queue.
///
/// @param value The enum value
/// @param schema The enum schema definition
///
void checkEnum(const Json::Value & value, const Json::Value & schema);
private:
/// The schema of the entire json-configuration
Json::Value _schema;
/// The current location into a json-configuration structure being checked
std::list<std::string> _currentPath;
/// The result messages collected during the schema verification
std::list<std::string> _messages;
/// Flag indicating an error occured during validation
bool _error;
/// A list with references (string => json-value)
std::map<std::string, const Json::Value *> _references; // ref 2 value
};

View File

@ -41,7 +41,7 @@ public:
/// @param grabScreensaver Whether or not to grab when the XBMC screensaver is activated
/// @param enable3DDetection Wheter or not to enable the detection of 3D movies playing
///
XBMCVideoChecker(const std::string & address, uint16_t port, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu, bool grabScreensaver, bool enable3DDetection);
XBMCVideoChecker(const std::string & address, uint16_t port, bool grabVideo, bool grabPhoto, bool grabAudio, bool grabMenu, bool grabPause, bool grabScreensaver, bool enable3DDetection);
///
/// Start polling XBMC
@ -76,7 +76,7 @@ private:
void setGrabbingMode(GrabbingMode grabbingMode);
void setScreensaverMode(bool isOnScreensaver);
/// Set the video mode
void setVideoMode(VideoMode videoMode);
@ -117,6 +117,9 @@ private:
/// Flag indicating whether or not to grab when XBMC is playing nothing (in menu)
const bool _grabMenu;
/// Flag indicating whether or not to grab when the XBMC videoplayer is at pause state
const bool _grabPause;
/// Flag indicating whether or not to grab when the XBMC screensaver is activated
const bool _grabScreensaver;
@ -125,7 +128,7 @@ private:
/// Flag indicating if XBMC is on screensaver
bool _previousScreensaverMode;
/// Previous emitted grab mode
GrabbingMode _previousGrabbingMode;

View File

@ -7,9 +7,11 @@ add_subdirectory(hyperion)
add_subdirectory(blackborder)
add_subdirectory(jsonserver)
if (ENABLE_PROTOBUF)
add_subdirectory(protoserver)
endif (ENABLE_PROTOBUF)
add_subdirectory(protoserver)
if (ENABLE_ZEROCONF)
add_subdirectory(bonjour)
endif (ENABLE_ZEROCONF)
add_subdirectory(boblightserver)
add_subdirectory(leddevice)

View File

@ -1,23 +1,23 @@
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/blackborder)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/blackborder)
SET(Blackborder_HEADERS
${CURRENT_HEADER_DIR}/BlackBorderDetector.h
${CURRENT_HEADER_DIR}/BlackBorderProcessor.h
)
SET(Blackborder_SOURCES
${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp
)
add_library(blackborder
${Blackborder_HEADERS}
${Blackborder_SOURCES}
)
target_link_libraries(blackborder
hyperion-utils
)
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/blackborder)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/blackborder)
SET(Blackborder_HEADERS
${CURRENT_HEADER_DIR}/BlackBorderDetector.h
${CURRENT_HEADER_DIR}/BlackBorderProcessor.h
)
SET(Blackborder_SOURCES
${CURRENT_SOURCE_DIR}/BlackBorderDetector.cpp
${CURRENT_SOURCE_DIR}/BlackBorderProcessor.cpp
)
add_library(blackborder
${Blackborder_HEADERS}
${Blackborder_SOURCES}
)
target_link_libraries(blackborder
hyperion-utils
)

View File

@ -1,40 +1,40 @@
# Define the current source locations
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/boblightserver)
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/boblightserver)
# Group the headers that go through the MOC compiler
set(BoblightServer_QT_HEADERS
${CURRENT_HEADER_DIR}/BoblightServer.h
${CURRENT_SOURCE_DIR}/BoblightClientConnection.h
)
set(BoblightServer_HEADERS
)
set(BoblightServer_SOURCES
${CURRENT_SOURCE_DIR}/BoblightServer.cpp
${CURRENT_SOURCE_DIR}/BoblightClientConnection.cpp
)
if(ENABLE_QT5)
qt5_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS})
else(ENABLE_QT5)
qt4_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS})
endif(ENABLE_QT5)
add_library(boblightserver
${BoblightServer_HEADERS}
${BoblightServer_QT_HEADERS}
${BoblightServer_SOURCES}
${BoblightServer_HEADERS_MOC}
)
if(ENABLE_QT5)
qt5_use_modules(boblightserver Widgets)
endif(ENABLE_QT5)
target_link_libraries(boblightserver
hyperion
hyperion-utils
${QT_LIBRARIES})
# Define the current source locations
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/boblightserver)
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/boblightserver)
# Group the headers that go through the MOC compiler
set(BoblightServer_QT_HEADERS
${CURRENT_HEADER_DIR}/BoblightServer.h
${CURRENT_SOURCE_DIR}/BoblightClientConnection.h
)
set(BoblightServer_HEADERS
)
set(BoblightServer_SOURCES
${CURRENT_SOURCE_DIR}/BoblightServer.cpp
${CURRENT_SOURCE_DIR}/BoblightClientConnection.cpp
)
if(ENABLE_QT5)
qt5_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS})
else()
qt4_wrap_cpp(BoblightServer_HEADERS_MOC ${BoblightServer_QT_HEADERS})
endif()
add_library(boblightserver
${BoblightServer_HEADERS}
${BoblightServer_QT_HEADERS}
${BoblightServer_SOURCES}
${BoblightServer_HEADERS_MOC}
)
if(ENABLE_QT5)
qt5_use_modules(boblightserver Widgets)
endif()
target_link_libraries(boblightserver
hyperion
hyperion-utils
${QT_LIBRARIES})

View File

@ -0,0 +1,52 @@
# Define the current source locations
set(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/bonjour)
set(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/bonjour)
# Group the headers that go through the MOC compiler
set(Bonjour_QT_HEADERS
${CURRENT_HEADER_DIR}/bonjourrecord.h
${CURRENT_HEADER_DIR}/bonjourserviceregister.h
)
set(Bonjour_HEADERS
)
set(Bonjour_SOURCES
${CURRENT_SOURCE_DIR}/bonjourserviceregister.cpp
)
set(Bonjour_RESOURCES
)
if(ENABLE_QT5)
qt5_wrap_cpp(Bonjour_HEADERS_MOC ${Bonjour_QT_HEADERS})
qt5_add_resources(Bonjour_RESOURCES_RCC ${Bonjour_RESOURCES} OPTIONS "-no-compress")
else(ENABLE_QT5)
qt4_wrap_cpp(Bonjour_HEADERS_MOC ${Bonjour_QT_HEADERS})
qt4_add_resources(Bonjour_RESOURCES_RCC ${Bonjour_RESOURCES} OPTIONS "-no-compress")
endif(ENABLE_QT5)
add_library(bonjour
${Bonjour_HEADERS}
${Bonjour_QT_HEADERS}
${Bonjour_SOURCES}
${Bonjour_RESOURCES}
${Bonjour_HEADERS_MOC}
${Bonjour_RESOURCES_RCC}
)
if(ENABLE_QT5)
qt5_use_modules(bonjour Widgets Network)
endif(ENABLE_QT5)
target_link_libraries(bonjour
libdns_sd.a
libavahi-client.a
libavahi-common.a
libavahi-core.a
libavahi-qt4.a
libdbus-1.a
hyperion
hyperion-utils
${QT_LIBRARIES})

View File

@ -0,0 +1,102 @@
/*
Copyright (c) 2007, Trenton Schulz
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
//#include "bonjourserviceregister.h"
#include <bonjour/bonjourserviceregister.h>
#include <QtCore/QSocketNotifier>
BonjourServiceRegister::BonjourServiceRegister(QObject *parent)
: QObject(parent), dnssref(0), bonjourSocket(0)
{
}
BonjourServiceRegister::~BonjourServiceRegister()
{
if (dnssref) {
DNSServiceRefDeallocate(dnssref);
dnssref = 0;
}
}
void BonjourServiceRegister::registerService(const BonjourRecord &record, quint16 servicePort)
{
if (dnssref) {
qWarning("Warning: Already registered a service for this object, aborting new register");
return;
}
quint16 bigEndianPort = servicePort;
#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN
{
bigEndianPort = 0 | ((servicePort & 0x00ff) << 8) | ((servicePort & 0xff00) >> 8);
}
#endif
DNSServiceErrorType err = DNSServiceRegister(&dnssref, 0, 0, record.serviceName.toUtf8().constData(),
record.registeredType.toUtf8().constData(),
record.replyDomain.isEmpty() ? 0
: record.replyDomain.toUtf8().constData(), 0,
bigEndianPort, 0, 0, bonjourRegisterService, this);
if (err != kDNSServiceErr_NoError) {
emit error(err);
} else {
int sockfd = DNSServiceRefSockFD(dnssref);
if (sockfd == -1) {
emit error(kDNSServiceErr_Invalid);
} else {
bonjourSocket = new QSocketNotifier(sockfd, QSocketNotifier::Read, this);
connect(bonjourSocket, SIGNAL(activated(int)), this, SLOT(bonjourSocketReadyRead()));
}
}
}
void BonjourServiceRegister::bonjourSocketReadyRead()
{
DNSServiceErrorType err = DNSServiceProcessResult(dnssref);
if (err != kDNSServiceErr_NoError)
emit error(err);
}
void BonjourServiceRegister::bonjourRegisterService(DNSServiceRef, DNSServiceFlags,
DNSServiceErrorType errorCode, const char *name,
const char *regtype, const char *domain,
void *data)
{
BonjourServiceRegister *serviceRegister = static_cast<BonjourServiceRegister *>(data);
if (errorCode != kDNSServiceErr_NoError) {
emit serviceRegister->error(errorCode);
} else {
serviceRegister->finalRecord = BonjourRecord(QString::fromUtf8(name),
QString::fromUtf8(regtype),
QString::fromUtf8(domain));
emit serviceRegister->serviceRegistered(serviceRegister->finalRecord);
}
}

View File

@ -0,0 +1,15 @@
HEADERS = server.h \
bonjourserviceregister.h
SOURCES = server.cpp \
main.cpp \
bonjourserviceregister.cpp
QT += network
!mac:x11:LIBS+=-ldns_sd
win32 {
LIBS+=-ldnssd
# Add your path to bonjour here.
LIBPATH=C:/Temp/mDNSResponder-107.6/mDNSWindows/DLL/Debug
INCLUDEPATH += c:/Temp/mDNSResponder-107.6/mDNSShared
}

39
libsrc/bonjour/main.cpp Executable file
View File

@ -0,0 +1,39 @@
/****************************************************************************
**
** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the example classes of the Qt Toolkit.
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://www.trolltech.com/products/qt/opensource.html
**
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://www.trolltech.com/products/qt/licensing.html or contact the
** sales department at sales@trolltech.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include <QApplication>
#include <QtCore>
#include <stdlib.h>
#include "server.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Server server;
server.show();
qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
int x = server.exec();
return x;
}

96
libsrc/bonjour/server.cpp Executable file
View File

@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the example classes of the Qt Toolkit.
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://www.trolltech.com/products/qt/opensource.html
**
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://www.trolltech.com/products/qt/licensing.html or contact the
** sales department at sales@trolltech.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#include <QtGui>
#include <QtNetwork>
#include <stdlib.h>
#include "server.h"
#include "bonjourserviceregister.h"
Server::Server(QWidget *parent)
: QDialog(parent)
{
setWindowModality(Qt::ApplicationModal);
statusLabel = new QLabel;
quitButton = new QPushButton(tr("Quit"));
quitButton->setAutoDefault(false);
tcpServer = new QTcpServer(this);
if (!tcpServer->listen()) {
QMessageBox::critical(this, tr("Fortune Server"),
tr("Unable to start the server: %1.")
.arg(tcpServer->errorString()));
close();
return;
}
statusLabel->setText(tr("The server is running on port %1.\n"
"Run the Fortune Client example now.")
.arg(tcpServer->serverPort()));
fortunes << tr("You've been leading a dog's life. Stay off the furniture.")
<< tr("You've got to think about tomorrow.")
<< tr("You will be surprised by a loud noise.")
<< tr("You will feel hungry again in another hour.")
<< tr("You might have mail.")
<< tr("You cannot kill time without injuring eternity.")
<< tr("Computers are not intelligent. They only think they are.");
connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
connect(tcpServer, SIGNAL(newConnection()), this, SLOT(sendFortune()));
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(1);
buttonLayout->addWidget(quitButton);
buttonLayout->addStretch(1);
QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(statusLabel);
mainLayout->addLayout(buttonLayout);
setLayout(mainLayout);
bonjourRegister = new BonjourServiceRegister(this);
bonjourRegister->registerService(BonjourRecord(tr("Fortune Server on %1").arg(QHostInfo::localHostName()),
QLatin1String("_trollfortune._tcp"), QString()),
tcpServer->serverPort());
setWindowTitle(tr("Fortune Server"));
}
void Server::sendFortune()
{
QByteArray block;
QDataStream out(&block, QIODevice::WriteOnly);
out.setVersion(QDataStream::Qt_4_0);
out << (quint16)0;
out << fortunes.at(qrand() % fortunes.size());
out.device()->seek(0);
out << (quint16)(block.size() - sizeof(quint16));
QTcpSocket *clientConnection = tcpServer->nextPendingConnection();
connect(clientConnection, SIGNAL(disconnected()),
clientConnection, SLOT(deleteLater()));
clientConnection->write(block);
clientConnection->disconnectFromHost();
}

52
libsrc/bonjour/server.h Executable file
View File

@ -0,0 +1,52 @@
/****************************************************************************
**
** Copyright (C) 2004-2007 Trolltech ASA. All rights reserved.
**
** This file is part of the example classes of the Qt Toolkit.
**
** This file may be used under the terms of the GNU General Public
** License version 2.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of
** this file. Please review the following information to ensure GNU
** General Public Licensing requirements will be met:
** http://www.trolltech.com/products/qt/opensource.html
**
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://www.trolltech.com/products/qt/licensing.html or contact the
** sales department at sales@trolltech.com.
**
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
**
****************************************************************************/
#ifndef SERVER_H
#define SERVER_H
#include <QDialog>
class QLabel;
class QPushButton;
class QTcpServer;
class BonjourServiceRegister;
class Server : public QDialog
{
Q_OBJECT
public:
Server(QWidget *parent = 0);
private slots:
void sendFortune();
private:
QLabel *statusLabel;
QPushButton *quitButton;
QTcpServer *tcpServer;
QStringList fortunes;
BonjourServiceRegister *bonjourRegister;
};
#endif

View File

@ -13,8 +13,8 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/effectengine)
# Group the headers that go through the MOC compiler
SET(EffectEngineQT_HEADERS
${CURRENT_HEADER_DIR}/EffectEngine.h
${CURRENT_SOURCE_DIR}/Effect.h
${CURRENT_HEADER_DIR}/EffectEngine.h
${CURRENT_SOURCE_DIR}/Effect.h
)
SET(EffectEngineHEADERS
@ -22,35 +22,34 @@ SET(EffectEngineHEADERS
)
SET(EffectEngineSOURCES
${CURRENT_SOURCE_DIR}/EffectEngine.cpp
${CURRENT_SOURCE_DIR}/Effect.cpp
${CURRENT_SOURCE_DIR}/EffectEngine.cpp
${CURRENT_SOURCE_DIR}/Effect.cpp
)
set(EffectEngine_RESOURCES ${CURRENT_SOURCE_DIR}/EffectEngine.qrc)
if(ENABLE_QT5)
QT5_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
qt5_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
else(ENABLE_QT5)
QT4_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
qt4_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
endif(ENABLE_QT5)
QT5_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
qt5_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
else()
QT4_WRAP_CPP(EffectEngineHEADERS_MOC ${EffectEngineQT_HEADERS})
qt4_add_resources(EffectEngine_RESOURCES_RCC ${EffectEngine_RESOURCES} OPTIONS "-no-compress")
endif()
add_library(effectengine
${EffectEngineHEADERS}
${EffectEngineQT_HEADERS}
${EffectEngineHEADERS_MOC}
${EffectEngine_RESOURCES_RCC}
${EffectEngineSOURCES}
${EffectEngineHEADERS}
${EffectEngineQT_HEADERS}
${EffectEngineHEADERS_MOC}
${EffectEngine_RESOURCES_RCC}
${EffectEngineSOURCES}
)
if(ENABLE_QT5)
qt5_use_modules(effectengine Widgets)
endif(ENABLE_QT5)
qt5_use_modules(effectengine Widgets)
endif()
target_link_libraries(effectengine
hyperion
jsoncpp
${QT_LIBRARIES}
${PYTHON_LIBRARIES})
hyperion
jsoncpp
${QT_LIBRARIES}
${PYTHON_LIBRARIES})

View File

@ -1,342 +1,342 @@
{
"type" : "object",
"required" : true,
"properties" : {
"device" : {
"type" : "object",
"required" : true,
"properties" : {
"name" : {
"type" : "string",
"required" : true
},
"type" : {
"type" : "string",
"required" : true
},
"output" : {
"type" : "string",
"required" : true
},
"rate" : {
"type" : "integer",
"required" : true,
"minimum" : 0
},
"colorOrder" : {
"type" : "string",
"required" : false
},
"bgr-output" : { // deprecated
"type" : "boolean",
"required" : false
}
},
"additionalProperties" : false
},
"color": {
"type":"object",
"required":false,
"properties": {
"hsv" : {
"type" : "object",
"required" : false,
"properties" : {
"saturationGain" : {
"type" : "number",
"required" : false,
"minimum" : 0.0
},
"valueGain" : {
"type" : "number",
"required" : false,
"minimum" : 0.0
}
},
"additionalProperties" : false
},
"red": {
"type":"object",
"required":false,
"properties":{
"gamma": {
"type":"number",
"required":false
},
"blacklevel": {
"type":"number",
"required":false
},
"whitelevel": {
"type":"number",
"required":false
},
"threshold": {
"type":"number",
"required":false,
"minimum" : 0.0,
"maximum" : 1.0
}
},
"additionalProperties" : false
},
"green": {
"type":"object",
"required":false,
"properties":{
"gamma": {
"type":"number",
"required":false
},
"blacklevel": {
"type":"number",
"required":false
},
"whitelevel": {
"type":"number",
"required":false
},
"threshold": {
"type":"number",
"required":false,
"minimum" : 0.0,
"maximum" : 1.0
}
},
"additionalProperties" : false
},
"blue": {
"type":"object",
"required":false,
"properties":{
"gamma": {
"type":"number",
"required":false
},
"whitelevel": {
"type":"number",
"required":false
},
"blacklevel": {
"type":"number",
"required":false
},
"threshold": {
"type":"number",
"required":false,
"minimum" : 0.0,
"maximum" : 1.0
}
},
"additionalProperties" : false
},
"smoothing" : {
"type" : "object",
"required" : false,
"properties" : {
"type" : {
"type" : "enum",
"required" : true,
"values" : ["none", "linear"]
},
"time_ms" : {
"type" : "integer",
"required" : false,
"minimum" : 10
},
"updateFrequency" : {
"type" : "number",
"required" : false,
"minimum" : 0.001
}
},
"additionalProperties" : false
}
},
"additionalProperties" : false
},
"leds": {
"type":"array",
"required":true,
"items": {
"type":"object",
"properties": {
"index": {
"type":"integer",
"required":true
},
"hscan": {
"type":"object",
"required":true,
"properties": {
"minimum": {
"type":"number",
"required":true
},
"maximum": {
"type":"number",
"required":true
}
},
"additionalProperties" : false
},
"vscan": {
"type":"object",
"required":true,
"properties": {
"minimum": {
"type":"number",
"required":true
},
"maximum": {
"type":"number",
"required":true
}
},
"additionalProperties" : false
}
},
"additionalProperties" : false
}
},
"effects" :
{
"type" : "object",
"required" : false,
"properties" : {
"paths" : {
"type" : "array",
"required" : false,
"items" : {
"type" : "string"
}
}
},
"additionalProperties" : false
},
"blackborderdetector" :
{
"type" : "object",
"required" : false,
"properties" : {
"enable" : {
"type" : "boolean",
"required" : true
}
},
"additionalProperties" : false
},
"xbmcVideoChecker" :
{
"type" : "object",
"required" : false,
"properties" : {
"xbmcAddress" : {
"type" : "string",
"required" : true
},
"xbmcTcpPort" : {
"type" : "integer",
"required" : true
},
"grabVideo" : {
"type" : "boolean",
"required" : true
},
"grabPictures" : {
"type" : "boolean",
"required" : true
},
"grabAudio" : {
"type" : "boolean",
"required" : true
},
"grabMenu" : {
"type" : "boolean",
"required" : true
}
},
"additionalProperties" : false
},
"bootsequence" :
{
"type" : "object",
"required" : false,
"properties" : {
"path" : {
"type" : "string",
"required" : true
},
"effect" : {
"type" : "string",
"required" : true
}
},
"additionalProperties" : false
},
"framegrabber" :
{
"type" : "object",
"required" : false,
"properties" : {
"width" : {
"type" : "integer",
"required" : true
},
"height" : {
"type" : "integer",
"required" : true
},
"frequency_Hz" : {
"type" : "integer",
"required" : true
}
},
"additionalProperties" : false
},
"jsonServer" :
{
"type" : "object",
"required" : false,
"properties" : {
"port" : {
"type" : "integer",
"required" : true,
"minimum" : 0,
"maximum" : 65535
}
},
"additionalProperties" : false
},
"protoServer" :
{
"type" : "object",
"required" : false,
"properties" : {
"port" : {
"type" : "integer",
"required" : true,
"minimum" : 0,
"maximum" : 65535
}
},
"additionalProperties" : false
},
"boblightServer" :
{
"type" : "object",
"required" : false,
"properties" : {
"port" : {
"type" : "integer",
"required" : true,
"minimum" : 0,
"maximum" : 65535
}
},
"additionalProperties" : false
}
},
"additionalProperties" : false
}
{
"type" : "object",
"required" : true,
"properties" : {
"device" : {
"type" : "object",
"required" : true,
"properties" : {
"name" : {
"type" : "string",
"required" : true
},
"type" : {
"type" : "string",
"required" : true
},
"output" : {
"type" : "string",
"required" : true
},
"rate" : {
"type" : "integer",
"required" : true,
"minimum" : 0
},
"colorOrder" : {
"type" : "string",
"required" : false
},
"bgr-output" : { // deprecated
"type" : "boolean",
"required" : false
}
},
"additionalProperties" : false
},
"color": {
"type":"object",
"required":false,
"properties": {
"hsv" : {
"type" : "object",
"required" : false,
"properties" : {
"saturationGain" : {
"type" : "number",
"required" : false,
"minimum" : 0.0
},
"valueGain" : {
"type" : "number",
"required" : false,
"minimum" : 0.0
}
},
"additionalProperties" : false
},
"red": {
"type":"object",
"required":false,
"properties":{
"gamma": {
"type":"number",
"required":false
},
"blacklevel": {
"type":"number",
"required":false
},
"whitelevel": {
"type":"number",
"required":false
},
"threshold": {
"type":"number",
"required":false,
"minimum" : 0.0,
"maximum" : 1.0
}
},
"additionalProperties" : false
},
"green": {
"type":"object",
"required":false,
"properties":{
"gamma": {
"type":"number",
"required":false
},
"blacklevel": {
"type":"number",
"required":false
},
"whitelevel": {
"type":"number",
"required":false
},
"threshold": {
"type":"number",
"required":false,
"minimum" : 0.0,
"maximum" : 1.0
}
},
"additionalProperties" : false
},
"blue": {
"type":"object",
"required":false,
"properties":{
"gamma": {
"type":"number",
"required":false
},
"whitelevel": {
"type":"number",
"required":false
},
"blacklevel": {
"type":"number",
"required":false
},
"threshold": {
"type":"number",
"required":false,
"minimum" : 0.0,
"maximum" : 1.0
}
},
"additionalProperties" : false
},
"smoothing" : {
"type" : "object",
"required" : false,
"properties" : {
"type" : {
"type" : "enum",
"required" : true,
"values" : ["none", "linear"]
},
"time_ms" : {
"type" : "integer",
"required" : false,
"minimum" : 10
},
"updateFrequency" : {
"type" : "number",
"required" : false,
"minimum" : 0.001
}
},
"additionalProperties" : false
}
},
"additionalProperties" : false
},
"leds": {
"type":"array",
"required":true,
"items": {
"type":"object",
"properties": {
"index": {
"type":"integer",
"required":true
},
"hscan": {
"type":"object",
"required":true,
"properties": {
"minimum": {
"type":"number",
"required":true
},
"maximum": {
"type":"number",
"required":true
}
},
"additionalProperties" : false
},
"vscan": {
"type":"object",
"required":true,
"properties": {
"minimum": {
"type":"number",
"required":true
},
"maximum": {
"type":"number",
"required":true
}
},
"additionalProperties" : false
}
},
"additionalProperties" : false
}
},
"effects" :
{
"type" : "object",
"required" : false,
"properties" : {
"paths" : {
"type" : "array",
"required" : false,
"items" : {
"type" : "string"
}
}
},
"additionalProperties" : false
},
"blackborderdetector" :
{
"type" : "object",
"required" : false,
"properties" : {
"enable" : {
"type" : "boolean",
"required" : true
}
},
"additionalProperties" : false
},
"xbmcVideoChecker" :
{
"type" : "object",
"required" : false,
"properties" : {
"xbmcAddress" : {
"type" : "string",
"required" : true
},
"xbmcTcpPort" : {
"type" : "integer",
"required" : true
},
"grabVideo" : {
"type" : "boolean",
"required" : true
},
"grabPictures" : {
"type" : "boolean",
"required" : true
},
"grabAudio" : {
"type" : "boolean",
"required" : true
},
"grabMenu" : {
"type" : "boolean",
"required" : true
}
},
"additionalProperties" : false
},
"bootsequence" :
{
"type" : "object",
"required" : false,
"properties" : {
"path" : {
"type" : "string",
"required" : true
},
"effect" : {
"type" : "string",
"required" : true
}
},
"additionalProperties" : false
},
"framegrabber" :
{
"type" : "object",
"required" : false,
"properties" : {
"width" : {
"type" : "integer",
"required" : true
},
"height" : {
"type" : "integer",
"required" : true
},
"frequency_Hz" : {
"type" : "integer",
"required" : true
}
},
"additionalProperties" : false
},
"jsonServer" :
{
"type" : "object",
"required" : false,
"properties" : {
"port" : {
"type" : "integer",
"required" : true,
"minimum" : 0,
"maximum" : 65535
}
},
"additionalProperties" : false
},
"protoServer" :
{
"type" : "object",
"required" : false,
"properties" : {
"port" : {
"type" : "integer",
"required" : true,
"minimum" : 0,
"maximum" : 65535
}
},
"additionalProperties" : false
},
"boblightServer" :
{
"type" : "object",
"required" : false,
"properties" : {
"port" : {
"type" : "integer",
"required" : true,
"minimum" : 0,
"maximum" : 65535
}
},
"additionalProperties" : false
}
},
"additionalProperties" : false
}

View File

@ -35,23 +35,28 @@ EffectEngine::EffectEngine(Hyperion * hyperion, const Json::Value & jsonEffectCo
{
const std::string & path = paths[i].asString();
QDir directory(QString::fromStdString(path));
if (!directory.exists())
if (directory.exists())
{
std::cerr << "EFFECTENGINE ERROR: Effect directory can not be loaded: " << path << std::endl;
continue;
}
QStringList filenames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase);
foreach (const QString & filename, filenames)
{
EffectDefinition def;
if (loadEffectDefinition(path, filename.toStdString(), def))
int efxCount = 0;
QStringList filenames = directory.entryList(QStringList() << "*.json", QDir::Files, QDir::Name | QDir::IgnoreCase);
foreach (const QString & filename, filenames)
{
_availableEffects.push_back(def);
EffectDefinition def;
if (loadEffectDefinition(path, filename.toStdString(), def))
{
_availableEffects.push_back(def);
efxCount++;
}
}
std::cerr << "EFFECTENGINE INFO: " << efxCount << " effects loaded from directory " << path << std::endl;
}
}
if (_availableEffects.size() == 0)
{
std::cerr << "EFFECTENGINE ERROR: no effects found, check your effect directories" << std::endl;
}
// initialize the python interpreter
std::cout << "EFFECTENGINE INFO: Initializing Python interpreter" << std::endl;
Effect::registerHyperionExtensionModule();

View File

@ -1,23 +1,23 @@
if (ENABLE_AMLOGIC)
add_subdirectory(amlogic)
endif (ENABLE_AMLOGIC)
if (ENABLE_DISPMANX)
add_subdirectory(dispmanx)
endif (ENABLE_DISPMANX)
if (ENABLE_FB)
add_subdirectory(framebuffer)
endif (ENABLE_FB)
if (ENABLE_OSX)
add_subdirectory(osx)
endif()
if (ENABLE_V4L2)
add_subdirectory(v4l2)
endif (ENABLE_V4L2)
if (ENABLE_X11)
add_subdirectory(x11)
endif()
if (ENABLE_AMLOGIC)
add_subdirectory(amlogic)
endif (ENABLE_AMLOGIC)
if (ENABLE_DISPMANX)
add_subdirectory(dispmanx)
endif (ENABLE_DISPMANX)
if (ENABLE_FB)
add_subdirectory(framebuffer)
endif (ENABLE_FB)
if (ENABLE_OSX)
add_subdirectory(osx)
endif()
if (ENABLE_V4L2)
add_subdirectory(v4l2)
endif (ENABLE_V4L2)
if (ENABLE_X11)
add_subdirectory(x11)
endif()

View File

@ -78,6 +78,7 @@ void AmlogicWrapper::setGrabbingMode(const GrabbingMode mode)
switch (mode)
{
case GRABBINGMODE_VIDEO:
case GRABBINGMODE_PAUSE:
// _frameGrabber->setFlags(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL);
start();
break;

View File

@ -1,33 +1,33 @@
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/amlogic)
# Group the headers that go through the MOC compiler
SET(AmlogicQT_HEADERS ${CURRENT_HEADER_DIR}/AmlogicWrapper.h)
SET(AmlogicHEADERS
${CURRENT_HEADER_DIR}/AmlogicGrabber.h
)
SET(AmlogicSOURCES
${CURRENT_SOURCE_DIR}/AmlogicWrapper.cpp
${CURRENT_SOURCE_DIR}/AmlogicGrabber.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
else(ENABLE_QT5)
QT4_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
endif(ENABLE_QT5)
add_library(amlogic-grabber
${AmlogicHEADERS}
${AmlogicQT_HEADERS}
${AmlogicHEADERS_MOC}
${AmlogicSOURCES}
)
target_link_libraries(amlogic-grabber
hyperion
${QT_LIBRARIES})
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/amlogic)
# Group the headers that go through the MOC compiler
SET(AmlogicQT_HEADERS ${CURRENT_HEADER_DIR}/AmlogicWrapper.h)
SET(AmlogicHEADERS
${CURRENT_HEADER_DIR}/AmlogicGrabber.h
)
SET(AmlogicSOURCES
${CURRENT_SOURCE_DIR}/AmlogicWrapper.cpp
${CURRENT_SOURCE_DIR}/AmlogicGrabber.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
else(ENABLE_QT5)
QT4_WRAP_CPP(AmlogicHEADERS_MOC ${AmlogicQT_HEADERS})
endif(ENABLE_QT5)
add_library(amlogic-grabber
${AmlogicHEADERS}
${AmlogicQT_HEADERS}
${AmlogicHEADERS_MOC}
${AmlogicSOURCES}
)
target_link_libraries(amlogic-grabber
hyperion
${QT_LIBRARIES})

View File

@ -1,41 +1,41 @@
# Find the BCM-package (VC control)
find_package(BCM REQUIRED)
include_directories(${BCM_INCLUDE_DIRS})
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/dispmanx)
# Group the headers that go through the MOC compiler
SET(DispmanxGrabberQT_HEADERS
${CURRENT_HEADER_DIR}/DispmanxWrapper.h
)
SET(DispmanxGrabberHEADERS
${CURRENT_HEADER_DIR}/DispmanxFrameGrabber.h
)
SET(DispmanxGrabberSOURCES
${CURRENT_SOURCE_DIR}/DispmanxWrapper.cpp
${CURRENT_SOURCE_DIR}/DispmanxFrameGrabber.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS})
else(ENABLE_QT5)
QT4_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS})
endif(ENABLE_QT5)
add_library(dispmanx-grabber
${DispmanxGrabberHEADERS}
${DispmanxGrabberQT_HEADERS}
${DispmanxGrabberHEADERS_MOC}
${DispmanxGrabberSOURCES}
)
target_link_libraries(dispmanx-grabber
hyperion
${QT_LIBRARIES}
${BCM_LIBRARIES}
)
# Find the BCM-package (VC control)
find_package(BCM REQUIRED)
include_directories(${BCM_INCLUDE_DIRS})
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/dispmanx)
# Group the headers that go through the MOC compiler
SET(DispmanxGrabberQT_HEADERS
${CURRENT_HEADER_DIR}/DispmanxWrapper.h
)
SET(DispmanxGrabberHEADERS
${CURRENT_HEADER_DIR}/DispmanxFrameGrabber.h
)
SET(DispmanxGrabberSOURCES
${CURRENT_SOURCE_DIR}/DispmanxWrapper.cpp
${CURRENT_SOURCE_DIR}/DispmanxFrameGrabber.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS})
else()
QT4_WRAP_CPP(DispmanxGrabberHEADERS_MOC ${DispmanxGrabberQT_HEADERS})
endif()
add_library(dispmanx-grabber
${DispmanxGrabberHEADERS}
${DispmanxGrabberQT_HEADERS}
${DispmanxGrabberHEADERS_MOC}
${DispmanxGrabberSOURCES}
)
target_link_libraries(dispmanx-grabber
hyperion
${QT_LIBRARIES}
${BCM_LIBRARIES}
)

View File

@ -11,7 +11,14 @@ DispmanxFrameGrabber::DispmanxFrameGrabber(const unsigned width, const unsigned
_vc_resource(0),
_vc_flags(0),
_width(width),
_height(height)
_height(height),
_videoMode(VIDEO_2D),
_cropLeft(0),
_cropRight(0),
_cropTop(0),
_cropBottom(0),
_captureBuffer(new ColorRgba[0]),
_captureBufferSize(0)
{
// Initiase BCM
bcm_host_init();
@ -49,6 +56,8 @@ DispmanxFrameGrabber::DispmanxFrameGrabber(const unsigned width, const unsigned
DispmanxFrameGrabber::~DispmanxFrameGrabber()
{
delete[] _captureBuffer;
// Clean up resources
vc_dispmanx_resource_delete(_vc_resource);
@ -63,38 +72,147 @@ void DispmanxFrameGrabber::setFlags(const int vc_flags)
void DispmanxFrameGrabber::setVideoMode(const VideoMode videoMode)
{
switch (videoMode) {
case VIDEO_3DSBS:
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width/2, _height);
break;
case VIDEO_3DTAB:
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width, _height/2);
break;
case VIDEO_2D:
default:
vc_dispmanx_rect_set(&_rectangle, 0, 0, _width, _height);
break;
_videoMode = videoMode;
}
void DispmanxFrameGrabber::setCropping(unsigned cropLeft, unsigned cropRight, unsigned cropTop, unsigned cropBottom)
{
if (cropLeft + cropRight >= _width || cropTop + cropBottom >= _height)
{
std::cout
<< "DISPMANXGRABBER ERROR: Rejecting invalid crop values"
<< " left: " << cropLeft
<< " right: " << cropRight
<< " top: " << cropTop
<< " bottom: " << cropBottom
<< std::endl;
return;
}
_cropLeft = cropLeft;
_cropRight = cropRight;
_cropTop = cropTop;
_cropBottom = cropBottom;
if (cropLeft > 0 || cropRight > 0 || cropTop > 0 || cropBottom > 0)
{
std::cout
<< "DISPMANXGRABBER INFO: Cropping " << _width << "x" << _height << " image"
<< " left: " << cropLeft
<< " right: " << cropRight
<< " top: " << cropTop
<< " bottom: " << cropBottom
<< std::endl;
}
}
void DispmanxFrameGrabber::grabFrame(Image<ColorRgba> & image)
{
// resize the given image if needed
if (image.width() != unsigned(_rectangle.width) || image.height() != unsigned(_rectangle.height))
int ret;
// vc_dispmanx_resource_read_data doesn't seem to work well
// with arbitrary positions so we have to handle cropping by ourselves
unsigned cropLeft = _cropLeft;
unsigned cropRight = _cropRight;
unsigned cropTop = _cropTop;
unsigned cropBottom = _cropBottom;
if (_vc_flags & DISPMANX_SNAPSHOT_FILL)
{
image.resize(_rectangle.width, _rectangle.height);
// disable cropping, we are capturing the video overlay window
cropLeft = cropRight = cropTop = cropBottom = 0;
}
unsigned imageWidth = _width - cropLeft - cropRight;
unsigned imageHeight = _height - cropTop - cropBottom;
// calculate final image dimensions and adjust top/left cropping in 3D modes
switch (_videoMode)
{
case VIDEO_3DSBS:
imageWidth = imageWidth / 2;
cropLeft = cropLeft / 2;
break;
case VIDEO_3DTAB:
imageHeight = imageHeight / 2;
cropTop = cropTop / 2;
break;
case VIDEO_2D:
default:
break;
}
// resize the given image if needed
if (image.width() != imageWidth || image.height() != imageHeight)
{
image.resize(imageWidth, imageHeight);
}
// Open the connection to the display
_vc_display = vc_dispmanx_display_open(0);
if (_vc_display < 0)
{
std::cout << "DISPMANXGRABBER ERROR: Cannot open display: " << _vc_display << std::endl;
return;
}
// Create the snapshot (incl down-scaling)
vc_dispmanx_snapshot(_vc_display, _vc_resource, (DISPMANX_TRANSFORM_T) _vc_flags);
ret = vc_dispmanx_snapshot(_vc_display, _vc_resource, (DISPMANX_TRANSFORM_T) _vc_flags);
if (ret < 0)
{
std::cout << "DISPMANXGRABBER ERROR: Snapshot failed: " << ret << std::endl;
vc_dispmanx_display_close(_vc_display);
return;
}
// Read the snapshot into the memory
void* image_ptr = image.memptr();
const unsigned destPitch = _rectangle.width * sizeof(ColorRgba);
vc_dispmanx_resource_read_data(_vc_resource, &_rectangle, image_ptr, destPitch);
void* imagePtr = image.memptr();
void* capturePtr = imagePtr;
unsigned imagePitch = imageWidth * sizeof(ColorRgba);
// dispmanx seems to require the pitch to be a multiple of 64
unsigned capturePitch = (_rectangle.width * sizeof(ColorRgba) + 63) & (~63);
// grab to temp buffer if image pitch isn't valid or if we are cropping
if (imagePitch != capturePitch
|| (unsigned)_rectangle.width != imageWidth
|| (unsigned)_rectangle.height != imageHeight)
{
// check if we need to resize the capture buffer
unsigned captureSize = capturePitch * _rectangle.height / sizeof(ColorRgba);
if (_captureBufferSize != captureSize)
{
delete[] _captureBuffer;
_captureBuffer = new ColorRgba[captureSize];
_captureBufferSize = captureSize;
}
capturePtr = &_captureBuffer[0];
}
ret = vc_dispmanx_resource_read_data(_vc_resource, &_rectangle, capturePtr, capturePitch);
if (ret < 0)
{
std::cout << "DISPMANXGRABBER ERROR: vc_dispmanx_resource_read_data failed: " << ret << std::endl;
vc_dispmanx_display_close(_vc_display);
return;
}
// copy capture data to image if we captured to temp buffer
if (imagePtr != capturePtr)
{
// adjust source pointer to top/left cropping
uint8_t* src_ptr = (uint8_t*) capturePtr
+ cropLeft * sizeof(ColorRgba)
+ cropTop * capturePitch;
for (unsigned y = 0; y < imageHeight; y++)
{
memcpy((uint8_t*)imagePtr + y * imagePitch,
src_ptr + y * capturePitch,
imagePitch);
}
}
// Close the displaye
vc_dispmanx_display_close(_vc_display);

View File

@ -74,6 +74,7 @@ void DispmanxWrapper::setGrabbingMode(const GrabbingMode mode)
switch (mode)
{
case GRABBINGMODE_VIDEO:
case GRABBINGMODE_PAUSE:
_frameGrabber->setFlags(DISPMANX_SNAPSHOT_NO_RGB|DISPMANX_SNAPSHOT_FILL);
start();
break;
@ -94,3 +95,9 @@ void DispmanxWrapper::setVideoMode(const VideoMode mode)
{
_frameGrabber->setVideoMode(mode);
}
void DispmanxWrapper::setCropping(const unsigned cropLeft, const unsigned cropRight,
const unsigned cropTop, const unsigned cropBottom)
{
_frameGrabber->setCropping(cropLeft, cropRight, cropTop, cropBottom);
}

View File

@ -9,31 +9,31 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/framebuffer)
# Group the headers that go through the MOC compiler
SET(FramebufferGrabberQT_HEADERS
${CURRENT_HEADER_DIR}/FramebufferWrapper.h
${CURRENT_HEADER_DIR}/FramebufferWrapper.h
)
SET(FramebufferGrabberHEADERS
${CURRENT_HEADER_DIR}/FramebufferFrameGrabber.h
${CURRENT_HEADER_DIR}/FramebufferFrameGrabber.h
)
SET(FramebufferGrabberSOURCES
${CURRENT_SOURCE_DIR}/FramebufferWrapper.cpp
${CURRENT_SOURCE_DIR}/FramebufferFrameGrabber.cpp
${CURRENT_SOURCE_DIR}/FramebufferWrapper.cpp
${CURRENT_SOURCE_DIR}/FramebufferFrameGrabber.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(FramebufferGrabberHEADERS_MOC ${FramebufferGrabberQT_HEADERS})
else(ENABLE_QT5)
else()
QT4_WRAP_CPP(FramebufferGrabberHEADERS_MOC ${FramebufferGrabberQT_HEADERS})
endif(ENABLE_QT5)
endif()
add_library(framebuffer-grabber
${FramebufferGrabberHEADERS}
${FramebufferGrabberQT_HEADERS}
${FramebufferGrabberHEADERS_MOC}
${FramebufferGrabberSOURCES}
${FramebufferGrabberHEADERS}
${FramebufferGrabberQT_HEADERS}
${FramebufferGrabberHEADERS_MOC}
${FramebufferGrabberSOURCES}
)
target_link_libraries(framebuffer-grabber
hyperion
${QT_LIBRARIES})
hyperion
${QT_LIBRARIES})

View File

@ -62,6 +62,7 @@ void FramebufferWrapper::setGrabbingMode(const GrabbingMode mode)
switch (mode)
{
case GRABBINGMODE_VIDEO:
case GRABBINGMODE_PAUSE:
case GRABBINGMODE_AUDIO:
case GRABBINGMODE_PHOTO:
case GRABBINGMODE_MENU:

View File

@ -4,31 +4,31 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/osx)
# Group the headers that go through the MOC compiler
SET(OsxGrabberQT_HEADERS
${CURRENT_HEADER_DIR}/OsxWrapper.h
${CURRENT_HEADER_DIR}/OsxWrapper.h
)
SET(OsxGrabberHEADERS
${CURRENT_HEADER_DIR}/OsxFrameGrabber.h
${CURRENT_HEADER_DIR}/OsxFrameGrabber.h
)
SET(OsxGrabberSOURCES
${CURRENT_SOURCE_DIR}/OsxWrapper.cpp
${CURRENT_SOURCE_DIR}/OsxFrameGrabber.cpp
${CURRENT_SOURCE_DIR}/OsxWrapper.cpp
${CURRENT_SOURCE_DIR}/OsxFrameGrabber.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(OsxGrabberHEADERS_MOC ${OsxGrabberQT_HEADERS})
else(ENABLE_QT5)
else()
QT4_WRAP_CPP(OsxGrabberHEADERS_MOC ${OsxGrabberQT_HEADERS})
endif(ENABLE_QT5)
endif()
add_library(osx-grabber
${OsxGrabberHEADERS}
${OsxGrabberQT_HEADERS}
${OsxGrabberHEADERS_MOC}
${OsxGrabberSOURCES}
${OsxGrabberHEADERS}
${OsxGrabberQT_HEADERS}
${OsxGrabberHEADERS_MOC}
${OsxGrabberSOURCES}
)
target_link_libraries(osx-grabber
hyperion
${QT_LIBRARIES})
hyperion
${QT_LIBRARIES})

View File

@ -62,6 +62,7 @@ void OsxWrapper::setGrabbingMode(const GrabbingMode mode)
switch (mode)
{
case GRABBINGMODE_VIDEO:
case GRABBINGMODE_PAUSE:
case GRABBINGMODE_AUDIO:
case GRABBINGMODE_PHOTO:
case GRABBINGMODE_MENU:

View File

@ -1,39 +1,39 @@
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/v4l2)
SET(V4L2_QT_HEADERS
${CURRENT_HEADER_DIR}/V4L2Grabber.h
${CURRENT_HEADER_DIR}/V4L2Wrapper.h
)
SET(V4L2_HEADERS
${CURRENT_HEADER_DIR}/VideoStandard.h
)
SET(V4L2_SOURCES
${CURRENT_SOURCE_DIR}/V4L2Grabber.cpp
${CURRENT_SOURCE_DIR}/V4L2Wrapper.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS})
else(ENABLE_QT5)
QT4_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS})
endif(ENABLE_QT5)
add_library(v4l2-grabber
${V4L2_HEADERS}
${V4L2_SOURCES}
${V4L2_QT_HEADERS}
${V4L2_HEADERS_MOC}
)
if(ENABLE_QT5)
qt5_use_modules(v4l2-grabber Widgets)
endif(ENABLE_QT5)
target_link_libraries(v4l2-grabber
hyperion
${QT_LIBRARIES}
)
# Define the current source locations
SET(CURRENT_HEADER_DIR ${CMAKE_SOURCE_DIR}/include/grabber)
SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/grabber/v4l2)
SET(V4L2_QT_HEADERS
${CURRENT_HEADER_DIR}/V4L2Grabber.h
${CURRENT_HEADER_DIR}/V4L2Wrapper.h
)
SET(V4L2_HEADERS
${CURRENT_HEADER_DIR}/VideoStandard.h
)
SET(V4L2_SOURCES
${CURRENT_SOURCE_DIR}/V4L2Grabber.cpp
${CURRENT_SOURCE_DIR}/V4L2Wrapper.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS})
else()
QT4_WRAP_CPP(V4L2_HEADERS_MOC ${V4L2_QT_HEADERS})
endif()
add_library(v4l2-grabber
${V4L2_HEADERS}
${V4L2_SOURCES}
${V4L2_QT_HEADERS}
${V4L2_HEADERS_MOC}
)
if(ENABLE_QT5)
qt5_use_modules(v4l2-grabber Widgets)
endif(ENABLE_QT5)
target_link_libraries(v4l2-grabber
hyperion
${QT_LIBRARIES}
)

File diff suppressed because it is too large Load Diff

View File

@ -19,20 +19,20 @@ SET(X11_HEADERS
)
SET(X11_SOURCES
${CURRENT_SOURCE_DIR}/X11Grabber.cpp
${CURRENT_SOURCE_DIR}/X11Grabber.cpp
)
if(ENABLE_QT5)
QT5_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
else(ENABLE_QT5)
QT4_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
endif(ENABLE_QT5)
QT5_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
else()
QT4_WRAP_CPP(X11_HEADERS_MOC ${X11_QT_HEADERS})
endif()
add_library(x11-grabber
${X11_HEADERS}
${X11_SOURCES}
${X11_QT_HEADERS}
${X11_HEADERS_MOC}
${X11_HEADERS}
${X11_SOURCES}
${X11_QT_HEADERS}
${X11_HEADERS_MOC}
)
target_link_libraries(x11-grabber

Some files were not shown because too many files have changed in this diff Show More