Category Archives: Multimedia

Cross-compiling FFmpeg for Serviio 1.8 with shared libraries on Synology NAS (for 7 CPU architectures)

This method will build FFmpeg 3.2.2 for Synology DSM 6.0 with the shared libraries linked with relative paths, required for Serviio DLNA media server, using a Ubuntu/Xubuntu Desktop 14.04 virtual machine. The same method probably works with many other Linux distributions. The target CPU architectures are ARMv5, ARMv7 hard float ABI, ARM hard float ABI with NEON, Intel i686, Intel i686 Evansport, Intel x86-64, and PowerPC e500v2.

The >10MB size of the static executable is kind of getting out of hand especially on embedded systems with very limited RAM. Using shared libs means many concurrent instances of FFmpeg can use broadly the same memory footprint, and package distribution binaries can be smaller – our target systems already have libmp3lame, libm, libz, libbz2, liblzma, libpng16, librt, libgmp, libgnutls, libhogweed, libnettle, libfreetype, libfontconfig, libexpat, and libpthread which add up to several megabytes. I’m also guessing that the OS will decide when to unload them from RAM which could help when FFmpeg is being launched repeatedly in a short period of time (e.g. during library scanning).

The notes below also detail how to compile the Synology fork of FFmpeg 2.7.1 with Intel Evansport SMD (Streaming Media Drivers) hardware transcoding support. This source is itself based upon a fork by Intel which seems to form part of the Evansport SDK. Synology took a very long time (over a year) to partly comply with the GNU Public License and release this source code, despite numerous support requests, forum posts, and reports to the GPL Violations team. Their first DSM 6.0 beta was released in October 2015, and the DSM 6.0 sources were only published in late November 2016, but these remain incomplete since the kernel sources are not included.

Although the unmodified FFmpeg source code will compile successfully for PowerPC CPUs, the FFmpeg binary will core dump when running any command on a video file. I contacted Synology Support for help with this issue back in October 2012 and was given a patch to use at that time which changes the use of a CPU register in the DSP assembly code. The FFmpeg source code has changed a bit recently meaning the patch was no longer valid, but I was able to discover the appropriate location in the code and create a new working patch (code was moved from dsputil_ppc.c to blockdsp.c):

diff -rupN ffmpeg/libavcodec/ppc/blockdsp.c ffmpeg-patched/libavcodec/ppc/blockdsp.c
--- ffmpeg/libavcodec/ppc/blockdsp.c    2015-06-19 21:44:40.000000000 +0100
+++ ffmpeg-patched/libavcodec/ppc/blockdsp.c    2015-07-11 04:06:27.326911100 +0100
@@ -115,8 +115,9 @@ static long check_dcbzl_effect(void)
     memset(fakedata, 0xFF, 1024);
 
     /* Below the constraint "b" seems to mean "address base register"
-     * in gcc-3.3 / RS/6000 speaks. Seems to avoid using r0, so.... */
-    __asm__ volatile ("dcbzl %0, %1" :: "b" (fakedata_middle), "r" (zero));
+     * in gcc-3.3 / RS/6000 speaks. Seems to avoid using r0, so.... 
+    __asm__ volatile ("dcbzl %0, %1" :: "b" (fakedata_middle), "r" (zero)); */
+    __asm__ volatile ("dcbz %0, %1" :: "r" (fakedata_middle), "r" (zero));
 
     for (i = 0; i < 1024; i++)
         if (fakedata[i] == (char) 0)
 
#-----set up Synology toolchain
cd ~/Downloads
export DL_PATH="https://sourceforge.net/projects/dsgpl/files/DSM%206.0.2%20Tool%20Chains"
#-----add 32bit binary compatibility to Ubuntu 14.04 LTS (Syno toolchains are 32bit)
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo apt-get install git
sudo apt-get install chrpath
#----------------------------------------------------
#-----NOW PASTE ONE OF THE FOLLOWING SIX BLOCKS TO THE TERMINAL, DEPENDING ON YOUR TARGET CPU TYPE
#-----Marvell Kirkwood mv6281/mv6282 (ARMv5te)
#-----Marvell Armada 370/375/XP (ARMv7l FPU)
#-----Mindspeed Comcerto 2000/Marvell Armada 375 (ARM Cortex-A9 NEON)
#-----Freescale PowerQUICC III MPC8533E/QorIQ P1022 (PPC e500v2 FPU)
#-----Intel Atom/Bromolow/Cedarview (i686 SSSE3)
#-----Intel Evansport (i686 SSSE3 various HW decoders, HW H.264 encoder)




#-----Marvell Kirkwood mv6281/mv6282 CPU is based on the ARMv5TE core which has DSP and Thumb instruction support
#-----However using Thumb on ARMv5 results in worse performance
#-----http://www.arm.com/products/processors/technologies/dsp-simd.php
#-----http://www.marvell.com/embedded-processors/kirkwood/assets/88f6282-3_pb.pdf
wget "${DL_PATH}/Marvell%2088F628x%20Linux%202.6.32/6281-gcc464_glibc215_88f6281-GPL.txz"
tar xvJf 6281-gcc464_glibc215_88f6281-GPL.txz
wget "https://sourceforge.net/projects/dsgpl/files/toolkit/DSM6.0/ds.6281-6.0.dev.txz"
export DEV_DL="ds.6281-6.0.dev.txz"
export DEV_DL_ROOT="libc"
export CROSS_PREFIX=arm-marvell-linux-gnueabi
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
export TARGET=arm-marvell-linux-gnueabi
export MARCH="-march=armv5te -mtune=marvell-f -mtune=xscale"
#-----libx264:
#-----http://forum.doom9.org/showthread.php?t=160584
#-----https://mailman.videolan.org/pipermail/x264-devel/2010-December/008093.html
#-----x264 builds with NEON by default because x264 is so slow without NEON (and on any non-NEON chip) as to be useless.
#-----You can of course compile with --disable-asm on such chips, but we don't do it by default because
#-----we don't feel it's necessary to actively support chips on which x264 would be basically useless
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --disable-asm --enable-pic --enable-strip --disable-opencl"
#-----FFmpeg:
#-----ARMv5TE CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
#-----something changed in the FFmpeg configure script and now vfp and neon optimizations have to be explicitly disabled for ARMv5TE, which doesn't have those features in any case
export FF_CONFIG="./configure --arch=arm --cpu=armv5te --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-neon --disable-vfp --disable-armv6 --disable-armv6t2 --disable-debug --enable-pthreads --enable-libshine --enable-librtmp --enable-libass --enable-libspeex --enable-libvorbis --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"
#export FF_CONFIG="./configure --arch=arm --cpu=armv5te --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-neon --disable-vfp --disable-armv6 --disable-armv6t2 --disable-debug --enable-pthreads --enable-libshine --enable-librtmp --enable-libass --enable-libspeex --enable-libvorbis --enable-gpl --enable-libx264 --enable-gnutls --enable-nonfree --enable-libfdk_aac --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"
#-----these next two packages are needed to build libshine
sudo apt-get install automake
sudo apt-get install libtool
wget https://github.com/savonet/shine/zipball/master
unzip master
cd toots-shine-*
./bootstrap
cd ..
#-----fetch libfdk-aac fixed point math AAC encoder, binaries linked to it cannot be redistributed under GPL
#-----so it is excluded from the FFmpeg binary I built for the Serviio package
wget http://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-0.1.4.tar.gz
tar xvzf fdk-aac-0.1.4.tar.gz
cd fdk-aac-0.1.4
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
make
make install
cd ..
 



#-----Marvell Armada 370/XP CPU is based on a dual issue ARMv7 core with Thumb-2, VFPv3-16, but no NEON vector unit
#-----http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf
#-----http://www.arm.com/products/processors/technologies/vector-floating-point.php
#-----since DSM 6.0 hard float ABI is used
wget "${DL_PATH}/Marvell%20Armada%20370%20Linux%203.2.40/armada370-gcc493_glibc220_hard-GPL.txz"
tar xvJf armada370-gcc493_glibc220_hard-GPL.txz
wget "https://sourceforge.net/projects/dsgpl/files/toolkit/DSM6.0/ds.armada370-6.0.dev.txz"
export DEV_DL="ds.armada370-6.0.dev.txz"
export DEV_DL_ROOT="sysroot"
export CROSS_PREFIX=arm-unknown-linux-gnueabi
export TARGET=arm-unknown-linux-gnueabi
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
#-----Tune for Marvell PJ4 dual issue core (two instructions per clock)
#-----Thumb-2 can be used on ARMv6 or newer with no performance drop
export MARCH="-march=armv7-a -mcpu=marvell-pj4 -mtune=marvell-pj4 -mhard-float -mfpu=vfpv3-d16 -mthumb"
#-----libx264:
#-----http://forum.doom9.org/showthread.php?t=160584
#-----https://mailman.videolan.org/pipermail/x264-devel/2010-December/008093.html
#-----x264 builds with NEON by default because x264 is so slow without NEON (and on any non-NEON chip) as to be useless.
#-----You can of course compile with --disable-asm on such chips, but we don't do it by default because
#-----we don't feel it's necessary to actively support chips on which x264 would be basically useless
#-----http://lists.busybox.net/pipermail/buildroot/2014-October/107797.html
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --disable-asm --enable-pic --enable-strip --disable-opencl"
#-----FFmpeg:
#-----ARMv7 CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=arm --cpu=armv7-a --enable-thumb --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-neon --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-libvorbis --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"




#-----Marvell Armada 375, Armada 385, and Mindspeed Comcerto 2000 CPU are based on dual ARM Cortex-A9 cores with NEON vector unit
#-----http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf
#-----http://www.marvell.com/embedded-processors/armada-38x/assets/A38x-Functional-Spec-PU0A.pdf
#-----http://www.mindspeed.com/products/cpe-processors/comcertoreg-2000
#-----http://www.arm.com/products/processors/cortex-a/cortex-a9.php
#-----http://www.arm.com/products/processors/technologies/neon.php
#-----Since DSM 6.0 Armada 375 finally has hard float ABI and therefore gains NEON support
wget "${DL_PATH}/Marvell%20Armada%20375%20Linux%203.2.40/armada375-gcc493_glibc220_hard-GPL.txz"
tar xvJf armada375-gcc493_glibc220_hard-GPL.txz
#-----Marvell gave all the ARMv7 toolchains the same name so rename to allow concurrent installations
mv arm-unknown-linux-gnueabi/ arm-cortexa9-linux-gnueabi/
wget "https://sourceforge.net/projects/dsgpl/files/toolkit/DSM6.0/ds.armada375-6.0.dev.txz"
export DEV_DL="ds.armada375-6.0.dev.txz"
export DEV_DL_ROOT="sysroot"
export CROSS_PREFIX=arm-unknown-linux-gnueabi
export TARGET=arm-unknown-linux-gnueabi
export TOOLCHAIN=/usr/local/arm-cortexa9-linux-gnueabi
#-----it seems that in general neon should be used as the fpu when present unless there's a specific reason not to use it
export MARCH="-march=armv7-a -mcpu=cortex-a9 -mfpu=neon -mhard-float -mthumb"
#-----libx264:
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --enable-pic --enable-strip --disable-opencl"
#-----FFmpeg:
#-----ARMv7 CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=arm --cpu=cortex-a9 --enable-thumb --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-libvorbis --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"




#-----Freescale PowerQUICC III MPC8533E/QorIQ P1022 CPUs use the PowerPC e500v2 core with Signal Processing Engine (SPE) which is not a classic FPU design, but have no AltiVec vector unit 
#-----Some QorIQ models have e500mc cores with true FPUs but these are not used in 2013 series Synology NAS
#-----http://en.wikipedia.org/wiki/QorIQ
#-----http://cache.freescale.com/files/32bit/doc/fact_sheet/QP1022FS.pdf?fpsp=1
wget "${DL_PATH}/PowerPC%20QorIQ%20Linux%202.6.32/qoriq-gcc493_glibc220_hard_qoriq-GPL.txz"
tar xvJf qoriq-gcc493_glibc220_hard_qoriq-GPL.txz
wget "https://sourceforge.net/projects/dsgpl/files/toolkit/DSM6.0/ds.qoriq-6.0.dev.txz"
export DEV_DL="ds.qoriq-6.0.dev.txz"
export DEV_DL_ROOT="sysroot"
export CROSS_PREFIX=powerpc-e500v2-linux-gnuspe
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
export TARGET=powerpc-e500v2-linux-gnuspe
export MARCH="-mcpu=8548 -mhard-float -mfloat-gprs=double"
#-----asm disabled since QorIQ has no AltiVec
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --disable-asm --enable-pic --enable-strip --disable-opencl"
#-----FFmpeg:#-----PowerPC e500v2 CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=ppc --cpu=e500v2 --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-libvorbis --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"




#-----Intel Evansport with support for hardware decoding of VC-1, H.264, MPEG-4, MPEG2, AAC and hardware encoding of H.264
#-----http://www.anandtech.com/show/8020/synology-ds214play-intel-evansport-almost-done-right/9
#-----libx264 requires yasm 1.20
sudo apt-get install yasm
wget "${DL_PATH}/Intel%20x86%20Linux%203.2.40%20%28Evansport%29/evansport-gcc493_glibc220_linaro_i686-GPL.txz"
tar xvJf evansport-gcc493_glibc220_linaro_i686-GPL.txz
#-----Both Intel i686 toolchains the same name so rename to allow concurrent installations
mv i686-pc-linux-gnu evansport-pc-linux-gnu
wget "https://sourceforge.net/projects/dsgpl/files/toolkit/DSM6.0/ds.evansport-6.0.dev.txz"
export DEV_DL="ds.evansport-6.0.dev.txz"
export DEV_DL_ROOT="sys-root"
export CROSS_PREFIX=i686-pc-linux-gnu
export TARGET=i686-pc-linux-gnu
export MARCH="-march=atom"
export TOOLCHAIN=/usr/local/evansport-pc-linux-gnu
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --enable-pic --enable-strip --disable-opencl"
#-----FFmpeg:
#-----Intel CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure.syno --arch=x86 --cpu=atom --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-libvorbis --enable-libx264 --enable-libh264_smd --enable-smd --enable-gpl --enable-gnutls --pkg-config=pkg-config --extra-version=SMD_enabled-compiled_by_patters_for_Serviio"
export FF_CONFIG_I686="./configure --arch=x86 --cpu=atom --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-libvorbis --enable-libx264 --enable-gpl --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"
#-----http://trac.ffmpeg.org/ticket/1794
#-----first ffmpeg compilation error run "make V=1" then add " -lismd_core -lismd_viddec -ljson-c" to the command line
#-----second ffmpeg compilation error run "make V=1" then add " -ljson-c" to the command line




#-----With the exception of Evansport (i686), Intel CPUs used in Synology products are all 64bit and SSSE3 capable
#-----Since DSM 6.0 x86_64 toolchain is used
#-----libx264 requires yasm 1.20
sudo apt-get install yasm
#-----unlike the others this toolchain has an external dependency on libz
#sudo apt-get install libz1:i386
wget "${DL_PATH}/Intel%20x86%20Linux%203.10.77%20%28Pineview%29/x64-gcc493_glibc220_linaro_x86_64-GPL.txz"
tar xvJf x64-gcc493_glibc220_linaro_x86_64-GPL.txz
wget "https://sourceforge.net/projects/dsgpl/files/toolkit/DSM6.0/ds.cedarview-6.0.dev.txz"
export DEV_DL="ds.cedarview-6.0.dev.txz"
export DEV_DL_ROOT="sys-root"
export CROSS_PREFIX=x86_64-pc-linux-gnu
export TARGET=x86_64-pc-linux-gnu
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
#-----We don't really care how lame is built since ffmpeg will use the version in DSM.
#-----The DSM version is built without asm optimizations but these only make a 5% difference, and have been known to introduce instability
export LAME_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-decoder"
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --enable-pic --enable-strip"
#-----FFmpeg:
#-----Intel CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=x86 --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-libvorbis --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"




#----------------------------------------------------
#-----script continues
sudo mv `echo $TOOLCHAIN | sed -r "s%^.*/(.*$)%\1%"` /usr/local
#-----some of the toolchains have bad permissions
sudo chmod -R 0755 ${TOOLCHAIN}
export PATH=${TOOLCHAIN}/bin:$PATH
export AR=${TOOLCHAIN}/bin/${CROSS_PREFIX}-ar
export AS=${TOOLCHAIN}/bin/${CROSS_PREFIX}-as
export CC=${TOOLCHAIN}/bin/${CROSS_PREFIX}-gcc
export CXX=${TOOLCHAIN}/bin/${CROSS_PREFIX}-g++
export LD=${TOOLCHAIN}/bin/${CROSS_PREFIX}-ld
export LDSHARED="${TOOLCHAIN}/bin/${CROSS_PREFIX}-gcc -shared "
export RANLIB=${TOOLCHAIN}/bin/${CROSS_PREFIX}-ranlib
export CFLAGS="-I${TOOLCHAIN}/include -O3 ${MARCH}"
export LDFLAGS="-L${TOOLCHAIN}/lib"
export PKG_CONFIG_PATH="${TOOLCHAIN}/lib/pkgconfig"


#-----set up all our dependent libraries from the Synology dev environment
mkdir ${CROSS_PREFIX}-dev
cd ${CROSS_PREFIX}-dev
tar xfJv ../${DEV_DL}

mkdir $TOOLCHAIN/lib/pkgconfig/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/expat.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/expat_external.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libexpat.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/expat.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/expat.pc

cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/fontconfig/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libfontconfig.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/fontconfig.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/fontconfig.pc

cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/freetype2/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libfreetype.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/freetype2.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/freetype2.pc
sed -i "s|^exec_prefix=.*$|exec_prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/freetype2.pc
sed -i "s|^libdir=.*$|libdir=${TOOLCHAIN}/lib|" $TOOLCHAIN/lib/pkgconfig/freetype2.pc
sed -i "s|^includedir=.*$|includedir=${TOOLCHAIN}/include/freetype2|" $TOOLCHAIN/lib/pkgconfig/freetype2.pc

cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/gmp.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libgmp.* $TOOLCHAIN/lib/

cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/gnutls/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libgnutls.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/gnutls.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/gnutls.pc

cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/lame/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libmp3lame.* $TOOLCHAIN/lib/

cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/nettle/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libnettle.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libhogweed.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/nettle.pc $TOOLCHAIN/lib/pkgconfig/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/hogweed.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/nettle.pc
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/hogweed.pc

cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/png.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/pngconf.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/pnglibconf.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libpng.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/libpng.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/libpng.pc

cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/zlib.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/zconf.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libz.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/zlib.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/zlib.pc

cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/json-c/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libjson-c.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/json-c.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/json-c.pc

#-----libbz2 and libxml-2.0 are dependencies of fontconfig
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/bzlib.h $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libbz2.* $TOOLCHAIN/lib/

cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/libxml2/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libxml2.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/libxml-2.0.pc $TOOLCHAIN/lib/pkgconfig/
sed -i "s|^prefix=.*$|prefix=${TOOLCHAIN}|" $TOOLCHAIN/lib/pkgconfig/libxml-2.0.pc

#-----liblzma is a dependency of libass
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/lzma.h $TOOLCHAIN/include/
cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/lzma/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/liblzma.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/liblzma.pc $TOOLCHAIN/lib/pkgconfig/

#-----libpng16 is a dependency of freetype2
cp -R usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/libpng16/ $TOOLCHAIN/include/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/libpng16.* $TOOLCHAIN/lib/
cp usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/pkgconfig/libpng16.pc $TOOLCHAIN/lib/pkgconfig/

#-----End of syno devkit extraction
cd ..

#-----shine shared lib for ARMv5 only (no FPU)
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && cd toots-shine-*
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && make
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && make install
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && cd ..

#-----fribidi shared lib
wget http://fribidi.org/download/fribidi-0.19.6.tar.bz2
tar xvjf fribidi-0.19.6.tar.bz2
cd fribidi-0.19.6
#-----patch fribidi source since it won't compile - some sort of page size function is no longer available
#-----error on Intel: fribidi-run.c:70: error: 'PAGE_SIZE' undeclared (first use in this function)
#-----http://armbedded.eu/node/56
#-----http://lists.debian.org/debian-glibc/2006/10/msg00169.html
#-----http://my.safaribooksonline.com/book/operating-systems-and-server-administration/linux/0596009585/advanced-file-i-o/mapping_files_into_memory
[ "${CROSS_PREFIX}" == "i686-pc-linux-gnu" ] && sed -i "s|include <asm/page.h>|include <unistd.h>\n#   define PAGE_SIZE sysconf(_SC_PAGESIZE)|" lib/common.h
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
make
make install
cd ..

#-----fontconfig shared lib
wget http://www.freedesktop.org/software/fontconfig/release/fontconfig-2.11.1.tar.gz
tar xvzf fontconfig-2.11.1.tar.gz
cd fontconfig-2.11.1
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
-----correct some non-standard library linking behaviour
sed -i "s/^hardcode_into_libs=yes/hardcode_into_libs=no/" libtool
make
make install
cd ..

#-----libass shared lib
wget https://github.com/libass/libass/releases/download/0.13.4/libass-0.13.4.tar.xz
tar xvJf libass-0.13.4.tar.xz
cd libass-0.13.4
LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,\'\$\$ORIGIN\' ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
#-----correct some non-standard library linking behaviour
sed -i "s/^hardcode_into_libs=yes/hardcode_into_libs=no/" libtool
make
make install
cd ..
#-----Although libass would link correctly to older FFmpeg versions, this mod is now necessary:
#-----http://ffmpeg.org/pipermail/ffmpeg-user/2012-November/010906.html
#-----no longer needed, note here in case of regression in future versions 
#sed -i -r "s/(^Libs: .*$)/\1 -lfontconfig -lfribidi -lfreetype -lexpat/" $TOOLCHAIN/lib/pkgconfig/libass.pc

#-----libx264 shared lib
wget https://download.videolan.org/x264/snapshots/last_stable_x264.tar.bz2
tar xvjf last_stable_x264.tar.bz2
cd x264-snapshot-*
#-----NEON ASM needs to be built by GCC assembler not AS
[ "${TOOLCHAIN}" == "/usr/local/arm-cortexa9-linux-gnueabi" ] && export AS=${TOOLCHAIN}/bin/${CROSS_PREFIX}-gcc
#-----Intel ASM needs to be built by yasm assembler
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && export AS=yasm
[ "${TOOLCHAIN}" == "/usr/local/i686-pc-linux-gnu" ] && export AS=yasm
[ "${TOOLCHAIN}" == "/usr/local/x86_64-pc-linux-gnu" ] && export AS=yasm
$X264_CONFIG
#-----back out assembler changes
AS=${TOOLCHAIN}/bin/${CROSS_PREFIX}-as
make
make install
cd ..

#-----libx265 shared lib
#wget https://bitbucket.org/multicoreware/x265/downloads/x265_2.1.tar.gz
#tar xvzf x265_2.1.tar.gz
#cd x265_2.1

#-----librtmp shared lib
git clone git://git.ffmpeg.org/rtmpdump
cd rtmpdump
make CROSS_COMPILE=${TOOLCHAIN}/bin/${CROSS_PREFIX}- SYS=posix prefix=${TOOLCHAIN} CRYPTO=GNUTLS INC=-I${TOOLCHAIN}/include XLDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,\'\$\$ORIGIN\'
#------librtmp.pc will have the wrong lib dependencies defined unless GNUTLS is specified again here
make install prefix=${TOOLCHAIN} CRYPTO=GNUTLS
cd ..

#-----libspeex shared lib
wget http://downloads.xiph.org/releases/speex/speex-1.2rc2.tar.gz
tar xvzf speex-1.2rc2.tar.gz
cd speex-1.2rc2
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
sed -i "s/^hardcode_into_libs=yes/hardcode_into_libs=no/" libtool
make
make install
cd ..

#-----libogg shared lib
wget http://downloads.xiph.org/releases/ogg/libogg-1.3.2.tar.xz
tar xvJf libogg-1.3.2.tar.xz
cd libogg-1.3.2
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
sed -i "s/^hardcode_into_libs=yes/hardcode_into_libs=no/" libtool
make
make install
cd ..

#-----libvorbis shared lib
wget http://downloads.xiph.org/releases/vorbis/libvorbis-1.3.5.tar.xz
tar xvJf libvorbis-1.3.5.tar.xz
cd libvorbis-1.3.5
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
sed -i "s/^hardcode_into_libs=yes/hardcode_into_libs=no/" libtool
make
make install
cd ..

#-----Evansport only - don't run these two lines until right before compiling FFmpeg since some of the includes will break other stuff
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cp -R ${CROSS_PREFIX}-dev/usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/include/intelce-utilities $TOOLCHAIN/include
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cp -R ${CROSS_PREFIX}-dev/usr/local/$TARGET/$TARGET/${DEV_DL_ROOT}/usr/lib/intelce-utilities $TOOLCHAIN/lib

#-----FFmpeg (Evansport uses a separate Synology-modified source bundle)
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || wget https://www.ffmpeg.org/releases/ffmpeg-3.2.2.tar.xz
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || tar xvJf ffmpeg-3.2.2.tar.xz
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || cd ffmpeg-3.2.2
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && wget https://sourceforge.net/projects/dsgpl/files/Synology%20NAS%20GPL%20Source/8451branch/evansport-source/ffmpeg-2.7.x.txz
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && tar xvJf ffmpeg-2.7.x.txz
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cd ffmpeg-2.7.x

#-----PowerPC-specific fix originally provided by Synology Support in Oct 2012, adapted after code re-org by ffmpeg
[ "${CROSS_PREFIX}" == "powerpc-e500v2-linux-gnuspe" ] && wget http://dl.dropboxusercontent.com/u/1188556/ffmpeg-syno-ppc.patch
[ "${CROSS_PREFIX}" == "powerpc-e500v2-linux-gnuspe" ] && patch --verbose -p1 < ffmpeg-syno-ppc.patch

#-----Evansport SMD driver scheduler uses inline asm which breaks compilation without -fasm
#-----http://stackoverflow.com/questions/18574943/gcc-inline-assembler-implicit-function-declaration-on-powerpc-arch
#-----http://ffmpeg.org/pipermail/ffmpeg-devel/2008-October/056533.html
#-----http://www.tldp.org/HOWTO/Assembly-HOWTO/gcc.html
#-----we also need to add the intelce-utlities locations of the SMD libraries
#-----libx264 will fail to compile with this added to include path, so only add it just before compiling ffmpeg
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] \
  && export CFLAGS="${CFLAGS} -fasm -I${TOOLCHAIN}/include/json-c -I${TOOLCHAIN}/include/intelce-utilities -I${TOOLCHAIN}/include/intelce-utilities/linux_user"

#-----Evansport SMD functionality is disabled by default
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && sed -i "1i#define SYNO_EVANSPORT_SMD" synoconfig.h
#-----Evansport ffmpeg will by default skip DTS audio tracks for transcoding and will refuse to encode AC3
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && wget https://dl.dropboxusercontent.com/u/1188556/ffmpeg-2.7.1-syno-dts-skip.patch
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && patch --verbose -p1 < ffmpeg-2.7.1-syno-dts-skip.patch

#-----set library linker to use relative library search path (../lib and .)
#-----tricky shell escaping of $ORIGIN is required http://itee.uq.edu.au/~daniel/using_origin/
#-----http://stackoverflow.com/questions/6562403/i-dont-understand-wl-rpath-wl
#-----however although FFmpeg gets a correct rpath, the downstream libraries get a value of "RIGIN/../lib:RIGIN"
#-----owing to some additional variable substitution happening - easier to build with XORIGIN and use chrpath later
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] \
  || LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,XORIGIN/../lib:XORIGIN,-rpath-link,${TOOLCHAIN}/lib ${FF_CONFIG} \
  && LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-L${TOOLCHAIN}/lib/intelce-utilities,-rpath,XORIGIN/../lib:XORIGIN,-rpath-link,${TOOLCHAIN}/lib,-rpath-link,${TOOLCHAIN}/lib/intelce-utilities ${FF_CONFIG}

#-----external libs (librtmp, libass) don't seem to link to ffmpeg (check ffmpeg binary with objdump -x)
#-----this is in fact normal because LDFLAGS as defined in config.mak contains '--as-needed'
#-----https://wiki.gentoo.org/wiki/Project:Quality_Assurance/As-needed
#-----e.g. FFmpeg does not contain any symbols from librtmp, but libavformat does
#-----use ldd on the target system and the full dependency chain will be shown
make
make install

#-----remove intelce-utilities from include path
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && export CFLAGS="-I${TOOLCHAIN}/include -O3 ${MARCH}"
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && rm -rf ${TOOLCHAIN}/include/intelce-utilities
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && rm -rf ${TOOLCHAIN}/lib/intelce-utilities 

mkdir native-${CROSS_PREFIX}
cd native-${CROSS_PREFIX}

#-----evansport FFmpeg 2.7.1
#-----fix up rpath settings
sudo chrpath -r '$ORIGIN/../lib:$ORIGIN' ${TOOLCHAIN}/bin/ffmpeg
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavcodec.so.56
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavdevice.so.56
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavfilter.so.5
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavformat.so.56
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavutil.so.54
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libpostproc.so.53
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libswresample.so.1
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libswscale.so.3
cp ${TOOLCHAIN}/lib/libavcodec.so.56 .
cp ${TOOLCHAIN}/lib/libavdevice.so.56 .
cp ${TOOLCHAIN}/lib/libavfilter.so.5 .
cp ${TOOLCHAIN}/lib/libavformat.so.56 .
cp ${TOOLCHAIN}/lib/libavutil.so.54 .
cp ${TOOLCHAIN}/lib/libpostproc.so.53 .
cp ${TOOLCHAIN}/lib/libswresample.so.1 .
cp ${TOOLCHAIN}/lib/libswscale.so.3 .
cp ${TOOLCHAIN}/bin/ffmpeg .
cp ${TOOLCHAIN}/bin/fc-cache .
cp ${TOOLCHAIN}/lib/libass.so.5 .
cp ${TOOLCHAIN}/lib/libfribidi.so.0 .
cp ${TOOLCHAIN}/lib/libogg.so.0 .
cp ${TOOLCHAIN}/lib/librtmp.so.1 .
cp ${TOOLCHAIN}/lib/libspeex.so.1 .
cp ${TOOLCHAIN}/lib/libvorbis.so.0 .
cp ${TOOLCHAIN}/lib/libvorbisenc.so.2 .
cp ${TOOLCHAIN}/lib/libx264.so.148 .


#-----FFmpeg 3.2.2
#-----fix up rpath settings
sudo chrpath -r '$ORIGIN/../lib:$ORIGIN' ${TOOLCHAIN}/bin/ffmpeg
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavcodec.so.57
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavdevice.so.57
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavfilter.so.6
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavformat.so.57
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavutil.so.55
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libpostproc.so.54
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libswresample.so.2
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libswscale.so.4
cp ${TOOLCHAIN}/lib/libavcodec.so.57 .
cp ${TOOLCHAIN}/lib/libavdevice.so.57 .
cp ${TOOLCHAIN}/lib/libavfilter.so.6 .
cp ${TOOLCHAIN}/lib/libavformat.so.57 .
cp ${TOOLCHAIN}/lib/libavutil.so.55 .
cp ${TOOLCHAIN}/lib/libpostproc.so.54 .
cp ${TOOLCHAIN}/lib/libswresample.so.2 .
cp ${TOOLCHAIN}/lib/libswscale.so.4 .
cp ${TOOLCHAIN}/bin/ffmpeg .
cp ${TOOLCHAIN}/bin/fc-cache .
cp ${TOOLCHAIN}/lib/libass.so.5 .
cp ${TOOLCHAIN}/lib/libfribidi.so.0 .
cp ${TOOLCHAIN}/lib/libogg.so.0 .
cp ${TOOLCHAIN}/lib/librtmp.so.1 .
cp ${TOOLCHAIN}/lib/libspeex.so.1 .
cp ${TOOLCHAIN}/lib/libvorbis.so.0 .
cp ${TOOLCHAIN}/lib/libvorbisenc.so.2 .
cp ${TOOLCHAIN}/lib/libx264.so.148 .
[ ${TOOLCHAIN} == "/usr/local/arm-none-linux-gnueabi" ] && cp ${TOOLCHAIN}/lib/libshine.so.3 .
#cp ${TOOLCHAIN}/lib/libfdk-aac.so.1 .
sudo chmod +x *
sudo chown root:root *
XZ_OPT=-9 tar -cvJf ffmpeg-${CROSS_PREFIX}.tar.xz *
 

Here’s how the library dependencies look. There are no links to any libraries in /opt, and DSM-bundled libraries in /lib are linked to where possible. All the other new libraries are kept within the Serviio lib folder (../lib relative to the ffmpeg binary).

DS214> ldd /var/packages/Serviio/target/bin/ffmpeg
	linux-gate.so.1 (0xffffe000)
	libavdevice.so.57 => /volume1/@appstore/Serviio/bin/../lib/libavdevice.so.57 (0xb7708000)
	libavfilter.so.6 => /volume1/@appstore/Serviio/bin/../lib/libavfilter.so.6 (0xb74fd000)
	libavformat.so.57 => /volume1/@appstore/Serviio/bin/../lib/libavformat.so.57 (0xb72bd000)
	libavcodec.so.57 => /volume1/@appstore/Serviio/bin/../lib/libavcodec.so.57 (0xb5ee8000)
	libpostproc.so.54 => /volume1/@appstore/Serviio/bin/../lib/libpostproc.so.54 (0xb5ec1000)
	libswresample.so.2 => /volume1/@appstore/Serviio/bin/../lib/libswresample.so.2 (0xb5ea2000)
	libswscale.so.4 => /volume1/@appstore/Serviio/bin/../lib/libswscale.so.4 (0xb5e11000)
	libavutil.so.55 => /volume1/@appstore/Serviio/bin/../lib/libavutil.so.55 (0xb5d8b000)
	libm.so.6 => /lib/libm.so.6 (0xb5d42000)
	libpthread.so.0 => /lib/libpthread.so.0 (0xb5d25000)
	libc.so.6 => /lib/libc.so.6 (0xb5b77000)
	libass.so.5 => /volume1/@appstore/Serviio/bin/../lib/libass.so.5 (0xb5b33000)
	librtmp.so.1 => /volume1/@appstore/Serviio/bin/../lib/librtmp.so.1 (0xb5b14000)
	libz.so.1 => /lib/libz.so.1 (0xb5afb000)
	libgnutls.so.28 => /lib/libgnutls.so.28 (0xb59f0000)
	libbz2.so.1.0 => /lib/libbz2.so.1.0 (0xb59df000)
	libdl.so.2 => /lib/libdl.so.2 (0xb59da000)
	libx264.so.148 => /volume1/@appstore/Serviio/bin/../lib/libx264.so.148 (0xb583c000)
	libvorbisenc.so.2 => /volume1/@appstore/Serviio/bin/../lib/libvorbisenc.so.2 (0xb57aa000)
	libvorbis.so.0 => /volume1/@appstore/Serviio/bin/../lib/libvorbis.so.0 (0xb5770000)
	libspeex.so.1 => /volume1/@appstore/Serviio/bin/../lib/libspeex.so.1 (0xb5747000)
	libmp3lame.so.0 => /lib/libmp3lame.so.0 (0xb56cf000)
	liblzma.so.5 => /lib/liblzma.so.5 (0xb56a3000)
	/lib/ld-linux.so.2 (0xb7718000)
	libfribidi.so.0 => /volume1/@appstore/Serviio/bin/../lib/libfribidi.so.0 (0xb5688000)
	libfontconfig.so.1 => /lib/libfontconfig.so.1 (0xb5645000)
	libfreetype.so.6 => /lib/libfreetype.so.6 (0xb5586000)
	libhogweed.so.2 => /lib/libhogweed.so.2 (0xb5555000)
	libnettle.so.4 => /lib/libnettle.so.4 (0xb5521000)
	libgmp.so.10 => /lib/libgmp.so.10 (0xb54ac000)
	libogg.so.0 => /volume1/@appstore/Serviio/bin/../lib/libogg.so.0 (0xb54a2000)
	libxml2.so.2 => /lib/libxml2.so.2 (0xb5321000)
	libpng16.so.16 => /lib/libpng16.so.16 (0xb52e4000)
DS214>
 

Here’s how the even more complex Evansport build with hardware transcoding support looks:

DS214Play> ldd /var/packages/Serviio/target/bin/ffmpeg
	linux-gate.so.1 (0xffffe000)
	libavdevice.so.56 => /volume1/@appstore/Serviio/bin/../lib/libavdevice.so.56 (0xb77c0000)
	libavfilter.so.5 => /volume1/@appstore/Serviio/bin/../lib/libavfilter.so.5 (0xb7686000)
	libavformat.so.56 => /volume1/@appstore/Serviio/bin/../lib/libavformat.so.56 (0xb748d000)
	libavcodec.so.56 => /volume1/@appstore/Serviio/bin/../lib/libavcodec.so.56 (0xb630e000)
	libpostproc.so.53 => /volume1/@appstore/Serviio/bin/../lib/libpostproc.so.53 (0xb62e7000)
	libswresample.so.1 => /volume1/@appstore/Serviio/bin/../lib/libswresample.so.1 (0xb62cb000)
	libswscale.so.3 => /volume1/@appstore/Serviio/bin/../lib/libswscale.so.3 (0xb624a000)
	libavutil.so.54 => /volume1/@appstore/Serviio/bin/../lib/libavutil.so.54 (0xb61d4000)
	libffmpeg_plugin.so => /lib/libffmpeg_plugin.so (0xb61be000)
	libm.so.6 => /lib/libm.so.6 (0xb6175000)
	libismd_core.so => /lib/libismd_core.so (0xb6168000)
	libismd_viddec.so => /lib/libismd_viddec.so (0xb6160000)
	libjson-c.so.2 => /lib/libjson-c.so.2 (0xb6153000)
	libpthread.so.0 => /lib/libpthread.so.0 (0xb6137000)
	libc.so.6 => /lib/libc.so.6 (0xb5f88000)
	libass.so.5 => /volume1/@appstore/Serviio/bin/../lib/libass.so.5 (0xb5f44000)
	librtmp.so.1 => /volume1/@appstore/Serviio/bin/../lib/librtmp.so.1 (0xb5f25000)
	libz.so.1 => /lib/libz.so.1 (0xb5f0c000)
	libgnutls.so.28 => /lib/libgnutls.so.28 (0xb5e02000)
	libbz2.so.1.0 => /lib/libbz2.so.1.0 (0xb5df0000)
	libx264.so.148 => /volume1/@appstore/Serviio/bin/../lib/libx264.so.148 (0xb5c52000)
	libvorbisenc.so.2 => /volume1/@appstore/Serviio/bin/../lib/libvorbisenc.so.2 (0xb5bc0000)
	libvorbis.so.0 => /volume1/@appstore/Serviio/bin/../lib/libvorbis.so.0 (0xb5b87000)
	libspeex.so.1 => /volume1/@appstore/Serviio/bin/../lib/libspeex.so.1 (0xb5b5e000)
	libmp3lame.so.0 => /lib/libmp3lame.so.0 (0xb5ae5000)
	liblzma.so.5 => /lib/liblzma.so.5 (0xb5ab9000)
	libdl.so.2 => /lib/libdl.so.2 (0xb5ab4000)
	libxml2.so.2 => /lib/libxml2.so.2 (0xb5933000)
	libismd_demux.so => /lib/libismd_demux.so (0xb5928000)
	libismd_vidrend.so => /lib/libismd_vidrend.so (0xb591f000)
	libismd_clock.so => /lib/libismd_clock.so (0xb591d000)
	libismd_audio.so => /lib/libismd_audio.so (0xb590e000)
	libismd_videnc.so => /lib/libismd_videnc.so (0xb590a000)
	libismd_vidpproc.so => /lib/libismd_vidpproc.so (0xb5903000)
	libismdmessage.so => /lib/libismdmessage.so (0xb58ff000)
	libsven.so => /lib/libsven.so (0xb57b9000)
	libpal.so => /lib/libpal.so (0xb57b7000)
	libosal.so => /lib/libosal.so (0xb57ae000)
	libplatform_config.so => /lib/libplatform_config.so (0xb57ab000)
	libsystem_utils.so => /lib/libsystem_utils.so (0xb57a8000)
	libismd_clock_recovery.so => /lib/libismd_clock_recovery.so (0xb57a4000)
	/lib/ld-linux.so.2 (0xb77d0000)
	libfribidi.so.0 => /volume1/@appstore/Serviio/bin/../lib/libfribidi.so.0 (0xb5789000)
	libfontconfig.so.1 => /lib/libfontconfig.so.1 (0xb5747000)
	libfreetype.so.6 => /lib/libfreetype.so.6 (0xb5688000)
	libhogweed.so.2 => /lib/libhogweed.so.2 (0xb5657000)
	libnettle.so.4 => /lib/libnettle.so.4 (0xb5623000)
	libgmp.so.10 => /lib/libgmp.so.10 (0xb55ad000)
	libogg.so.0 => /volume1/@appstore/Serviio/bin/../lib/libogg.so.0 (0xb55a4000)
	libpng16.so.16 => /lib/libpng16.so.16 (0xb5567000)
DS214Play> 
 
 
Advertisements

Cross-compiling FFmpeg for Serviio with shared libraries on Synology NAS (for 7 CPU architectures)

This method will build FFmpeg 2.7.1 with the shared libraries (linked with relative paths) required for Serviio DLNA media server, using a Ubuntu/Xubuntu Desktop 14.04 virtual machine, however the same method probably works with many other Linux distributions. The target CPU architectures are ARMv5, ARMv7, ARM hard float ABI with NEON, Intel i686, Intel x64, and PowerPC e500v2.

The >10MB size of the static executable is kind of getting out of hand especially on embedded systems with very limited RAM. Using shared libs means many concurrent instances of FFmpeg can use broadly the same memory footprint, and package distribution binaries can be smaller – our target systems already have libmp3lame, libm, libz, librt, libgmp, libssl, libcrypto, libfreetype, libexpat, and libpthread which add up to several megabytes. I’m also guessing that the OS will decide when to unload them from RAM which could help when FFmpeg is being launched repeatedly in a short period of time (e.g. during library scanning).

The notes below also detail how to compile the Synology fork of FFmpeg 2.0.2 with Intel Evansport SMD (Streaming Media Drivers) hardware transcoding support. This source is itself based upon a fork by Intel which seems to form part of the Evansport SDK. It was not straightforward to compile, and now that I have released Serviio for Synology with hardware transcoding support I’m sharing my method in the hope it can help others. This older FFmpeg needs a patch to fix a long standing bug with DTS audio remuxing (reported by me) where the stream ID was incorrectly set:

--- ffmpeg-2.2.1/libavformat/mpegts.h
+++ ffmpeg-2.2.1-ticket1398/libavformat/mpegts.h
@@ -57,7 +57,8 @@
 #define STREAM_TYPE_VIDEO_DIRAC     0xd1
 
 #define STREAM_TYPE_AUDIO_AC3       0x81
-#define STREAM_TYPE_AUDIO_DTS       0x8a
+#define STREAM_TYPE_AUDIO_DTS       0x82
+#define STREAM_TYPE_AUDIO_TRUEHD    0x83
 
 typedef struct MpegTSContext MpegTSContext;
 
--- ffmpeg-2.2.1/libavformat/mpegtsenc.c
+++ ffmpeg-2.2.1-ticket1398/libavformat/mpegtsenc.c
@@ -311,6 +311,12 @@
         case AV_CODEC_ID_AC3:
             stream_type = STREAM_TYPE_AUDIO_AC3;
             break;
+        case AV_CODEC_ID_DTS:
+            stream_type = STREAM_TYPE_AUDIO_DTS;
+            break;
+        case AV_CODEC_ID_TRUEHD:
+            stream_type = STREAM_TYPE_AUDIO_TRUEHD;
+            break;
         default:
             stream_type = STREAM_TYPE_PRIVATE_DATA;
             break;

Although the unmodified FFmpeg source code will compile successfully for PowerPC CPUs, the FFmpeg binary will core dump when running any command on a video file. I contacted Synology Support for help with this issue back in October 2012 and was given a patch to use at that time which changes the use of a CPU register in the DSP assembly code. The FFmpeg source code has changed a bit recently meaning the patch was no longer valid, but I was able to discover the appropriate location in the code and create a new working patch (code was moved from dsputil_ppc.c to blockdsp.c):

diff -rupN ffmpeg/libavcodec/ppc/blockdsp.c ffmpeg-patched/libavcodec/ppc/blockdsp.c
--- ffmpeg/libavcodec/ppc/blockdsp.c	2015-06-19 21:44:40.000000000 +0100
+++ ffmpeg-patched/libavcodec/ppc/blockdsp.c	2015-07-11 04:06:27.326911100 +0100
@@ -115,8 +115,9 @@ static long check_dcbzl_effect(void)
     memset(fakedata, 0xFF, 1024);
 
     /* Below the constraint "b" seems to mean "address base register"
-     * in gcc-3.3 / RS/6000 speaks. Seems to avoid using r0, so.... */
-    __asm__ volatile ("dcbzl %0, %1" :: "b" (fakedata_middle), "r" (zero));
+     * in gcc-3.3 / RS/6000 speaks. Seems to avoid using r0, so.... 
+    __asm__ volatile ("dcbzl %0, %1" :: "b" (fakedata_middle), "r" (zero)); */
+    __asm__ volatile ("dcbz %0, %1" :: "r" (fakedata_middle), "r" (zero));
 
     for (i = 0; i < 1024; i++)
         if (fakedata[i] == (char) 0)
 
#-----set up Synology toolchain
cd ~/Downloads
#export DL_PATH="http://sourceforge.net/projects/dsgpl/files/DSM%205.0%20Tool%20Chains"
#export DL_PATH="http://sourceforge.net/projects/dsgpl/files/DSM%20Beta%205.2%20Tool%20Chains"
export DL_PATH="http://sourceforge.net/projects/dsgpl/files/DSM%205.2%20Tool%20Chains"
#-----add 32bit binary compatibility to Ubuntu 14.04 LTS (Syno toolchains are 32bit)
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install libc6:i386 libncurses5:i386 libstdc++6:i386
sudo apt-get install git
sudo apt-get install chrpath
#----------------------------------------------------
#-----NOW PASTE ONE OF THE FOLLOWING SIX BLOCKS TO THE TERMINAL, DEPENDING ON YOUR TARGET CPU TYPE
#-----Marvell Kirkwood mv6281/mv6282 (ARMv5te)
#-----Marvell Armada 370/375/XP (ARMv7l FPU)
#-----Mindspeed Comcerto 2000/Marvell Armada 375 (ARM Cortex-A9 NEON)
#-----Freescale PowerQUICC III MPC8533E/QorIQ P1022 (PPC e500v2 FPU)
#-----Intel Atom/Bromolow/Cedarview (i686 SSSE3)
#-----Intel Evansport (i686 SSSE3 various HW decoders, HW H.264 encoder)




#-----Marvell Kirkwood mv6281/mv6282 CPU is based on the ARMv5TE core which has DSP and Thumb instruction support
#-----However using Thumb on ARMv5 results in worse performance
#-----http://www.arm.com/products/processors/technologies/dsp-simd.php
#-----http://www.marvell.com/embedded-processors/kirkwood/assets/88f6282-3_pb.pdf
wget "${DL_PATH}/Marvell%2088F628x%20Linux%202.6.32/6281-gcc464_glibc215_88f6281-GPL.txz"
tar xvJf 6281-gcc464_glibc215_88f6281-GPL.txz
#-----Marvell gave the ARMv5 and ARMv7 toolchains the same name so rename to allow concurrent installations
mv arm-marvell-linux-gnueabi/ arm-none-linux-gnueabi/
#-----these next two packages are needed to build libshine
sudo apt-get install automake
sudo apt-get install libtool
export CROSS_PREFIX=arm-marvell-linux-gnueabi
export TOOLCHAIN=/usr/local/arm-none-linux-gnueabi
export TARGET=arm-marvell-linux-gnueabi
export MARCH="-march=armv5te -mtune=marvell-f -mtune=xscale"
export LAME_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-decoder"
#-----libx264:
#-----http://forum.doom9.org/showthread.php?t=160584
#-----https://mailman.videolan.org/pipermail/x264-devel/2010-December/008093.html
#-----x264 builds with NEON by default because x264 is so slow without NEON (and on any non-NEON chip) as to be useless.
#-----You can of course compile with --disable-asm on such chips, but we don't do it by default because
#-----we don't feel it's necessary to actively support chips on which x264 would be basically useless
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --disable-asm --enable-pic --enable-strip"
#-----FFmpeg:
#-----ARMv5TE CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
#-----something changed in the FFmpeg configure script and now vfp and neon optimizations have to be explicitly disabled for ARMv5TE, which doesn't have those features in any case
export FF_CONFIG="./configure --arch=arm --cpu=armv5te --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-neon --disable-vfp --disable-armv6 --disable-armv6t2 --disable-debug --enable-pthreads --enable-libshine --enable-librtmp --enable-libass --enable-libspeex --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"
#export FF_CONFIG="./configure --arch=arm --cpu=armv5te --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-neon --disable-vfp --disable-armv6 --disable-armv6t2 --disable-debug --enable-pthreads --enable-libshine --enable-librtmp --enable-libass --enable-libspeex --enable-gpl --enable-libx264 --enable-gnutls --enable-nonfree --enable-libfdk_aac --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"
wget https://github.com/savonet/shine/zipball/master
unzip master
cd toots-shine-*
./bootstrap
cd ..
#-----fetch libfdk-aac fixed point math AAC encoder, binaries linked to it cannot be redistributed under GPL
#-----so it is excluded from the FFmpeg binary I built for the Serviio package
wget http://sourceforge.net/projects/opencore-amr/files/fdk-aac/fdk-aac-0.1.4.tar.gz
tar xvzf fdk-aac-0.1.4.tar.gz
cd fdk-aac-0.1.4
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
make
make install
cd ..
 



#-----Marvell Armada 370/XP CPU is based on a dual issue ARMv7 core with Thumb-2, VFPv3-16, but no NEON vector unit
#-----http://www.marvell.com/embedded-processors/armada-300/assets/Marvell_ARMADA_370_SoC.pdf
#-----http://www.arm.com/products/processors/technologies/vector-floating-point.php
#-----Marvell Armada 375 CPU is based on dual ARM Cortex-A9 cores with NEON vector unit, but there is no Synology toolchain with NEON support
#-----Synology seems to have used this toolchain to build DSM for the Armada 375
#-----http://www.marvell.com/embedded-processors/armada-300/assets/ARMADA_375_SoC-01_product_brief.pdf
wget "${DL_PATH}/Marvell%20Armada%20370%20Linux%203.2.40/armada370-gcc464_glibc215_hard_armada-GPL.txz"
tar xvJf armada370-gcc464_glibc215_hard_armada-GPL.txz
export CROSS_PREFIX=arm-marvell-linux-gnueabi
export TARGET=arm-marvell-linux-gnueabi
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
#-----Tune for Marvell PJ4 dual issue core (two instructions per clock)
#-----Thumb-2 can be used on ARMv6 or newer with no performance drop
export MARCH="-march=armv7-a -mcpu=marvell-pj4 -mtune=marvell-pj4 -mhard-float -mfpu=vfpv3-d16 -mthumb"
export LAME_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-decoder"
#-----libx264:
#-----http://forum.doom9.org/showthread.php?t=160584
#-----https://mailman.videolan.org/pipermail/x264-devel/2010-December/008093.html
#-----x264 builds with NEON by default because x264 is so slow without NEON (and on any non-NEON chip) as to be useless.
#-----You can of course compile with --disable-asm on such chips, but we don't do it by default because
#-----we don't feel it's necessary to actively support chips on which x264 would be basically useless
#-----http://lists.busybox.net/pipermail/buildroot/2014-October/107797.html
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --disable-asm --enable-pic --enable-strip"
#-----FFmpeg:
#-----ARMv7 CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=arm --cpu=armv7-a --enable-thumb --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-neon --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"




#-----Mindspeed Comcerto 2000 CPU is based on dual ARM Cortex-A9 cores with NEON vector unit
#-----http://www.mindspeed.com/products/cpe-processors/comcertoreg-2000
#-----http://www.arm.com/products/processors/cortex-a/cortex-a9.php
#-----http://www.arm.com/products/processors/technologies/neon.php
#-----Armada 375 toolchain uses glibc 2.15, Comcerto 2000 uses glibc 2.17 
wget "${DL_PATH}/Mindspeed%20Comcerto%202000%20Linux%203.2.40/comcerto2k-gcc464_glibc217_neon_comcerto-GPL.txz"
tar xvJf comcerto2k-gcc464_glibc217_neon_comcerto-GPL.txz
export CROSS_PREFIX=arm-cortexa9-linux-gnueabi
export TARGET=arm-cortexa9-linux-gnueabi
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
#-----it seems that in general neon should be used as the fpu when present unless there's a specific reason not to use it
export MARCH="-march=armv7-a -mcpu=cortex-a9 -mfpu=neon -mhard-float -mthumb"
export LAME_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-decoder"
#-----libx264:
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --enable-pic --enable-strip"
#-----FFmpeg:
#-----ARMv7 CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=arm --cpu=cortex-a9 --enable-thumb --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"




#-----Freescale PowerQUICC III MPC8533E/QorIQ P1022 CPUs use the PowerPC e500v2 core with Signal Processing Engine (SPE) which is not a classic FPU design, but have no AltiVec vector unit 
#-----Some QorIQ models have e500mc cores with true FPUs but these are not used in 2013 series Synology NAS
#-----http://en.wikipedia.org/wiki/QorIQ
#-----http://cache.freescale.com/files/32bit/doc/fact_sheet/QP1022FS.pdf?fpsp=1
wget "${DL_PATH}/PowerPC%20QorIQ%20Linux%202.6.32/qoriq-gcc4374_eglibc2874_qoriq-GPL.txz"
tar xvJf qoriq-gcc4374_eglibc2874_qoriq-GPL.txz
export CROSS_PREFIX=powerpc-none-linux-gnuspe
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
export TARGET=powerpc-none-linux-gnuspe
export MARCH="-mcpu=8548 -mhard-float -mfloat-gprs=double"
export LAME_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-decoder"
#-----asm disabled since QorIQ has no AltiVec
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --disable-asm --enable-pic --enable-strip"
#-----FFmpeg:#-----PowerPC e500v2 CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=ppc --cpu=e500v2 --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"




#-----With the exception of Evansport (i686), Intel CPUs used in Synology products are all 64bit and SSSE3 capable but existing DSM libs are 32bit at time of writing (DSM 4.1), so use the i686 toolchain rather than x86_64
#-----libx264 requires yasm 1.20
sudo apt-get install yasm
#-----unlike the others this toolchain has an external dependency on libz
sudo apt-get install libz1:i386
wget "${DL_PATH}/Intel%20x86%20Linux%203.2.40%20%28Pineview%29/x64-gcc463_glibc213_i686_patched-GPL.txz"
tar xvJf x64-gcc463_glibc213_i686_patched-GPL.txz
export CROSS_PREFIX=i686-pc-linux-gnu
export TARGET=i686-pc-linux-gnu
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
#-----We don't really care how lame is built since ffmpeg will use the version in DSM.
#-----The DSM version is built without asm optimizations but these only make a 5% difference, and have been known to introduce instability
export LAME_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-decoder"
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --enable-pic --enable-strip"
#-----FFmpeg:
#-----Intel CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=x86 --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"




#-----Intel Evansport with support for hardware decoding of VC-1, H.264, MPEG-4, MPEG2, AAC and hardware encoding of H.264
#-----http://www.anandtech.com/show/8020/synology-ds214play-intel-evansport-almost-done-right/9
#-----http://ukdl.synology.com/download/spk/VideoStation/1.3-0547/
#-----libx264 requires yasm 1.20
sudo apt-get install yasm
wget "${DL_PATH}/Intel%20x86%20Linux%203.2.40%20%28Evansport%29/evansport-gcc463_glibc213_i686_patched-GPL.txz"
tar xvJf evansport-gcc463_glibc213_i686_patched-GPL.txz
#-----Both Intel toolchains the same name so rename to allow concurrent installations
mv i686-pc-linux-gnu evansport-pc-linux-gnu
#-----Synology headers and libs for the Intel Streaming Media Driver support
wget http://sourceforge.net/projects/dsgpl/files/Synology%20NAS%20GPL%20Source/5565branch/evansport-chroot.txz
mkdir evansport-chroot
cd evansport-chroot
tar xvJf ../evansport-chroot.txz
sudo cp -R lib/intelce-utilities/ ../evansport-pc-linux-gnu/lib
sudo cp -R include/intelce-utilities/ ../evansport-pc-linux-gnu/include
cd ..
#end of Intel SMD section
export CROSS_PREFIX=i686-pc-linux-gnu
export TARGET=i686-pc-linux-gnu
export MARCH="-march=atom"
export TOOLCHAIN=/usr/local/evansport-pc-linux-gnu
export LAME_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-decoder"
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --enable-pic --enable-strip"
#-----FFmpeg:
#-----Intel CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure.syno --arch=x86 --cpu=atom --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-libx264 --enable-libh264_smd --enable-smd --enable-gpl --enable-gnutls --pkg-config=pkg-config --extra-version=SMD_enabled_with_DTS_remux_fix-compiled_by_patters_for_Serviio"
#-----implicit function declaration issue for libavcodec/ismd_ffmpeg_audio_util.o, libavcodec/libx264.o, ffmpeg.o
#-----http://stackoverflow.com/questions/11561261/cc1-warnings-being-treated-as-errors
#-----http://stackoverflow.com/questions/13986301/is-gcc-doing-implicit-function-declarations-incorrectly-in-c99-mode
#-----how to workaround an error using make V=1 (re-issue gcc command, removing -Werror=implicit-function-declaration from command line)
#-----http://trac.ffmpeg.org/ticket/1794
#-----ffmpeg_g and ffprobe_g libavcodec/libavcodec.so: undefined reference to `json_object_array_length' used by (libavcodec/syno_trans_loading.c)
#-----add -ljson-c to the linker parameters




#-----Intel Core-i3 CPUs are 64bit and SSSE3 and seem to have their DSM built using x86_64
#-----libx264 requires yasm 1.20
sudo apt-get install yasm
wget "${DL_PATH}/Intel%20x86%20Linux%203.2.40%20%28Pineview%29/x64-gcc473_glibc217_x86_64-GPL.txz"
tar xvJf x64-gcc473_glibc217_x86_64-GPL.txz
export CROSS_PREFIX=x86_64-pc-linux-gnu
export TARGET=x86_64-pc-linux-gnu
export TOOLCHAIN=/usr/local/${CROSS_PREFIX}
#-----We don't really care how lame is built since ffmpeg will use the version in DSM.
#-----The DSM version is built without asm optimizations but these only make a 5% difference, and have been known to introduce instability
export LAME_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-decoder"
export X264_CONFIG="./configure --prefix=${TOOLCHAIN} --host=${TARGET} --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --enable-shared --enable-pic --enable-strip"
#-----FFmpeg:
#-----Intel CPU-specific options (based on inspecting 'configure' script https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes ${CROSS_PREFIX}-pkg-config which doesn't exist, and then librtmp won't be detected
export FF_CONFIG="./configure --arch=x86 --enable-cross-compile --cross-prefix=${TOOLCHAIN}/bin/${CROSS_PREFIX}- --target-os=linux --prefix=${TOOLCHAIN} --enable-shared --disable-static --enable-pic --disable-ffplay --disable-ffserver --disable-debug --enable-pthreads --enable-libmp3lame --enable-librtmp --enable-libass --enable-libspeex --enable-gpl --enable-libx264 --enable-gnutls --pkg-config=pkg-config --extra-version=compiled_by_patters_for_Serviio"





#----------------------------------------------------
#-----script continues
sudo mv `echo $TOOLCHAIN | sed -r "s%^.*/(.*$)%\1%"` /usr/local
#-----some of the toolchains have bad permissions
sudo chmod -R 0755 ${TOOLCHAIN}
export PATH=${TOOLCHAIN}/bin:$PATH
export AR=${TOOLCHAIN}/bin/${CROSS_PREFIX}-ar
export AS=${TOOLCHAIN}/bin/${CROSS_PREFIX}-as
export CC=${TOOLCHAIN}/bin/${CROSS_PREFIX}-gcc
export CXX=${TOOLCHAIN}/bin/${CROSS_PREFIX}-g++
export LD=${TOOLCHAIN}/bin/${CROSS_PREFIX}-ld
export LDSHARED="${TOOLCHAIN}/bin/${CROSS_PREFIX}-gcc -shared "
export RANLIB=${TOOLCHAIN}/bin/${CROSS_PREFIX}-ranlib
export CFLAGS="-I${TOOLCHAIN}/include -O3 ${MARCH}"
export LDFLAGS="-L${TOOLCHAIN}/lib"
export PKG_CONFIG_PATH="${TOOLCHAIN}/lib/pkgconfig"


#-----fetch Synology's DSM 5565 sources for certain libraries we want to link against
wget https://dl.dropboxusercontent.com/u/1188556/DSM5565-src.tar.xz
tar xvJf DSM5565-src.tar.xz

#-----libz shared lib (toolchain only has static lib)
cd zlib-1.x
./configure --prefix=${TOOLCHAIN}
#-----owing to a bug in the configure script, libz cross compiles without a SONAME (check it with objdump -x)
#-----http://forums.gentoo.org/viewtopic-p-7156392.html
sed -i "s/\(^LDSHARED=.*$\)/\1 -Wl,-soname,libz.so.1,--version-script,zlib.map/" Makefile
make
make install
cd ..

#-----LAME shared lib
cd lame-398
$LAME_CONFIG
make
make install
cd ..

#-----expat shared lib
cd expat-2.x
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
make
make install
cd ..

#-----freetype shared lib
cd freetype-2.x
#-----disable external zlib library since it appears Synology compiled DSM-included libfreetype binary this way
#-----failure to do this results in a hang during fc-cache generation - this took a significant effort to determine
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --with-zlib=no --enable-shared --disable-static
make
make install
cd ..

#-----shine shared lib for ARMv5 only (no FPU)
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && cd toots-shine-*
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && make
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && make install
[ "${TOOLCHAIN}" == "/usr/local/arm-none-linux-gnueabi" ] && cd ..

#-----misc shared libs for Intel Evansport FFmpeg build only
#-----use libx264 version from Synology sources since the Evansport ffmpeg may have specific dependencies on this version
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cd x264
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && $X264_CONFIG
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && make
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && make install
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cd ..
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cd libxml2-2.x
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --without-python
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && make
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && make install
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cd ..
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cd json-c-0.x
#-----undefined reference to `rpl_malloc' when linking ffmpeg
#-----http://rickfoosusa.blogspot.co.uk/2011/11/howto-fix-undefined-reference-to.html 
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && ac_cv_func_malloc_0_nonnull=yes ac_cv_func_realloc_0_nonnull=yes ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu  --enable-shared --disable-static
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && make
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && make install
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cd ..

#-----fribidi shared lib
wget http://fribidi.org/download/fribidi-0.19.6.tar.bz2
tar xvjf fribidi-0.19.6.tar.bz2
cd fribidi-0.19.6
#-----patch fribidi source since it won't compile - some sort of page size function is no longer available
#-----error on Intel: fribidi-run.c:70: error: 'PAGE_SIZE' undeclared (first use in this function)
#-----http://armbedded.eu/node/56
#-----http://lists.debian.org/debian-glibc/2006/10/msg00169.html
#-----http://my.safaribooksonline.com/book/operating-systems-and-server-administration/linux/0596009585/advanced-file-i-o/mapping_files_into_memory
[ "${CROSS_PREFIX}" == "i686-pc-linux-gnu" ] && sed -i "s|include <asm/page.h>|include <unistd.h>\n#   define PAGE_SIZE sysconf(_SC_PAGESIZE)|" lib/common.h
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
make
make install
cd ..

#-----fontconfig shared lib
wget http://www.freedesktop.org/software/fontconfig/release/fontconfig-2.11.1.tar.gz
tar xvzf fontconfig-2.11.1.tar.gz
cd fontconfig-2.11.1
LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,\'\$\$ORIGIN/../lib:\$\$ORIGIN\' ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
#-----correct some non-standard library linking behaviour
sed -i "s/^hardcode_into_libs=yes/hardcode_into_libs=no/" libtool
make
make install
cd ..

#-----libass shared lib
wget https://github.com/libass/libass/releases/download/0.12.1/libass-0.12.1.tar.xz
tar xvJf libass-0.12.1.tar.xz
cd libass-0.12.1
LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,\'\$\$ORIGIN\' ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
#-----correct some non-standard library linking behaviour
sed -i "s/^hardcode_into_libs=yes/hardcode_into_libs=no/" libtool
make
make install
cd ..
#-----Although libass would link correctly to older FFmpeg versions, this mod is now necessary:
#-----http://ffmpeg.org/pipermail/ffmpeg-user/2012-November/010906.html
#-----no longer needed, note here in case of regression in future versions 
#sed -i -r "s/(^Libs: .*$)/\1 -lfontconfig -lfribidi -lfreetype -lexpat/" $TOOLCHAIN/lib/pkgconfig/libass.pc

#-----libx264 shared lib
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || wget ftp://ftp.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || tar xvjf last_x264.tar.bz2
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || cd x264-snapshot-*
#-----NEON ASM needs to be built by GCC assembler not AS
[ "${TOOLCHAIN}" == "/usr/local/arm-cortexa9-linux-gnueabi" ] && export AS=${TOOLCHAIN}/bin/${CROSS_PREFIX}-gcc
#-----intel ASM needs to be built by yasm assembler
[ "${TOOLCHAIN}" == "/usr/local/i686-pc-linux-gnu" ] && export AS=yasm
[ "${TOOLCHAIN}" == "/usr/local/x86_64-pc-linux-gnu" ] && export AS=yasm
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || $X264_CONFIG
#-----back out assembler changes
[ "${TOOLCHAIN}" == "/usr/local/arm-cortexa9-linux-gnueabi" ] && export AS=${TOOLCHAIN}/bin/${CROSS_PREFIX}-as
[ "${TOOLCHAIN}" == "/usr/local/i686-pc-linux-gnu" ] && export AS=${TOOLCHAIN}/bin/${CROSS_PREFIX}-as
[ "${TOOLCHAIN}" == "/usr/local/x86_64-pc-linux-gnu" ] && export AS=${TOOLCHAIN}/bin/${CROSS_PREFIX}-as
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || make
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || make install
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || cd ..

#-----GMP shared lib
wget https://gmplib.org/download/gmp/gmp-6.0.0a.tar.xz
tar -xJf gmp-6.0.0a.tar.xz
cd gmp-6.0.0
#-----disable ARM Thumb - GMP doesn't compile in Thumb mode even using this patch
#-----https://gmplib.org/list-archives/gmp-discuss/2014-March/005537.html
export MARCH=`echo $MARCH | sed -e "s/ -mthumb//"`
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || export CFLAGS="-I${TOOLCHAIN}/include -O3 ${MARCH}"
[ "${TOOLCHAIN}" == "/usr/local/powerpc-none-linux-gnuspe" ] && mv ${TOOLCHAIN}/bin/flex ${TOOLCHAIN}/bin/flex.old
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
make
make install
#-----re-enable thumb-2 mode where applicable
[ "${TOOLCHAIN}" == "/usr/local/arm-cortexa9-linux-gnueabi" ] && export MARCH="${MARCH} -mthumb" 
[ "${TOOLCHAIN}" == "/usr/local/arm-marvell-linux-gnueabi" ] && export MARCH="${MARCH} -mthumb"
[ "${TOOLCHAIN}" == "/usr/local/armv7-marvell-linux-gnueabi-hard" ] && export MARCH="${MARCH} -mthumb"
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || export CFLAGS="-I${TOOLCHAIN}/include -O3 ${MARCH}" 
cd ..

#-----nettle shared lib
#-----version compatibility issues with gnutls: https://crux.nu/bugs/?do=details&task_id=1023
wget https://ftp.gnu.org/gnu/nettle/nettle-2.7.1.tar.gz
tar xvzf nettle-2.7.1.tar.gz
cd nettle-2.7.1
LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,\'\$\$ORIGIN\' ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static --disable-openssl
make
make install
#-----this will fail to complete but it's not important: *** No rule to make target `../libnettle.a', needed by `sexp-conv'. Stop.
cd ..

#-----gnutls shared lib
wget ftp://ftp.gnutls.org/gcrypt/gnutls/v3.3/gnutls-3.3.14.tar.xz
tar -xJf gnutls-3.3.14.tar.xz 
cd gnutls-3.3.14
#-----use DSM's existing root CA certs bundle
LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,\'\$\$ORIGIN\' ./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --with-default-trust-store-file=/etc/ssl/certs/ca-certificates.crt --enable-threads=posix --disable-doc --enable-shared --disable-static
#-----correct some non-standard library linking behaviour
sed -i "s/^hardcode_into_libs=yes/hardcode_into_libs=no/" libtool
make
make install
sed -i -r "s/(^Libs: .*$)/\1 -lnettle -lhogweed -lgmp/" $TOOLCHAIN/lib/pkgconfig/gnutls.pc
cd ..

#-----librtmp shared lib
git clone git://git.ffmpeg.org/rtmpdump
cd rtmpdump
make CROSS_COMPILE=${TOOLCHAIN}/bin/${CROSS_PREFIX}- SYS=posix prefix=${TOOLCHAIN} CRYPTO=GNUTLS INC=-I${TOOLCHAIN}/include XLDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,\'\$\$ORIGIN\'
#------librtmp.pc will have the wrong lib dependencies defined unless GNUTLS is specified again here
make install prefix=${TOOLCHAIN} CRYPTO=GNUTLS
cd ..

#-----libspeex shared lib
wget http://downloads.xiph.org/releases/speex/speex-1.2rc2.tar.gz
tar xvzf speex-1.2rc2.tar.gz
cd speex-1.2rc2
./configure --prefix=${TOOLCHAIN} --host=${TARGET} --build=x86_64-linux-gnu --enable-shared --disable-static
make
make install
cd ..

#-----FFmpeg (Evansport uses a separate Synology-modified source bundle)
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || wget https://www.ffmpeg.org/releases/ffmpeg-2.7.1.tar.gz
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || tar xvzf ffmpeg-2.7.1.tar.gz
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] || cd ffmpeg-2.7.1
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && wget https://dl.dropboxusercontent.com/u/1188556/DSM5565-ffmpeg-2.0.x-src.tar.xz
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && tar xvJf DSM5565-ffmpeg-2.0.x-src.tar.xz
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && cd ffmpeg-2.0.x

#-----Apply DTS audio remux fix for hardware players (incorrect stream ID was set in older versions of FFmpeg)
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && wget http://dl.dropboxusercontent.com/u/1188556/ffmpeg-ticket1398.patch
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && patch --verbose -p1 < ffmpeg-ticket1398.patch

#-----PowerPC-specific fix originally provided by Synology Support in Oct 2012, adapted after code re-org by ffmpeg
[ "${CROSS_PREFIX}" == "powerpc-none-linux-gnuspe" ] && wget http://dl.dropboxusercontent.com/u/1188556/ffmpeg-syno-ppc.patch
[ "${CROSS_PREFIX}" == "powerpc-none-linux-gnuspe" ] && patch --verbose -p1 < ffmpeg-syno-ppc.patch

#-----Evansport SMD driver scheduler uses inline asm which breaks compilation without -fasm
#-----http://stackoverflow.com/questions/18574943/gcc-inline-assembler-implicit-function-declaration-on-powerpc-arch
#-----http://ffmpeg.org/pipermail/ffmpeg-devel/2008-October/056533.html
#-----http://www.tldp.org/HOWTO/Assembly-HOWTO/gcc.html
#-----we also need to add the intelce-utlities locations of the SMD libraries
#-----libx264 will fail to compile with this added to include path, so only add it just before compiling ffmpeg
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] \
  && export CFLAGS="${CFLAGS} -fasm -I${TOOLCHAIN}/include/json-c -I${TOOLCHAIN}/include/intelce-utilities -I${TOOLCHAIN}/include/intelce-utilities/linux_user"

#-----Evansport SMD functionality is disabled by default
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && sed -i "1i#define SYNO_ENABLE_SMD" synoconfig.h
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && sed -i "1i#define SYNO_EVANSPORT" synoconfig.h

#-----set library linker to use relative library search path (../lib and .)
#-----tricky shell escaping of $ORIGIN is required http://itee.uq.edu.au/~daniel/using_origin/
#-----http://stackoverflow.com/questions/6562403/i-dont-understand-wl-rpath-wl
#-----however although FFmpeg gets a correct rpath, the downstream libraries get a value of "RIGIN/../lib:RIGIN"
#-----owing to some additional variable substitution happening - easier to build with XORIGIN and use chrpath later
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] \
  || LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-rpath,XORIGIN/../lib:XORIGIN,-rpath-link,${TOOLCHAIN}/lib ${FF_CONFIG} \
  && LDFLAGS=-Wl,-L${TOOLCHAIN}/lib,-L${TOOLCHAIN}/lib/intelce-utilities,-rpath,XORIGIN/../lib:XORIGIN,-rpath-link,${TOOLCHAIN}/lib,-rpath-link,${TOOLCHAIN}/lib/intelce-utilities ${FF_CONFIG}

#-----external libs (librtmp, libass) don't seem to link to ffmpeg (check ffmpeg binary with objdump -x)
#-----this is in fact normal because LDFLAGS as defined in config.mak contains '--as-needed'
#-----https://wiki.gentoo.org/wiki/Project:Quality_Assurance/As-needed
#-----e.g. FFmpeg does not contain any symbols from librtmp, but libavformat does
#-----use ldd on the target system and the full dependency chain will be shown
make
make install

#-----remove intelce-utilities from include path
[ "${TOOLCHAIN}" == "/usr/local/evansport-pc-linux-gnu" ] && export CFLAGS="-I${TOOLCHAIN}/include -O3 ${MARCH}"

mkdir native-${CROSS_PREFIX}
cd native-${CROSS_PREFIX}

#-----evansport FFmpeg 2.0.2
#-----fix up rpath settings
sudo chrpath -r '$ORIGIN/../lib:$ORIGIN' ${TOOLCHAIN}/bin/ffmpeg
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavcodec.so.55
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavdevice.so.55
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavfilter.so.3
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavformat.so.55
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavutil.so.52
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libpostproc.so.52
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libswresample.so.0
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libswscale.so.2
cp ${TOOLCHAIN}/lib/libavcodec.so.55 .
cp ${TOOLCHAIN}/lib/libavdevice.so.55 .
cp ${TOOLCHAIN}/lib/libavfilter.so.3 .
cp ${TOOLCHAIN}/lib/libavformat.so.55 .
cp ${TOOLCHAIN}/lib/libavutil.so.52 .
cp ${TOOLCHAIN}/lib/libpostproc.so.52 .
cp ${TOOLCHAIN}/lib/libswresample.so.0 .
cp ${TOOLCHAIN}/lib/libswscale.so.2 .
cp ${TOOLCHAIN}/lib/libx264.so.119 .

#-----FFmpeg 2.7.1
#-----fix up rpath settings
sudo chrpath -r '$ORIGIN/../lib:$ORIGIN' ${TOOLCHAIN}/bin/ffmpeg
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavcodec.so.56
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavdevice.so.56
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavfilter.so.5
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavformat.so.56
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libavutil.so.54
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libpostproc.so.53
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libswresample.so.1
sudo chrpath -r '$ORIGIN' ${TOOLCHAIN}/lib/libswscale.so.3
cp ${TOOLCHAIN}/lib/libavcodec.so.56 .
cp ${TOOLCHAIN}/lib/libavdevice.so.56 .
cp ${TOOLCHAIN}/lib/libavfilter.so.5 .
cp ${TOOLCHAIN}/lib/libavformat.so.56 .
cp ${TOOLCHAIN}/lib/libavutil.so.54 .
cp ${TOOLCHAIN}/lib/libpostproc.so.53 .
cp ${TOOLCHAIN}/lib/libswresample.so.1 .
cp ${TOOLCHAIN}/lib/libswscale.so.3 .
cp ${TOOLCHAIN}/lib/libx264.so.146 .

cp ${TOOLCHAIN}/bin/ffmpeg .
cp ${TOOLCHAIN}/bin/fc-cache .
cp ${TOOLCHAIN}/lib/libass.so.5 .
cp ${TOOLCHAIN}/lib/libfontconfig.so.1 .
cp ${TOOLCHAIN}/lib/libfribidi.so.0 .
cp ${TOOLCHAIN}/lib/libnettle.so.4 .
cp ${TOOLCHAIN}/lib/libhogweed.so.2 .
cp ${TOOLCHAIN}/lib/libgnutls.so.28 .
cp ${TOOLCHAIN}/lib/librtmp.so.1 .
cp ${TOOLCHAIN}/lib/libspeex.so.1 .
[ ${TOOLCHAIN} == "/usr/local/arm-none-linux-gnueabi" ] && cp ${TOOLCHAIN}/lib/libshine.so.3 .
#cp ${TOOLCHAIN}/lib/libfdk-aac.so.1 .
sudo chmod +x *
sudo chown root:root *
XZ_OPT=-9 tar -cvJf ffmpeg-${CROSS_PREFIX}.tar.xz *
 

Here’s how the library dependencies look. There are no links to any libraries in /opt, and DSM-bundled libraries in /lib are linked to where possible. All the other new libraries are kept within the Serviio lib folder (../lib relative to the ffmpeg binary).

DS111> ldd /var/packages/Serviio/target/bin/ffmpeg
	libavdevice.so.56 => /volume1/@appstore/Serviio/bin/../lib/libavdevice.so.56 (0x40031000)
	libavfilter.so.5 => /volume1/@appstore/Serviio/bin/../lib/libavfilter.so.5 (0x4004f000)
	libavformat.so.56 => /volume1/@appstore/Serviio/bin/../lib/libavformat.so.56 (0x40174000)
	libavcodec.so.56 => /volume1/@appstore/Serviio/bin/../lib/libavcodec.so.56 (0x40321000)
	libpostproc.so.53 => /volume1/@appstore/Serviio/bin/../lib/libpostproc.so.53 (0x4138d000)
	libswresample.so.1 => /volume1/@appstore/Serviio/bin/../lib/libswresample.so.1 (0x413ad000)
	libswscale.so.3 => /volume1/@appstore/Serviio/bin/../lib/libswscale.so.3 (0x413d1000)
	libavutil.so.54 => /volume1/@appstore/Serviio/bin/../lib/libavutil.so.54 (0x41449000)
	libm.so.6 => /lib/libm.so.6 (0x414c2000)
	libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x4156b000)
	libpthread.so.0 => /lib/libpthread.so.0 (0x41587000)
	libc.so.6 => /lib/libc.so.6 (0x415b0000)
	libass.so.5 => /volume1/@appstore/Serviio/bin/../lib/libass.so.5 (0x416f3000)
	librtmp.so.1 => /volume1/@appstore/Serviio/bin/../lib/librtmp.so.1 (0x41726000)
	libz.so.1 => /lib/libz.so.1 (0x4174e000)
	libgnutls.so.28 => /volume1/@appstore/Serviio/bin/../lib/libgnutls.so.28 (0x41772000)
	libx264.so.146 => /volume1/@appstore/Serviio/bin/../lib/libx264.so.146 (0x4187a000)
	libspeex.so.1 => /volume1/@appstore/Serviio/bin/../lib/libspeex.so.1 (0x419ea000)
	libshine.so.3 => /volume1/@appstore/Serviio/bin/../lib/libshine.so.3 (0x41a14000)
	librt.so.1 => /lib/librt.so.1 (0x41a2e000)
	/lib/ld-linux.so.3 (0x40000000)
	libfribidi.so.0 => /volume1/@appstore/Serviio/bin/../lib/libfribidi.so.0 (0x41a45000)
	libfontconfig.so.1 => /volume1/@appstore/Serviio/bin/../lib/libfontconfig.so.1 (0x41a6c000)
	libexpat.so.1 => /lib/libexpat.so.1 (0x41ab9000)
	libfreetype.so.6 => /lib/libfreetype.so.6 (0x41adb000)
	libhogweed.so.2 => /volume1/@appstore/Serviio/bin/../lib/libhogweed.so.2 (0x41b7e000)
	libnettle.so.4 => /volume1/@appstore/Serviio/bin/../lib/libnettle.so.4 (0x41bb5000)
	libgmp.so.10 => /lib/libgmp.so.10 (0x41bfc000)
	libbz2.so.1.0 => /lib/libbz2.so.1.0 (0x41c6b000)
	libpng16.so.16 => /lib/libpng16.so.16 (0x41c7c000)
DS111>
 

Here’s how the even more complex Evansport build with hardware transcoding support looks:

DS214Play> ldd /var/packages/Serviio/target/bin/ffmpeg
	linux-gate.so.1 =>  (0xffffe000)
	libavdevice.so.55 => /volume1/@appstore/Serviio/bin/../lib/libavdevice.so.55 (0xb775c000)
	libavfilter.so.3 => /volume1/@appstore/Serviio/bin/../lib/libavfilter.so.3 (0xb767d000)
	libavformat.so.55 => /volume1/@appstore/Serviio/bin/../lib/libavformat.so.55 (0xb74fd000)
	libavcodec.so.55 => /volume1/@appstore/Serviio/bin/../lib/libavcodec.so.55 (0xb677b000)
	libpostproc.so.52 => /volume1/@appstore/Serviio/bin/../lib/libpostproc.so.52 (0xb674b000)
	libswresample.so.0 => /volume1/@appstore/Serviio/bin/../lib/libswresample.so.0 (0xb6733000)
	libswscale.so.2 => /volume1/@appstore/Serviio/bin/../lib/libswscale.so.2 (0xb66c9000)
	libavutil.so.52 => /volume1/@appstore/Serviio/bin/../lib/libavutil.so.52 (0xb6687000)
	libffmpeg_plugin.so => /lib/libffmpeg_plugin.so (0xb6672000)
	libm.so.6 => /lib/libm.so.6 (0xb6648000)
	libjson-c.so.2 => /lib/libjson-c.so.2 (0xb663d000)
	libpthread.so.0 => /lib/libpthread.so.0 (0xb6622000)
	libc.so.6 => /lib/libc.so.6 (0xb64aa000)
	libismd_core.so => /lib/libismd_core.so (0xb649d000)
	libismd_viddec.so => /lib/libismd_viddec.so (0xb6494000)
	librt.so.1 => /lib/librt.so.1 (0xb648b000)
	libass.so.5 => /volume1/@appstore/Serviio/bin/../lib/libass.so.5 (0xb645f000)
	librtmp.so.1 => /volume1/@appstore/Serviio/bin/../lib/librtmp.so.1 (0xb6443000)
	libz.so.1 => /lib/libz.so.1 (0xb642d000)
	libgnutls.so.28 => /volume1/@appstore/Serviio/bin/../lib/libgnutls.so.28 (0xb6306000)
	libx264.so.119 => /volume1/@appstore/Serviio/bin/../lib/libx264.so.119 (0xb61b3000)
	libspeex.so.1 => /volume1/@appstore/Serviio/bin/../lib/libspeex.so.1 (0xb6193000)
	libmp3lame.so.0 => /lib/libmp3lame.so.0 (0xb6121000)
	libdl.so.2 => /lib/libdl.so.2 (0xb611c000)
	libxml2.so.2 => /lib/libxml2.so.2 (0xb5fc5000)
	libismd_demux.so => /lib/libismd_demux.so (0xb5fba000)
	libismd_vidrend.so => /lib/libismd_vidrend.so (0xb5fb2000)
	libismd_clock.so => /lib/libismd_clock.so (0xb5fb0000)
	libismd_audio.so => /lib/libismd_audio.so (0xb5fa1000)
	libismd_videnc.so => /lib/libismd_videnc.so (0xb5f9d000)
	libismd_vidpproc.so => /lib/libismd_vidpproc.so (0xb5f96000)
	libismdmessage.so => /lib/libismdmessage.so (0xb5f93000)
	libsven.so => /lib/libsven.so (0xb5e53000)
	libpal.so => /lib/libpal.so (0xb5e51000)
	libosal.so => /lib/libosal.so (0xb5e49000)
	libplatform_config.so => /lib/libplatform_config.so (0xb5e46000)
	libsystem_utils.so => /lib/libsystem_utils.so (0xb5e43000)
	libismd_clock_recovery.so => /lib/libismd_clock_recovery.so (0xb5e40000)
	/lib/ld-linux.so.2 (0xb7768000)
	libfribidi.so.0 => /volume1/@appstore/Serviio/bin/../lib/libfribidi.so.0 (0xb5e27000)
	libfontconfig.so.1 => /volume1/@appstore/Serviio/bin/../lib/libfontconfig.so.1 (0xb5de4000)
	libexpat.so.1 => /lib/libexpat.so.1 (0xb5dbc000)
	libfreetype.so.6 => /lib/libfreetype.so.6 (0xb5d08000)
	libhogweed.so.2 => /volume1/@appstore/Serviio/bin/../lib/libhogweed.so.2 (0xb5cdb000)
	libnettle.so.4 => /volume1/@appstore/Serviio/bin/../lib/libnettle.so.4 (0xb5ca3000)
	libgmp.so.10 => /lib/libgmp.so.10 (0xb5c33000)
	liblzma.so.5 => /lib/liblzma.so.5 (0xb5c0d000)
	libbz2.so.1.0 => /lib/libbz2.so.1.0 (0xb5bfc000)
	libpng16.so.16 => /lib/libpng16.so.16 (0xb5bc4000)
DS214Play> 

Building the Intel EMGD display driver for Sony VAIO P with fully working backlight control

Background

The Windows 7 driver for the GMA 500 GPU has not been updated for nearly two years now (v2030 from September 2010). According to this document Intel will only support and continue to maintain the EMGD driver going forward. This is a driver for Linux and Windows primarily for embedded systems, but unfortunately its target audience is system manufacturers and not end users (it’s distributed as a driver build kit). You need quite a detailed technical understanding of the hardware you’re creating the driver for, in particular the LCD panel specifications. Sony are unlikely to provide new driver builds for a three year old laptop, and it will most likely be needed for Windows 8 compatibility. I seem to remember reading that the Windows 8 Release Preview will not accept the GMA 500 Windows 7 driver. The EMGD driver does also have one big advantage in that it includes an OpenGL ICD, which the Windows 7 GMA 500 driver has always lacked.

Thanks in part to ‘viewtiful’ on the Pocketables forum having shared the DTD details for the 1600×768 panel, several people (myself included) had built prior versions of EMGD for the VAIO P, but no one was able to get the LCD backlight working correctly. The onscreen control provided by Sony Shared Library has 8 different levels, and it would turn off the backlight completely at levels 1-3. Experimenting with building new drivers is an extremely slow and painstaking process, especially when you’re not very clear on which values may need tweaking, but I’m pleased to say that I finally got all 8 brightness levels working this evening. And rather than keeping that knowledge secret, I’m sharing it here so that other Vaio users can build their own EMGD drivers for future release versions.

Download

Here is my pre-built driver:
Intel_EMGD_1.16_VaioP_Windows7_v3228_patters.zip

Method

Download and install Intel EMGD (version 1.16 from November 2012 is the latest at the time of writing). Launch the emgd-ced shortcut it has created on your desktop. This will start the java builder application.

Firstly create a new DTD called 1600×768@60Hz with settings as shown. Don’t worry about the greyed out values at the bottom of the screenshot – they’re not used.

New-dtd-for-vaio-p

Next create a new configuration called 16x7Sony like so:

EMGD-vaio-p-config1

Define the LVDS port name as MID (the name the regular GMA 500 driver uses), select the options as shown, taking care to select the custom DTD you just created:

EMGD-vaio-p-config2

In that same screen, click the Attributes button and set the Inverter Frequency to 300. Many thanks to Kirk over at the Intel Embedded Communities Forum for helping me to home in on this being the crucial setting. There are several mentions in the EMGD documentation of a reference value of 20300 which turns out to be incorrect for the VAIO P’s screen. I spent hours searching high and low in vain for a datasheet for this LCD panel (a Toshiba LT080EE04000). Eventually I discovered on the Notebook Review forum that a user called jeonghun had created an EMGD 1.10 build crucially with all eight backlight levels working for the VAIO X laptop which also has a GMA 500, though with a different 1366×768 panel. Since at this point I knew what to look for I opened his driver inf and discovered the magic value of 300. I took a guess that the motherboard-to-LCD circuitry would probably be similar for both models of VAIO.

EMGD-vaio-p-config3-attributes

Click Finish to close that window, and now click on Flat Panel Settings. The VAIO P panel is an 18bit panel. I can’t remember exactly, but I think all these values are the defaults:

EMGD-vaio-p-config4-panel-settings

Now that we’re finished with the LVDS settings (the built-in screen), click Next to move on to configuring the sDVO external monitor connection. Name it Monitor to keep it consistent with the Windows 7 GMA 500 driver. We don’t need any customization other than what is shown in this screenshot:

EMGD-vaio-p-config5-sDVO

The final screen after this relates to building a video BIOS which we aren’t interested in so leave these settings on the defaults. Once finished, create a new package called SonyVaioP:

EMGD-vaio-p-package

Finally while selecting the package, click on Generate Installation in the toolbar. This will create your zipped driver which can be found in:
C:\IEMGD\IEMGD_1_16\workspace\installation\SonyVaioP.pkg_installation\IEMGD_HEAD_Windows7

Serviio 1.9 package for Synology NAS

Serviio 1.6 in DSM Package Center

Running the Serviio DLNA server on a NAS is a very efficient solution. It allows all your media to be constantly available to all your devices, all without the need for a dedicated media PC. Most TV and Bluray players are already capable media renderers – so indexing the library, retrieving metadata, and streaming the content are where Serviio fits in. Device support is continually improved by a community of contributors, and this crowd-sourced aspect was what initially drew me to the project, leading me to create the Sony Bluray device profile back in 2010. Serviio can also connect to online sources of content such as catch-up TV portals and allow fuss free content playback without advertising, even on devices which lack native support. These online plugins are also community maintained.

This new version of the Synology package updates Serviio to version 1.9 which replaces the Flash Player dependency in Media Browser with an HTML5 player (release notes). Serviio 1.7 brought audio track selection preferences, and automatic subtitle downloading. The most significant enhancement from version 1.6 onwards is the new web management console which removes the need to install the separate Serviio Console application on a computer. The web console uses a modern adaptive design which works well on mobile devices, and it is now integrated with DSM so you will see its icon in the application menu when the package is running:

Serviio-DSM-integration
Serviio 1.6 web console
The package supports hardware transcoding on the DS214play and DS415play with Intel Evansport media processor. This support required substantial personal effort and was made possible by the very kind donation of a new DS214play unit from MrK/Boretom a fellow package maintainer for ASUStor devices.

 

Limitations

If you use a TV, Bluray or media player bought in the last few years it is likely to have very good format support. In this case even a low specification NAS will be adequate for streaming most video content. There are some limitations however, in particular with video transcoding.

Serviio’s MediaBrowser is a Pro version only feature, and is designed to allow direct playback of media on tablet devices without the need for dedicated apps. Please note that Apple iOS devices require video in H.264 and audio in stereo AAC format when streaming. With the exception of the Play models already mentioned, most Synology NAS models lack the CPU power to transcode video into H.264 in realtime. Even if the source video is already H.264, ARMv5 family CPUs (which lack an FPU) in the older models lack the power even to transcode AAC audio in realtime without libfdk_aac. Unfortunately I am unable to distribute an FFmpeg binary compiled against this library under the terms of its software license.

Ever since Serviio version 1.2 renderers that do not natively support subtitles via DLNA can have them burned into the video during transcoding, but as already explained a NAS usually lacks the CPU power to do this (more info on subs here). If you absolutely need hard subs for a particular film, you could start playback on your device then stop it and Serviio will continue transcoding. Then you will be able to try again in a few hours since it will play from the transcode cache folder. Newer TVs tend to support inline SRT subs, but for those with older models I can recommend the PlayStation 4 Media Player as a competent DLNA renderer with inline subs support.

I was able to compile FFmpeg for all seven supported architectures (ARMv5, ARMv7, ARM with NEON, Intel i686, Intel x64, Intel Evansport media processor, and PowerPC e500v2) with the additional libraries Serviio requires while using the libs included within DSM as far as possible. I have published my compilation methods to make the process easier for others in future since parts of it were difficult to figure out. Only the Intel CPU or higher end Annapurna Alpine ARM CPUs are likely to be of any practical use transcoding to H.264, since the other CPU types lack vector units (no AltiVec in QorIQ/PowerQUICC, and no NEON in Armada 370/XP).

 

Synology Package Installation

  • In Synology DSM’s Package Center, click Settings and add my package repository:
    Add Package Repository
  • The repository will push its certificate automatically to the NAS, which is used to validate package integrity. Set the Trust Level to Synology Inc. and trusted publishers:
    Trust Level
  • Serviio now requires Java 8 for OS-native filesystem watching, so you will need to install my Java SE Embedded package first if you have not already done so. Read the instructions on that page carefully too.
  • Now browse the Community section in Package Center to install Serviio:
    Community-packages
    Community packages are not listed in the All category for some reason. The repository only displays packages which are compatible with your specific model of NAS. If you don’t see Serviio in the list, then either your NAS model or your DSM version are not supported at this time. DSM 6.0 is the minimum supported version for this package.
  • When Serviio is started for the first time, a plugins folder will be created in the public shared folder (usually /volume1/public/serviio/plugins/). Download any Serviio online content plugins that you require and place the .groovy files in that location.
  • If you need subtitle support for glyphs not present in the default DejaVu fonts, add additional fonts to the following folder inside your NAS’s public shared folder (usually /volume1/public/serviio/fonts/).
 

Notes

  • You should reserve an IP address for your NAS (most home broadband routers will let you do this in the DHCP options), or use a static IP address. This will prevent Serviio from appearing multiple times in the menus of your renderer devices as its IP changes.
  • In the console disable ‘Generate thumbnails for local videos’ in the Metadata tab. Failure to do this can make adding videos to your library very slow on older NAS systems. With this disabled Serviio will still fetch thumbnail images automatically from the online databases.
  • Don’t alter the transcoded files location on the Transcoding tab, it’s already set to a sensible location for Synology systems. This particular folder is deleted each time your NAS restarts, and Serviio cleans up its temp files automatically in any case.
  • When adding folders to the media library use the Browse button. This will show the root of the entire NAS Linux filesystem, so you will find your DSM shared folders inside /volume1.
  • If you’re upgrading from a previous Serviio version you should check for updates of your online content plugins.
  • MediaBrowser (Pro only feature) can be opened using the link in the side bar of the web console (http://IPofYourNAS:23424/mediabrowser). If you want to use the MediaBrowser from a remote location you would need to either port forward 23424 on your router, or use SSH tunnelling. You can also manage Serviio remotely by SSH tunnelling port 23423 which the console uses. Both of these service definitions are added to the DSM Firewall.
  • Advanced users who wish to edit device profiles or enable debug logging can find the Serviio files in /var/packages/Serviio/target. You will need to use an SSH session to access this folder – it cannot be navigated to using DSM’s File Station. You will need to restart the Serviio package for profile changes to take effect.
  • Some users may wish to restrict running Serviio to specific times of day in order to free up RAM for a scheduled backup window for instance. This can be achieved by creating tasks to start and stop Serviio using the Task Scheduler in DSM Control Panel:
    Schedule service start
  • The package uses an FFmpeg wrapper script to modify the usual transcoding behaviour of Serviio to use the Intel Evansport hardware decoding and encoding available in the DS214play and DS415play models. I have left the FFmpeg wrapper scripts in the package even when not in use (in the Serviio/bin folder), because they are still useful for people trying to test a particular workaround or encoder setting. The wrapper was a tricky script to get working due to variable expansion precedence issues and quote handling. If you need it, just change the ffmpeg.location system property in /var/packages/Serviio/target/bin/serviio.sh to point to your modified wrapper script.
  • If additional fonts are not working as expected, some troubleshooting is available. You can re-create the fontconfig cache by connecting to the NAS via an SSH session as admin, and then running:
    sudo -i
    (enter admin password to become root)
    rm -rf ~/.fontconfig.cache
    FC_DEBUG=128 /var/packages/Serviio/target/bin/fc-cache --verbose
 

Hardware transcoding support

  • DS214play and DS415play with Intel Evansport SoC are the only models supported. Serviio uses the multimedia tool FFmpeg for manipulating media files, and I am only able to build a hardware-assisted FFmpeg for DS214play and DS215play. Subsequent to those products, Synology has marketed a number of other systems with hardware transcoding features but these are not supported by Serviio. The DS216play with STiH412 Monaco SoC uses a specialised build of Gstreamer for the Synology transcoding solution, so its hardware features cannot be used by FFmpeg. It seems likely that Synology is also using Gstreamer for the Intel Braswell or newer generation CPUs with QuikSync, since DSM ships with an older FFmpeg (2.7.1) than the version which introduced QuikSync support (2.8.0). To implement FFmpeg QuikSync hardware transcoding support requires Linux kernel patches for libmfx support which is not currently included in DSM 6.x, so Serviio support for Intel QuikSync on Synology is unlikely unless Synology in future switches to using FFmpeg for its own hardware transcoding solution.
  • FFmpeg will use hardware decoding where possible.
  • Although multiple hardware assisted decodes can take place simultaneously, only a single hardware encode is available. The package intelligently avoids race conditions for this.
  • Any FFmpeg commandline to encode using libx264 will automatically be sent to the hardware encoder when available.
  • profiles.xml has been modified so that the preferred transcode format for most devices for non-natively supported videos is H.264.
  • In order to add hardware H.264 encoding to a device profile, specify h264 as the desired codec and the FFmpeg wrapper script will make the necessary substitution automatically.
  • When the hardware encoder is used, the low quality settings in Serviio’s default libx264 options to favour encoding speed are ignored. The hardware encoder performance is not altered by quality settings.
  • If a media stream is being both hardware decoded and hardware encoded, it will use pipelined mode. Based on responses from Synology support during development this means that both jobs occur on the media processor without exposing the intermediate bitstream to FFmpeg. Consequently it is not possible to burn subtitles in pipelined mode. As a result my FFmpeg wrapper script will run the decode part of the job in software in order to do this. The unfortunate result is that the encoder cannot quite achieve real time transcoding during subtitle compositing. For full 1080p HD material it achieves around 20fps, whereas most movies are 24fps. This means that in order to watch a film with hard subs you would need to start it off, pause or stop the renderer and return a bit later to view. An alternative would be to mux the content into an MKV container with the desired subtitles before adding it to the Serviio library, assuming that your device supports SRTs in MKV.
  • The hardware encoded H.264 streams are not 100% compliant with the specification and fail validation using the tool DGAVCDec. For most tested renderers this does not affect playback (Bravia, Sony Bluray, iOS). However FlowPlayer (the Flash player in MediaBrowser) does not play these files satisfactorily and drops many frames resulting in jerky playback. Since the Evansport CPU is capable of realtime encoding regular Flash Video when the decode of the source file is hardware accelerated, MediaBrowser does not use hardware encoding for FlowPlayer. iOS and Android devices browsing content via MediaBrowser do benefit from hardware transcoding however.
 

Package scripts

For information, here are the package scripts so you can see what it’s going to do. You can get more information about how packages work by reading the Synology 3rd Party Developer Guide.

installer.sh

#!/bin/sh

#--------SERVIIO installer script
#--------package maintained at pcloadletter.co.uk


DOWNLOAD_PATH="http://download.serviio.org/releases"
DOWNLOAD_FILE="serviio-1.9-linux.tar.gz"
EXTRACTED_FOLDER="serviio-1.9"
DOWNLOAD_URL="${DOWNLOAD_PATH}/${DOWNLOAD_FILE}"
SYNO_CPU_ARCH="`uname -m`"
[ "${SYNO_CPU_ARCH}" == "x86_64" ] && SYNO_CPU_ARCH="x64"
[ "${SYNOPKG_DSM_ARCH}" == "comcerto2k" ] && SYNO_CPU_ARCH="armneon"
[ "${SYNOPKG_DSM_ARCH}" == "armada375" ] && SYNO_CPU_ARCH="armneon"
[ "${SYNOPKG_DSM_ARCH}" == "armada38x" ] && SYNO_CPU_ARCH="armneon"
[ "${SYNOPKG_DSM_ARCH}" == "alpine" ] && SYNO_CPU_ARCH="armneon"
[ "${SYNOPKG_DSM_ARCH}" == "alpine4k" ] && SYNO_CPU_ARCH="armneon"
[ "${SYNOPKG_DSM_ARCH}" == "monaco" ] && SYNO_CPU_ARCH="armneon"
[ "${WIZARD_ENC_HW}" == "true" ] && SYNO_CPU_ARCH="i686evansport"
NATIVE_BINS_URL="http://packages.pcloadletter.co.uk/downloads/serviio-native-${SYNO_CPU_ARCH}.tar.xz"   
NATIVE_BINS_FILE="`echo ${NATIVE_BINS_URL} | sed -r "s%^.*/(.*)%\1%"`"
FONTS_URL="http://sourceforge.net/projects/dejavu/files/dejavu/2.37/dejavu-fonts-ttf-2.37.tar.bz2"
FONTS_FILE="`echo ${FONTS_URL} | sed -r "s%^.*/(.*)%\1%"`"
#'ua' prefix means wget user-agent will be customized
INSTALL_FILES="ua${DOWNLOAD_URL} ${NATIVE_BINS_URL} ${FONTS_URL}"
PID_FILE="${SYNOPKG_PKGDEST}/serviio.pid"
COMMENT="# Synology Serviio Package"
TEMP_FOLDER="`find / -maxdepth 2 -path '/volume?/@tmp' | head -n 1`"
PUBLIC_FOLDER="`synoshare --get public | sed -r "/Path/!d;s/^.*\[(.*)\].*$/\1/"`"
PLUGINS_PATH="${PUBLIC_FOLDER}/serviio"
source /etc/profile


pre_checks ()
{
  #These checks are called from preinst and from preupgrade functions to prevent failures resulting in a partially upgraded package
  if [ -z ${JAVA_HOME} ]; then
    echo "Java is not installed or not properly configured. JAVA_HOME is not defined. " >> $SYNOPKG_TEMP_LOGFILE
    echo "Download and install the Java Synology package from http://wp.me/pVshC-z5" >> $SYNOPKG_TEMP_LOGFILE
    exit 1
  fi

  if [ ! -f ${JAVA_HOME}/bin/java ]; then
    echo "Java is not installed or not properly configured. The Java binary could not be located. " >> $SYNOPKG_TEMP_LOGFILE
    echo "Download and install the Java Synology package from http://wp.me/pVshC-z5" >> $SYNOPKG_TEMP_LOGFILE
    exit 1
  fi

  JAVA_VER=`java -version 2>&1 | sed -r "/^.* version/!d;s/^.* version \"[0-9]\.([0-9]).*$/\1/"`
  if [ ${JAVA_VER} -lt 8 ]; then
    echo "This version of Serviio requires Java 8 or newer. Please update your Java package. " >> $SYNOPKG_TEMP_LOGFILE
    exit 1
  fi

  if [ -z ${PUBLIC_FOLDER} ]; then
    echo "A shared folder called 'public' could not be found - note this name is case-sensitive. " >> $SYNOPKG_TEMP_LOGFILE
    echo "Please create this using the Shared Folder DSM Control Panel and try again." >> $SYNOPKG_TEMP_LOGFILE
    exit 1
  fi
}


preinst ()
{
  pre_checks
  cd ${TEMP_FOLDER}
  for WGET_URL in ${INSTALL_FILES}
  do
    WGET_FILENAME="`echo ${WGET_URL} | sed -r "s%^.*/(.*)%\1%"`"
    [ -f ${TEMP_FOLDER}/${WGET_FILENAME} ] && rm ${TEMP_FOLDER}/${WGET_FILENAME}
    #this will allow serviio.org to track the number of downloads from Synology users
    WGET_URL=`echo ${WGET_URL} | sed -e "s/^ua/--user-agent=Synology --referer=http:\/\/pcloadletter.co.uk\/2012\/01\/25\/serviio-syno-package /"`
    wget ${WGET_URL}
    if [ $? != 0 ]; then
      if [ -d ${PUBLIC_FOLDER} ] && [ -f ${PUBLIC_FOLDER}/${WGET_FILENAME} ]; then
        cp ${PUBLIC_FOLDER}/${WGET_FILENAME} ${TEMP_FOLDER}
      else
        echo "There was a problem downloading ${WGET_FILENAME} from the official download link, " >> $SYNOPKG_TEMP_LOGFILE
        echo "which was \"${WGET_URL}\" " >> $SYNOPKG_TEMP_LOGFILE
        echo "Alternatively, you may download this file manually and place it in the 'public' shared folder. " >> $SYNOPKG_TEMP_LOGFILE
        exit 1
      fi
    fi
  done

  exit 0
}


postinst ()
{
  #extract the downloaded Serviio archive
  cd ${TEMP_FOLDER}
  tar xzf ${TEMP_FOLDER}/${DOWNLOAD_FILE}
  rm ${TEMP_FOLDER}/${DOWNLOAD_FILE}
  cp -R ${TEMP_FOLDER}/${EXTRACTED_FOLDER}/* ${SYNOPKG_PKGDEST}
  if [ ! -z "${EXTRACTED_FOLDER}" ]; then
    rm -r ${TEMP_FOLDER}/${EXTRACTED_FOLDER}
  fi
  if [ ! -d "${PLUGINS_PATH}/plugins" ]; then
    mkdir -p ${PLUGINS_PATH}/plugins
  fi
  if [ ! -d "${PLUGINS_PATH}/fonts" ]; then
    mkdir -p ${PLUGINS_PATH}/fonts
  fi

  #extract CPU-specific additional binaries
  cd ${SYNOPKG_PKGDEST}/lib
  tar xJf ${TEMP_FOLDER}/${NATIVE_BINS_FILE} && rm ${TEMP_FOLDER}/${NATIVE_BINS_FILE}
  mv ${SYNOPKG_PKGDEST}/lib/ffmpeg ${SYNOPKG_PKGDEST}/bin
  mv ${SYNOPKG_PKGDEST}/lib/fc-cache ${SYNOPKG_PKGDEST}/bin

  #remove legacy package font versions
  [ -d ${PLUGINS_PATH}/fonts/dejavu-fonts-ttf-2.33/ ] && rm -rf ${PLUGINS_PATH}/fonts/dejavu-fonts-ttf-2.33/
  [ -d ${PLUGINS_PATH}/fonts/dejavu-fonts-ttf-2.34/ ] && rm -rf ${PLUGINS_PATH}/fonts/dejavu-fonts-ttf-2.34/
  [ -d ${PLUGINS_PATH}/fonts/dejavu-fonts-ttf-2.35/ ] && rm -rf ${PLUGINS_PATH}/fonts/dejavu-fonts-ttf-2.35/

  #extract open source font package for subtitle support during transcoding
  cd ${PLUGINS_PATH}/fonts
  tar xvjf ${TEMP_FOLDER}/${FONTS_FILE} && rm ${TEMP_FOLDER}/${FONTS_FILE}
  sed -i "s|WINDOWSFONTDIR|${PLUGINS_PATH}/fonts|" ${SYNOPKG_PKGDEST}/config/fonts/fonts.conf
  sed -i "s|WINDOWSTEMPDIR_FONTCONFIG_CACHE|~/.fontconfig.cache|" ${SYNOPKG_PKGDEST}/config/fonts/fonts.conf

  #wrapper script can be useful for testing different encoder options
  if [ -e "${SYNOPKG_PKGDEST}/bin/ffmpeg-wrapper-${SYNO_CPU_ARCH}.sh" ]; then
    #we need to use the wrapper to make FFmpeg use libshine on ARM systems and to use hardware decode/encode on Intel Evansport systems
    FFMPEG_PATH="\$SERVIIO_HOME/bin/ffmpeg-wrapper-${SYNO_CPU_ARCH}.sh"
  else
    FFMPEG_PATH="\$SERVIIO_HOME/bin/ffmpeg"
  fi

  #modifications to device profiles (evansport hardware transcoding)
  if [ -e "${SYNOPKG_PKGDEST}/config/profiles-${SYNO_CPU_ARCH}.xml" ]; then
    mv "${SYNOPKG_PKGDEST}/config/profiles.xml" "${SYNOPKG_PKGDEST}/config/profiles-orig.xml"
    mv "${SYNOPKG_PKGDEST}/config/profiles-${SYNO_CPU_ARCH}.xml" "${SYNOPKG_PKGDEST}/config/profiles.xml"
  fi

  #modifications to application profiles (evansport hardware transcoding)
  #removed owing to frame drops in FlowPlayer because encoder does not produce 100% valid streams, evansport has sufficient power for flv encoding
  #if [ -e "${SYNOPKG_PKGDEST}/config/application-profiles-${SYNO_CPU_ARCH}.xml" ]; then
  #  mv "${SYNOPKG_PKGDEST}/config/application-profiles-${SYNO_CPU_ARCH}.xml" "${SYNOPKG_PKGDEST}/config/application-profiles.xml"
  #fi

  #make changes to Serviio launcher script so that pid file is created for Java process
  sed -r -i "s%Execute the JVM in the foreground%Execute the JVM in the background%" ${SYNOPKG_PKGDEST}/bin/serviio.sh
  sed -r -i "s%^(exec \"$JAVA.*)$%\1 \&%" ${SYNOPKG_PKGDEST}/bin/serviio.sh
  echo "echo \$! > ${PID_FILE}" >> ${SYNOPKG_PKGDEST}/bin/serviio.sh

  #set some additional Serviio system properties (temp folder, FFmpeg path, plugins folder)
  #http://www.serviio.org/index.php?option=com_content&view=article&id=43
  EXTRA_OPTS="-Dserviio\.defaultTranscodeFolder=${TEMP_FOLDER} -Dffmpeg\.location=${FFMPEG_PATH} -Dplugins\.location=${PLUGINS_PATH}"
  #fix Java prefs checking which was preventing NAS hibernation http://forum.serviio.org/viewtopic.php?f=5&t=6878
  EXTRA_OPTS="${EXTRA_OPTS} -Djava.util.prefs.syncInterval=86400"
  if [ "${SYNO_CPU_ARCH}" == "armv5tel" ]; then
    #use integer math (not floating point) Dolby AC-3 encoder for better performance on ARM CPUs
    #http://ffmpeg.org/ffmpeg.html#ac3-and-ac3_005ffixed
    EXTRA_OPTS="${EXTRA_OPTS} -Dserviio\.fixedPointEncoders"
  fi
  sed -r -i "s% -Dffmpeg\.location=ffmpeg%%; s%^(JAVA_OPTS=.*)\"$%\1 ${EXTRA_OPTS}\"%" ${SYNOPKG_PKGDEST}/bin/serviio.sh

  #create log file to allow package start errors to be captured
  [ -e ${SYNOPKG_PKGDEST}/log ] || mkdir ${SYNOPKG_PKGDEST}/log
  [ -e ${SYNOPKG_PKGDEST}/log/serviio.log ] || touch ${SYNOPKG_PKGDEST}/log/serviio.log

  #add firewall config
  /usr/syno/bin/servicetool --install-configure-file --package /var/packages/${SYNOPKG_PKGNAME}/scripts/${SYNOPKG_PKGNAME}.sc > /dev/null

  exit 0
}


preuninst ()
{
  `dirname $0`/stop-start-status stop

  exit 0
}


postuninst ()
{
  #remove fontconfig configuration
  sed -i "/${COMMENT}/d" /root/.profile

  #remove firewall config
  if [ "${SYNOPKG_PKG_STATUS}" == "UNINSTALL" ]; then
    /usr/syno/bin/servicetool --remove-configure-file --package ${SYNOPKG_PKGNAME}.sc > /dev/null
  fi

  #remove legacy daemon user and homedir
  [ -e /var/services/homes/serviio ] && synouser --del serviio
  [ -e /var/services/homes/serviio ] && rm -r /var/services/homes/serviio

  exit 0
}


preupgrade ()
{
  `dirname $0`/stop-start-status stop
  pre_checks
  #if a media database exists we need to preserve it
  if [ -d ${SYNOPKG_PKGDEST}/library/db ]; then
    mkdir ${SYNOPKG_PKGDEST}/../${SYNOPKG_PKGNAME}_db_migration
    mv ${SYNOPKG_PKGDEST}/library/db ${SYNOPKG_PKGDEST}/../${SYNOPKG_PKGNAME}_db_migration
  fi

  exit 0
}


postupgrade ()
{
  #use the backed up media database from the previous version
  if [ -d ${SYNOPKG_PKGDEST}/../${SYNOPKG_PKGNAME}_db_migration/db ]; then
    mv ${SYNOPKG_PKGDEST}/../${SYNOPKG_PKGNAME}_db_migration/db ${SYNOPKG_PKGDEST}/library
    rmdir ${SYNOPKG_PKGDEST}/../${SYNOPKG_PKGNAME}_db_migration
  fi
  chown -R root:root ${SYNOPKG_PKGDEST}

  exit 0
}
 

start-stop-status.sh

#!/bin/sh

#--------SERVIIO start-stop-status script
#--------package maintained at pcloadletter.co.uk

PKG_FOLDER="/var/packages/Serviio"
ENGINE_CFG="${PKG_FOLDER}/target/bin/serviio.sh"
ENGINE_SCRIPT="${PKG_FOLDER}/target/bin/serviio.sh"
PID_FILE="${PKG_FOLDER}/target/serviio.pid"
DNAME="Serviio"
DLOG="${PKG_FOLDER}/target/log/serviio.log"
COMMENT="# Synology Serviio Package"
TIMESTAMP="`date "+%F %X,000"`"
source /etc/profile
source /root/.profile


EnvCheck ()
#updates to DSM will reset these changes so check them each startup
{
  #/root/.profile should contain 2 lines added by this package tagged with trailing comments
  COUNT=`grep -c "$COMMENT$" /root/.profile`
  if [ $COUNT != 2 ]; then

    #remove any existing mods
    sed -i "/${COMMENT}/d" /root/.profile

    #add required environment variables
    echo "export FONTCONFIG_FILE=fonts.conf ${COMMENT}" >> /root/.profile
    echo "export FONTCONFIG_PATH=${PKG_FOLDER}/target/config/fonts ${COMMENT}" >> /root/.profile
  fi
}

start_daemon ()
{
  EnvCheck
  source /root/.profile

  #create/refresh fontconfig cache - prevents delay the first time that FFmpeg renders hard subs
  #FC_DEBUG=128 fc-cache --verbose
  ${PKG_FOLDER}/target/bin/fc-cache

  #refresh hostname in Serviio instance name - recently DSM has modified the hosts file and broken localhost name resolution
  sed -i -r "s%<FriendlyName>Serviio \((\{computerName\})\)%<FriendlyName>Serviio \(`hostname`\)%" $PKG_FOLDER/target/config/profiles.xml

  #set appropriate Java max heap size
  RAM=$((`free | grep Mem: | sed -e "s/^ *Mem: *\([0-9]*\).*$/\1/"`/1024))
  if [ $RAM -le 128 ]; then
    JAVA_MAX_HEAP=80
  elif [ $RAM -le 256 ]; then
    JAVA_MAX_HEAP=192
  elif [ $RAM -le 512 ]; then
    JAVA_MAX_HEAP=384
  #Serviio's default max heap is 512MB
  elif [ $RAM -gt 512 ]; then
    JAVA_MAX_HEAP=512
  fi
  sed -i -r "s/(^..JAVA.) -Xmx[0-9]+[mM] (.*$)/\1 -Xmx${JAVA_MAX_HEAP}m \2/" "${ENGINE_CFG}"
  echo "${TIMESTAMP} Starting ${DNAME}" >> ${DLOG}
  ${ENGINE_SCRIPT} > /dev/null 2>> ${DLOG}
  if [ -z ${SYNOPKG_PKGDEST} ]; then
    #script was manually invoked, need this to show status change in Package Center
    [ -e ${PKG_FOLDER}/enabled ] || touch ${PKG_FOLDER}/enabled
  fi
}

stop_daemon ()
{
  echo "${TIMESTAMP} Stopping ${DNAME}" >> ${DLOG}
  kill `cat ${PID_FILE}`
  wait_for_status 1 20 || kill -9 `cat ${PID_FILE}`
  rm -f ${PID_FILE}
  if [ -z ${SYNOPKG_PKGDEST} ]; then
    #script was manually invoked, need this to show status change in Package Center
    [ -e ${PKG_FOLDER}/enabled ] && rm ${PKG_FOLDER}/enabled
  fi
}

daemon_status ()
{
  if [ -f ${PID_FILE} ] && kill -0 `cat ${PID_FILE}` > /dev/null 2>&1; then
    return
  fi
  rm -f ${PID_FILE}
  return 1
}

wait_for_status ()
{
  counter=$2
  while [ ${counter} -gt 0 ]; do
    daemon_status
    [ $? -eq $1 ] && return
    let counter=counter-1
    sleep 1
  done
  return 1
}

case $1 in
  start)
    if daemon_status; then
      echo ${DNAME} is already running with PID `cat ${PID_FILE}`
      exit 0
    else
      echo Starting ${DNAME} ...
      start_daemon
      exit $?
    fi
  ;;

  stop)
    if daemon_status; then
      echo Stopping ${DNAME} ...
      stop_daemon
      exit $?
    else
      echo ${DNAME} is not running
      exit 0
    fi
  ;;

  restart)
    stop_daemon
    start_daemon
    exit $?
  ;;

  status)
    if daemon_status; then
      echo ${DNAME} is running with PID `cat ${PID_FILE}`
      exit 0
    else
      echo ${DNAME} is not running
      exit 1
    fi
  ;;

  log)
    echo "${DLOG}"
    exit 0
  ;;

  *)
    echo "Usage: $0 {start|stop|status|restart}" >&2
    exit 1
  ;;

esac
 

ffmpeg-wrapper-i686evansport.sh

#!/bin/sh

#FFmpeg wrapper script to enable hardware decoding and encoding on Intel Evansport CPUs
#wrapper originally posted here: http://forum.serviio.org/viewtopic.php?f=7&t=6458

FOLDER="`dirname $0`"
PARAMS=""
COMMANDLINE=$@
FFMPEG_BIN="ffmpeg"
INPUT=0
for PARAM in "$@"; do
  if [ ${INPUT} = 1 ]; then
    #the FFmpeg input filename/URL needs quotes adding back on
    #because it may contain spaces, and the shell has removed them
    PARAMS="${PARAMS} \"${PARAM}\""    
    INPUT=0
  elif [ ${INPUT} = 2 ]; then
    #the FFmpeg subtitles filename needs quotes adding back on
    #because it may contain spaces, and the shell has removed them
    PARAM=${PARAM/\[*.*\]subtitles=filename=/subtitles=filename=\"}
    PARAM=${PARAM/:original_size/\":original_size}
    PARAMS="${PARAMS} ${PARAM}"    
    INPUT=0
  elif [ "${PARAM}" == "-filter_complex" ]; then
    #next parameter will be subtitles filtergraph including subtitle filename
    #which needs special treatment, so set a flag
    INPUT=2
    PARAMS="${PARAMS} ${PARAM}"
  elif [ "${PARAM}" == "-i" ]; then
    #next parameter will be input filename which needs special treatment, so set a flag    
    INPUT=1
    #enable hardware decoding by default, but not when Serviio is either:
    # gathering media metadata,
    # remuxing video,
    # generating thumbnails,
    # or rendering subtitles into the video stream (pipeline mode not supported for subs),
    if [ $# -lt 3 ] || \
       [ "${COMMANDLINE}" != "${COMMANDLINE/ -c:v copy /}" ] || \
       [ "${COMMANDLINE}" != "${COMMANDLINE/ pipe:/}" ] || \
       [ "${COMMANDLINE}" != "${COMMANDLINE/ -filter_complex \[*:*\]subtitles=/}" ]; then
      PARAMS="${PARAMS} -i"
    # or gathering online stream metadata 
    elif [ $# -eq 4 ] && [ "${COMMANDLINE}" != "${COMMANDLINE/-analyzeduration /}" ]; then
      PARAMS="${PARAMS} -i"
    else
      PARAMS="${PARAMS} -prefer_smd -i"
    fi
  else
    PARAMS="${PARAMS} ${PARAM}"
  fi
done

#older Evansport FFmpeg version 2.7.1 needs "-strict -2" to use experimental aac encoder
if [ "${PARAMS}" != "${PARAMS/ -c:a:* aac /}" ]; then
  PARAMS="${PARAMS/ aac / aac -strict -2 }"
fi

#Is this FFmpeg commandline a candidate for the hardware encoder?
HWENC=0
if [ "${PARAMS}" != "${PARAMS/ -c:v libx264 /}" ]; then
  #check whether H.264 encoder is already busy with another Serviio/VideoStation session
  PID_HWENC=`cat /tmp/VideoStation/enabled 2> /dev/null | sed -r "s/.*\"PID\":([0-9]+),\"hardware_transcode.*$/\1/;s/\[//;s/\]//"`
  #is there an indicated PID?
  if [ -n "${PID_HWENC}" ]; then
    #there is an indicated PID - is it running? 
    if ! kill -0 ${PID_HWENC}; then
      #the indicated PID is not in fact running, HW encoder is therefore available
      rm /tmp/VideoStation/enabled
      #make hardware H.264 encoder substitution to replace libx264
      HWENC=1
    fi 
  else
    #there is no indicated PID, HW encoder is therefore available
    HWENC=1
  fi  
fi

if [ ${HWENC} = 1 ]; then
  #make hardware H.264 encoder substitution to replace libx264
  PARAMS=${PARAMS/ libx264 / h264_smd }

  #by default Serviio's libx264 transcoding is intended for speed over quality, with SMD we can opt for better quality
  PARAMS="`echo ${PARAMS} | sed -r "s/ -crf [0-9]+ / /; s/ -g [0-9]+ / /"`"
  PARAMS=${PARAMS/ -preset:v veryfast / }
  PARAMS=${PARAMS/ -profile:v baseline / -profile:v high }
  PARAMS=${PARAMS/ -level 3 / -level 4.1 }
fi

#invoke FFmpeg
#log commandline, except media probes
#[ $# -gt 2 ] && echo "${FOLDER}/${FFMPEG_BIN} ${PARAMS}" >> ${FOLDER}/../log/ffmpeg-wrapper.log

#need to use eval here otherwise the quotes aren't handled properly
#http://fvue.nl/wiki/Bash:_Why_use_eval_with_variable_expansion%3F
eval ${FOLDER}/${FFMPEG_BIN} ${PARAMS}

#return FFmpeg status
exit $?
 

Changelog:

  • 0033 30/Oct/17 – Added support for new CPU types in x18 products
  • 0033 02/Aug/17 – Updated to Serviio 1.9
  • 0032 21/Jan/17 – Fixed Evansport FFmpeg wrapper script to allow transcoding to aac since it’s an older FFmpeg version with slightly different command syntax
  • 0031 07/Jan/17 – Updated to Serviio 1.8
    Updated FFmpeg to 3.2.2
    Updated Intel Evansport hardware transcoding build of FFmpeg from 2.0.2 to 2.7.1 – now detects H.265 codec correctly
    Fixed Intel Evansport FFmpeg support for transcoding DTS audio
    FFmpeg now uses hard float ABI on systems with Armada 370/XP SoC (DSM 6.0 change)
    FFmpeg now uses NEON on systems with Armada 375 SoC (DSM 6.0 change)
    Disabled FFmpeg wrapper script to enable libshine for ARMv5 systems now that Serviio handles this automatically
    Added Ogg Vorbis audio support to FFmpeg
    Updated Deja-Vu fonts to 2.37
    DSM 6.0 is now required due to greatly simplify FFmpeg compilation
  • 0030 21/May/16 – Updated to Serviio 1.6.1
  • 0029 28/Jan/16 – Updated to Serviio 1.6, integrated the new built-in web console into DSM, fixed stupid wrapper bug which had broken evansport hardware transcoding on DS214play and DS415play, fixed online content when using evansport build. You must have already upgraded to version 1.5.2-0028 or else Package Center will report a TCP port conflict and will fail to upgrade the package. If you missed the 0028 update, install it manually in Package Center using the .spk file: (DS214play/DS415play), (all other models).
  • 0028 08/Jan/16 – Serviio instance uses hostname rather than localhost, more accurate detection of DSM 6.0 on Intel CPUs which need x64 FFmpeg build, added DS216play support, fixed missing libgmp on DS3612xs running DSM 5.0, change to allow easy package upgrade to forthcoming Serviio 1.6
  • 0027 12/Nov/15 – Substantial package re-write hence the long delay since the last release
    Completely refreshed documentation, please re-read
    Updated to Serviio version 1.5.2
    Java 8 is now required – this is a Serviio imposed requirement
    DSM 5.0 or newer is now required
    Updated to FFmpeg 2.7.1 and many libs e.g. x264 at latest versions from late July 2015
    Added optional hardware transcoding support for Intel Evansport systems (DS214play, DS415play) built using Synology-modified sources for FFmpeg 2.0.2
    FFmpeg is now compiled with https support via GNUTLS library (useful for online streams via plugins)
    Switched to using root account which was necessary for Evansport hardware encoding – no more adding account permissions, package upgrades will no longer break this
    Added support for Mindspeed Comcerto 2000 CPU (comcerto2k – ARM Cortex-A9 with NEON) in DS414j
    Added support for Intel Atom C2538 (avoton) CPU in DS415+
    Fontconfig fc-cache utility now included to allow troubleshooting issues with adding new fonts for additional subtitle language support
    Fontconfig variables checked on each package startup so DSM upgrades no longer break hard subs support
    Updated DejaVu subtitle font to version 2.35
    DSM Firewall application definitions added
    Tested with DSM Task Scheduler to allow package to start/stop at certain times of day, saving RAM when not needed
    Daemon init script now uses a proper PID file instead of the unreliable method of using grep on the output of ps
    Daemon init script can be run from the command line
    Improved accuracy of temp folder and plugins folder detection
    Switched to .tar.xz compression for native binaries to reduce web hosting storage footprint
    Package is now signed with repository private key
    User Agent customization while downloading Serviio binaries from serviio.org to allow download stats gathering
  • 0026 25/Mar/14 – Updated to Serviio 1.4.1.2
  • 0025 18/Mar/14 – Updated to Serviio 1.4.1.1
  • 0024 30/Jan/14 – Updated to Serviio 1.4
  • 0023 07/Nov/13 – Updated to FFmpeg 2.1 stable release
  • 0022 30/Oct/13 – Added support for Intel Atom Evansport and Armada XP CPUs in new DSx14 products
  • 0021 18/Oct/13 – Fixed zlib linking issue in QorIQ and Intel builds of FFmpeg
  • 0020 05/Sep/13 – Updated to Serviio 1.3.1
  • 0019 25/May/13 – Added support for Armada370 SoC used in DS213j (ARMv7 CPU with FPU)
  • 0018 29/Mar/13 – Updated to Serviio 1.2.1, recompiled FFmpeg to use the libRTMP source code from serviio.org for consistency
  • 0017 01/Mar/13 – Updated to Serviio 1.2
  • 0016 23/Jan/13 – Fixes for DSM 4.2
  • 015 30/Dec/13 – Updated to Serviio 1.1, fixed garbled ac3 encoding issue on ARM CPUs by compiling FFmpeg natively, rather than cross compiling. Remember to update your computer’s Serviio Console to 1.1 before connecting to manage.
  • 014 28/Oct/12 – Added support for Freescale QorIQ PowerPC CPUs used in some Synology x13 series products, switched to shared library compile of FFmpeg with some minor changes, ARM build now uses libshine encoder which allows realtime audio transcoding to MP3, edited FlowPlayer config to play AAC audio natively to make Media Browser more usable with online feed items.
  • 013 Fixed a bug in the plugins folder creation, fixed deletion of home directories after user deletion (DSM 4.1)
  • 012 Reduced Java prefs checking interval to once every 24 hours to allow the NAS to hibernate (was 30 seconds by default – remember to increase the time between library refreshes if you want hibernation)
  • 011 Updated Serviio to 1.0.1, slightly altered how the plugins folder path is determined
  • 010 Updated to Serviio 1.0, removed WebUI, FFmpeg wrapper no longer needed on ARM, plugins folder moved to /volume1/public/serviio/plugins to make adding/updating plugins easier
  • 009 Installation fails unless User Home service is enabled, unified the installer scripts, merged ARM and Intel packages into one which downloads the FFmpeg binary separately, used integer maths Dolby AC-3 encoder on ARM systems (no floating point)
  • 008 Fixed DST timezone support, installer no longer assumes /volume1 is primary storage volume
  • 007 Updated Serviio to 0.6.2, kairoh’s WebUI to 0.6.2c, changed package to download Serviio from the official website during installation, temp path is set by default to /volume1/@tmp on first run, and finally some CSS improvements
  • 006 Updated to Serviio 0.6.1, switched to kairoh’s Java WebUI, added timezone support, removed DSM icon when Serviio is not running, adjusted Java max heap size for systems with low RAM, specified FFmpeg path directly rather than creating a symlink in /bin so as not to interfere with other packages which may use different versions of FFmpeg
  • 005 Added Web Station dependency, EULA dialog, and links for Web UI and user forum in More Info
  • 004 Test for package repo to allow update notification
  • 0.6.0.1 v3 Hopefully fixed an issue with the Serviio DSM icon in DSM 3.2 on NAS units without Optware installed
  • 0.6.0.1 v2 Inclusion of a modified version of the PHP Web UI
  • 0.6.0.1 v1 New minor Serviio release 0.6.0.1 with some updated international translations – will upgrade 0.6 preserving the media library
  • 0.6 v1 23/Sep/11 – First public release – Serviio 0.6
  • 0.6b4 v2 Fixed permissions on transcode temporary folder following upgrade, avoiding the need for a reboot
  • 0.6b4 v1 Updated to Serviio 0.6 beta 4, added upgrade scripts to allow media database migration (install future packages over the top of this one – database is preserved)
  • 0.6b3c v2 Fixed HOME env var for serviio user (to fix librtmp issues with BBC iPlayer) and removed the need to edit the passwd file to change the shell (safer)
  • 0.6b3c v1 Initial spk test release – Serviio 0.6 beta 3

 
 

Compiling FFmpeg with libRTMP and libmp3lame for Intel, ARM and QorIQ PowerPC CPUs

Intel cross-compile for Synology NAS on Ubuntu Desktop 12.04 64bit (VirtualBox VM running on a Macbook Air):

#-----set up Synology toolchain
cd ~/Downloads
PART1="http://sourceforge.net/projects/dsgpl/files/DSM%204.0%20Tool%20Chains/"
PART2="Intel%20x86%20Linux%202.6.32%20%28Pineview%29/gcc420_glibc236_x64-GPL.tgz"
wget "${PART1}${PART2}"
tar xvzf gcc420_glibc236_x64-GPL.tgz
sudo mv x86_64-linux-gnu /usr/local
export PATH="/usr/local/x86_64-linux-gnu/bin:${PATH}"

#-----libz static lib
wget http://zlib.net/zlib-1.2.7.tar.gz
tar xvzf zlib-1.2.7.tar.gz
cd zlib-1.2.7
./configure --prefix=/usr/local/x86_64-linux-gnu --static
make libz.a
cp libz.a /usr/local/x86_64-linux-gnu/lib
cp *.h /usr/local/x86_64-linux-gnu/include/
cd ..

#-----libbz2 static lib
#-----seem to need 32bit libraries to build bzip2
#-----http://maketecheasier.com/run-32-bit-apps-in-64-bit-linux/2009/08/10
sudo apt-get install ia32-libs
wget http://bzip.org/1.0.6/bzip2-1.0.6.tar.gz
tar xvfz bzip2-1.0.6.tar.gz
cd bzip2-1.0.6
sed -i 's/^CC=gcc/CC=x86_64-linux-gnu-gcc/g' Makefile
sed -i 's/^AR=ar rc/AR=x86_64-linux-gnu-ar rc/g' Makefile
sed -i 's/^RANLIB=ranlib/RANLIB=x86_64-linux-gnu-ranlib/g' Makefile
make
make install PREFIX=/usr/local/x86_64-linux-gnu
cd ..

#-----libmp3lame static lib
sudo apt-get install nasm
wget http://sourceforge.net/projects/lame/files/lame/3.99/lame-3.99.5.tar.gz
tar xvzf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --prefix=/usr/local/x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --build=x86_64-linux-gnu --enable-static --disable-shared --disable-decoder --enable-nasm
make
make install
cd..

#-----libssl & libcrypto static libs
wget http://www.openssl.org/source/openssl-0.9.8v.tar.gz
tar xvzf openssl-0.9.8v.tar.gz
cd openssl-0.9.8v
./config --prefix=/usr/local/x86_64-linux-gnu no-shared
sed -i 's/^CC= gcc/CC= x86_64-linux-gnu-gcc/g' Makefile
sed -i 's/^AR= ar /AR= x86_64-linux-gnu-ar /g' Makefile
sed -i 's/^ARD=ar /ARD=x86_64-linux-gnu-ar /g' Makefile
sed -i 's/^RANLIB= \/usr\/bin\/ranlib/RANLIB=x86_64-linux-gnu-ranlib/g' Makefile
sed -i 's/^MAKEDEPPROG= gcc/MAKEDEPPROG= x86_64-linux-gnu-gcc /g' Makefile
make
make install
cd ..

#-----librtmp 2.4 static lib
wget http://download.serviio.org/opensource/rtmpdump-c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5.tar.gz
tar xvfz rtmpdump-c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5.tar.gz
cd rtmpdump
#-----move all static libs to a separate folder to force compiler to use them
#-----http://www.gossamer-threads.com/lists/apache/dev/265052
mkdir /tmp/lib
cp /usr/local/x86_64-linux-gnu/lib/*.a /tmp/lib
#-----fix Makefile (won't compile without libdl linked)
#-----http://forum.luahub.com/index.php?topic=2390.0
sed -i.bak -e '/^LIB_OPENSSL\=/s/lcrypto/lcrypto \-ldl/' Makefile
make CROSS_COMPILE=x86_64-linux-gnu- SYS=posix prefix=/usr/local/x86_64-linux-gnu INC=-I/usr/local/x86_64-linux-gnu XLDFLAGS=-L/tmp/lib SHARED=
make install prefix=/usr/local/x86_64-linux-gnu SHARED=
cd ..

#-----gather all static libs again ready for FFmpeg compile
cp /usr/local/x86_64-linux-gnu/lib/*.a /tmp/lib
#-----remove unsupported URL line from pkgconfig/librtmp.pc
#-----pkg-config --exists --print-errors librtmp
sed -i -e '/^URL/d' /usr/local/x86_64-linux-gnu/lib/pkgconfig/librtmp.pc
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/local/x86_64-linux-gnu/lib/pkgconfig"

#-----FFmpeg 0.11.1
wget http://download.serviio.org/opensource/ffmpeg-N-41860-g6fd0b55.tar.gz
tar xvzf ffmpeg-N-41860-g6fd0b55.tar.gz
cd ffmpeg
echo N-41860-g6fd0b55 > RELEASE
#-----Intel CPU-specific options
#-----pkg-config needs to be defined because with cross-prefix it assumes x86_64-linux-gnu-pkg-config which doesn't exist, and then librtmp won't be detected
sudo apt-get install yasm
./configure --arch=x86_64 --enable-ssse3 --cross-prefix=x86_64-linux-gnu- --target-os=linux --prefix=/usr/local/x86_64-linux-gnu --extra-cflags='-I/usr/local/x86_64-linux-gnu/include' --extra-ldflags='-L/tmp/lib' --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-pthreads --enable-libmp3lame --enable-librtmp --pkg-config=pkg-config --extra-version=Serviio
make
./ffmpeg
 

ARM cross-compile for Synology NAS on Ubuntu Desktop 12.04 64bit (VirtualBox VM running on a Macbook Air):

#-----set up Synology toolchain
cd ~/Downloads
PART1="http://sourceforge.net/projects/dsgpl/files/DSM%204.1%20Tool%20Chains/"
PART2="Marvell%2088F628x%20Linux%202.6.32/gcc421_glibc25_88f6281-GPL.tgz"
wget "${PART1}${PART2}"
tar xvzf gcc421_glibc25_88f6281-GPL.tgz
sudo mv arm-none-linux-gnueabi /usr/local
export PATH=/usr/local/arm-none-linux-gnueabi/bin:$PATH
export AR=arm-none-linux-gnueabi-ar
export CC=arm-none-linux-gnueabi-gcc
export CXX=arm-none-linux-gnueabi-g++
export LD=arm-none-linux-gnueabi-ld
export RANLIB=arm-none-linux-gnueabi-ranlib
export CFLAGS="-I/usr/local/arm-none-linux-gnueabi/include"
export LDFLAGS="-L/usr/local/arm-none-linux-gnueabi/lib"

#-----libz static lib
wget http://zlib.net/zlib-1.2.7.tar.gz
tar xvzf zlib-1.2.7.tar.gz
cd zlib-1.2.7
./configure --prefix=/usr/local/arm-none-linux-gnueabi --static
make libz.a
cp libz.a /usr/local/arm-none-linux-gnueabi/lib
cp *.h /usr/local/arm-none-linux-gnueabi/include/
cd ..

#-----libbz2 static lib
wget http://bzip.org/1.0.6/bzip2-1.0.6.tar.gz
tar xvfz bzip2-1.0.6.tar.gz
cd bzip2-1.0.6
sed -i 's/^CC=gcc/CC=arm-none-linux-gnueabi-gcc/g' Makefile
sed -i 's/^AR=ar/AR=arm-none-linux-gnueabi-ar/g' Makefile
sed -i 's/^RANLIB=ranlib/RANLIB=arm-none-linux-gnueabi-ranlib/g' Makefile
#remove the tests - we can't run the native binaries
sed -i 's/^\(all: libbz2\.a bzip2 bzip2recover\) test/\1/' Makefile
make
make install PREFIX=/usr/local/arm-none-linux-gnueabi
cd ..

#-----libmp3lame static lib
wget http://sourceforge.net/projects/lame/files/lame/3.99/lame-3.99.5.tar.gz
tar xvzf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --prefix=/usr/local/arm-none-linux-gnueabi --host=arm-none-linux-gnueabi --build=x86_64-linux-gnu --enable-static --disable-shared --disable-decoder
make
make install
cd ..

#-----libssl & libcrypto static libs
wget http://www.openssl.org/source/openssl-0.9.8v.tar.gz
tar xvzf openssl-0.9.8v.tar.gz
cd openssl-0.9.8v
#Some kind of strange issue where cross compilation parameters are ignored
#unless this fix is used http://marc.waeckerlin.org/computer/blog/openssl_fuer_windows_mingw_unter_linux_crosscomilieren
sed -i 's/\(die \"target already defined - \$target (offending arg\)/#\1/' Configure
./config --prefix=/usr/local/arm-none-linux-gnueabi no-shared linux-generic32
make
make install
cd ..

#-----librtmp 2.4 static lib
wget http://download.serviio.org/opensource/rtmpdump-c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5.tar.gz
tar xvfz rtmpdump-c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5.tar.gz
cd rtmpdump
#-----move all static libs to a separate folder to force compiler to use them
#-----http://www.gossamer-threads.com/lists/apache/dev/265052
mkdir /tmp/lib
cp /usr/local/arm-none-linux-gnueabi/lib/*.a /tmp/lib
#-----fix Makefile (won't compile without libdl linked)
#-----http://forum.luahub.com/index.php?topic=2390.0
sed -i.bak -e '/^LIB_OPENSSL\=/s/lcrypto/lcrypto \-ldl/' Makefile
make CROSS_COMPILE=arm-none-linux-gnueabi- SYS=posix prefix=/usr/local/arm-none-linux-gnueabi INC=-I/usr/local/arm-none-linux-gnueabi XLDFLAGS=-L/tmp/lib SHARED=
make install prefix=/usr/local/arm-none-linux-gnueabi SHARED=
cd ..

#-----gather all static libs again ready for FFmpeg compile
cp /usr/local/arm-none-linux-gnueabi/lib/*.a /tmp/lib
#-----remove unsupported URL line from pkgconfig/librtmp.pc
#-----pkg-config --exists --print-errors librtmp
sed -i -e '/^URL/d' /usr/local/arm-none-linux-gnueabi/lib/pkgconfig/librtmp.pc
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/local/arm-none-linux-gnueabi/lib/pkgconfig"

#-----FFmpeg
wget http://download.serviio.org/opensource/ffmpeg-N-42368-gbf53863.tar.gz
tar xvzf ffmpeg-N-42368-gbf53863.tar.gz
cd ffmpeg
#-----fixed point maths modification for mpeg audio encoder
sed -i "s/^#define USE_FLOATS//" libavcodec/mpegaudioenc.c
#-----Marvell Kirkwood mv6282 CPU is based on the ARMv5TE core which has DSP and thumb instruction support
#-----http://www.arm.com/products/processors/technologies/dsp-simd.php
#-----http://www.marvell.com/embedded-processors/kirkwood/assets/88f6282-3_pb.pdf
#-----ARMv5TE CPU-specific options (based on inspecting 'configure' source https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes arm-none-linux-gnueabi-pkg-config which doesn't exist, and then librtmp won't be detected
#-----zmbv encoder refuses to cross compile here so it's disabled
./configure --arch=arm --cpu=armv5te --cross-prefix=arm-none-linux-gnueabi- --target-os=linux --prefix=/usr/local/arm-none-linux-gnueabi --extra-cflags='-I/usr/local/arm-none-linux-gnueabi/include' --extra-ldflags='-L/tmp/lib' --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-pthreads --enable-libmp3lame --enable-librtmp --disable-encoder=zmbv --pkg-config=pkg-config --extra-version=Serviio
make

./ffmpeg

Freescale QorIQ P1022 PowerPC cross-compile for Synology NAS on Ubuntu Desktop 12.04 64bit (VirtualBox VM running on a Macbook Air):

#-----set up Synology toolchain
cd ~/Downloads
PART1="http://sourceforge.net/projects/dsgpl/files/DSM%204.1%20Tool%20Chains/"
PART2="PowerPC%20QorIQ%20Linux%202.6.32/gcc4374_eglibc2874_qoriq-GPL.tgz"
wget "${PART1}${PART2}"
tar xvzf gcc4374_eglibc2874_qoriq-GPL.tgz
sudo mv powerpc-none-linux-gnuspe /usr/local
export PATH=/usr/local/powerpc-none-linux-gnuspe/bin:$PATH
export AR=powerpc-none-linux-gnuspe-ar
export CC=powerpc-none-linux-gnuspe-gcc
export CXX=powerpc-none-linux-gnuspe-g++
export LD=powerpc-none-linux-gnuspe-ld
export RANLIB=powerpc-none-linux-gnuspe-ranlib
export CFLAGS="-I/usr/local/powerpc-none-linux-gnuspe/include"
export LDFLAGS="-L/usr/local/powerpc-none-linux-gnuspe/lib"

#-----libz static lib
wget http://zlib.net/zlib-1.2.7.tar.gz
tar xvzf zlib-1.2.7.tar.gz
cd zlib-1.2.7
./configure --prefix=/usr/local/powerpc-none-linux-gnuspe --static
make libz.a
cp libz.a /usr/local/powerpc-none-linux-gnuspe/lib
cp *.h /usr/local/powerpc-none-linux-gnuspe/include/
cd ..

#-----libbz2 static lib
wget http://bzip.org/1.0.6/bzip2-1.0.6.tar.gz
tar xvfz bzip2-1.0.6.tar.gz
cd bzip2-1.0.6
sed -i 's/^CC=gcc/CC=powerpc-none-linux-gnuspe-gcc/g' Makefile
sed -i 's/^AR=ar/AR=powerpc-none-linux-gnuspe-ar/g' Makefile
sed -i 's/^RANLIB=ranlib/RANLIB=powerpc-none-linux-gnuspe-ranlib/g' Makefile
#remove the tests - we can't run the native binaries
sed -i 's/^\(all: libbz2\.a bzip2 bzip2recover\) test/\1/' Makefile
make
make install PREFIX=/usr/local/powerpc-none-linux-gnuspe
cd ..

#-----libmp3lame static lib
wget http://sourceforge.net/projects/lame/files/lame/3.99/lame-3.99.5.tar.gz
tar xvzf lame-3.99.5.tar.gz
cd lame-3.99.5
./configure --prefix=/usr/local/powerpc-none-linux-gnuspe --host=powerpc-none-linux-gnuspe --build=x86_64-linux-gnu --enable-static --disable-shared --disable-decoder
make
make install
cd..

#-----libssl & libcrypto static libs
wget http://www.openssl.org/source/openssl-0.9.8v.tar.gz
tar xvzf openssl-0.9.8v.tar.gz
cd openssl-0.9.8v
#Some kind of strange issue where cross compilation parameters are ignored
#unless this fix is used http://marc.waeckerlin.org/computer/blog/openssl_fuer_windows_mingw_unter_linux_crosscomilieren
sed -i 's/\(die \"target already defined - \$target (offending arg\)/#\1/' Configure
./config --prefix=/usr/local/powerpc-none-linux-gnuspe no-shared linux-ppc
make
make install
cd ..

#-----librtmp 2.4 static lib
wget http://download.serviio.org/opensource/rtmpdump-c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5.tar.gz
tar xvfz rtmpdump-c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5.tar.gz
cd rtmpdump
#-----move all static libs to a separate folder to force compiler to use them
#-----http://www.gossamer-threads.com/lists/apache/dev/265052
mkdir /tmp/lib
cp /usr/local/powerpc-none-linux-gnuspe/lib/*.a /tmp/lib
#-----fix Makefile (won't compile without libdl linked)
#-----http://forum.luahub.com/index.php?topic=2390.0
sed -i.bak -e '/^LIB_OPENSSL\=/s/lcrypto/lcrypto \-ldl/' Makefile
make CROSS_COMPILE=powerpc-none-linux-gnuspe- SYS=posix prefix=/usr/local/powerpc-none-linux-gnuspe INC=-I/usr/local/powerpc-none-linux-gnuspe XLDFLAGS=-L/tmp/lib SHARED=
make install prefix=/usr/local/powerpc-none-linux-gnuspe SHARED=
cd ..

#-----gather all static libs again ready for FFmpeg compile
cp /usr/local/powerpc-none-linux-gnuspe/lib/*.a /tmp/lib
#-----remove unsupported URL line from pkgconfig/librtmp.pc
#-----pkg-config --exists --print-errors librtmp
sed -i -e '/^URL/d' /usr/local/powerpc-none-linux-gnuspe/lib/pkgconfig/librtmp.pc
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/local/powerpc-none-linux-gnuspe/lib/pkgconfig"

#-----FFmpeg
wget http://download.serviio.org/opensource/ffmpeg-N-42368-gbf53863.tar.gz
tar xvzf ffmpeg-N-42368-gbf53863.tar.gz
cd ffmpeg
#-----QorIQ P1022 CPU is based on the PowerPC e500v2 core which has Signal Processing Engine which is not a classic FPU design
#-----some QorIQ models have e500mc cores with true FPUs but these are not used in 2013 series Synology NAS
#-----http://en.wikipedia.org/wiki/QorIQ
#-----http://cache.freescale.com/files/32bit/doc/fact_sheet/QP1022FS.pdf?fpsp=1
#-----PowerPC e500v2 CPU-specific options (based on inspecting source https://github.com/FFmpeg/FFmpeg/blob/master/configure)
#-----pkg-config needs to be defined because with cross-prefix it assumes powerpc-none-linux-gnuspe-pkg-config which doesn't exist, and then librtmp won't be detected
./configure --arch=ppc --cpu=e500v2 --cross-prefix=powerpc-none-linux-gnuspe- --target-os=linux --prefix=/usr/local/powerpc-none-linux-gnuspe --extra-cflags='-I/usr/local/powerpc-none-linux-gnuspe/include' --extra-ldflags='-L/tmp/lib' --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-pthreads --enable-libmp3lame --enable-librtmp --pkg-config=pkg-config --extra-version=Serviio
make
./ffmpeg

Cross-compiling FFmpeg with librtmp for Intel CPU Synology NAS

I used this method to compile the FFmpeg binary for inclusion in my Serviio package, because I don’t have a NAS with an Intel CPU. Several people who tried to help were getting strange errors while trying to compile on their NAS units.

To begin, install 64bit Ubuntu Linux (I used a VM). As a test I first successfully cross-compiled ARM binaries using the same method but using the ARM Synology toolchain, since I was able to test the results. Once I got it working I did the following:

#-----set up Synology toolchain
cd ~/Downloads
wget http://sourceforge.net/projects/dsgpl/files/DSM%203.1%20Tool%20Chains/Intel%20x86%20Linux%202.6.32/gcc420_glibc236_pineview.tgz
tar xvfz gcc420_glibc236_pineview.tgz
sudo mv i686-linux-gnu /usr/local
sudo mv x86_64-linux-gnu /usr/local
#-----I think the Synology toolchain is anticipating being run on i686-linux-gnu, so we need 32bit libraries to even run the binaries
#-----http://maketecheasier.com/run-32-bit-apps-in-64-bit-linux/2009/08/10
sudo apt-get install ia32-libs
export PATH="/usr/local/x86_64-linux-gnu/bin:${PATH}"

#-----libz static lib
wget http://zlib.net/zlib-1.2.5.tar.gz
tar xvfz zlib-1.2.5.tar.gz
cd zlib-1.2.5
#-----http://www.crosscompile.org/static/pages/ZLib.html
#-----http://tinc-vpn.org/examples/cross-compiling-64-bit-windows-binary/
./configure --prefix=/usr/local/x86_64-linux-gnu --static
sed -i 's/^CC=gcc/CC=x86_64-linux-gnu-gcc/g' Makefile
sed -i 's/^LDSHARED=gcc/LDSHARED=x86_64-linux-gnu-gcc/g' Makefile
sed -i 's/^CPP=gcc -E/CPP=x86_64-linux-gnu-gcc -E/g' Makefile
sed -i 's/^AR=ar rc/AR=x86_64-linux-gnu-ar rc/g' Makefile
sed -i 's/^RANLIB=ranlib/RANLIB=x86_64-linux-gnu-ranlib/g' Makefile
make libz.a
cp libz.a /usr/local/x86_64-linux-gnu/lib
cp *.h /usr/local/x86_64-linux-gnu/include/
cd ..

#-----libbz2 static lib
wget http://bzip.org/1.0.6/bzip2-1.0.6.tar.gz
tar xvfz bzip2-1.0.6.tar.gz
cd bzip2-1.0.6
sed -i 's/^CC=gcc/CC=x86_64-linux-gnu-gcc/g' Makefile
sed -i 's/^AR=ar rc/AR=x86_64-linux-gnu-ar rc/g' Makefile
sed -i 's/^RANLIB=ranlib/RANLIB=x86_64-linux-gnu-ranlib/g' Makefile
make
make install PREFIX=/usr/local/x86_64-linux-gnu
cd ..

#-----libmp3lame static lib
wget http://sourceforge.net/projects/lame/files/lame/3.98.4/lame-3.98.4.tar.gz
tar xvfz lame-3.98.4.tar.gz
cd lame-3.98.4
./configure --prefix=/usr/local/x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu --build=x86_64-linux-gnu --enable-static --disable-shared --disable-decoder --enable-nasm
make
make install

#-----libssl & libcrypto static libs
ipkg install openssl-dev
wget http://www.openssl.org/source/openssl-0.9.8p.tar.gz
tar xvfz openssl-0.9.8p.tar.gz
cd openssl-0.9.8p
./config --prefix=/usr/local/x86_64-linux-gnu no-shared
sed -i 's/^CC= gcc/CC= x86_64-linux-gnu-gcc/g' Makefile
sed -i 's/^AR= ar /AR= x86_64-linux-gnu-ar /g' Makefile
sed -i 's/^ARD=ar /ARD=x86_64-linux-gnu-ar /g' Makefile
sed -i 's/^RANLIB= \/usr\/bin\/ranlib/RANLIB=x86_64-linux-gnu-ranlib/g' Makefile
sed -i 's/^MAKEDEPPROG= gcc/MAKEDEPPROG= x86_64-linux-gnu-gcc /g' Makefile
make
make install
cd ..

#-----librtmp 2.4 static lib
wget http://download.serviio.org/opensource/rtmpdump-c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5.tar.gz
tar xvfz rtmpdump-c58cfb3e9208c6e6bc1aa18f1b1d650d799084e5.tar.gz
cd rtmpdump
#-----move all static libs to a separate folder to force compiler to use them
#-----http://www.gossamer-threads.com/lists/apache/dev/265052
mkdir /tmp/lib
cp /usr/local/x86_64-linux-gnu/lib/*.a /tmp/lib
#-----fix Makefile (won't compile without libdl linked)
#-----http://forum.luahub.com/index.php?topic=2390.0
sed -i.bak -e '/^LIB_OPENSSL\=/s/lcrypto/lcrypto \-ldl/' Makefile
make CROSS_COMPILE=x86_64-linux-gnu- SYS=posix prefix=/usr/local/x86_64-linux-gnu INC=-I/usr/local/x86_64-linux-gnu XLDFLAGS=-L/tmp/lib SHARED=
make install prefix=/usr/local/x86_64-linux-gnu SHARED=
cd ..
#-----gather all static libs again ready for FFmpeg compile
cp /usr/local/x86_64-linux-gnu/lib/*.a /tmp/lib
#-----remove unsupported URL line from pkgconfig/librtmp.pc
#-----pkg-config --exists --print-errors librtmp
sed -i -e '/^URL/d' /usr/local/x86_64-linux-gnu/lib/pkgconfig/librtmp.pc
export PKG_CONFIG_PATH="${PKG_CONFIG_PATH}:/usr/local/x86_64-linux-gnu/lib/pkgconfig"

#-----FFmpeg 0.8.2 (slightly newer than the one at Serviio.org)
wget http://dl.dropbox.com/u/1188556/ffmpeg-HEAD-05a2673.tar.gz
tar xvfz ffmpeg-HEAD-05a2673.tar.gz
cd ffmpeg-HEAD-05a2673
#-----Intel CPU-specific options
#-----pkg-config needs to be defined because with cross-prefix it assumes x86_64-linux-gnu-pkg-config which doesn't exist, and then librtmp won't be detected
sudo apt-get install yasm
./configure --arch=x86_64 --enable-ssse3 --cross-prefix=x86_64-linux-gnu- --target-os=linux --prefix=/usr/local/x86_64-linux-gnu
--extra-cflags='-I/usr/local/x86_64-linux-gnu/include' --extra-ldflags='-L/tmp/lib' --enable-static --disable-shared --disable-ffplay
--disable-ffserver --enable-pthreads --enable-libmp3lame --enable-librtmp --pkg-config=pkg-config --extra-version=Serviio
make
make install
 

Serviio 0.6 package for Synology NAS with Web UI

Serviio-package-with-webUI

The Serviio Web UI, styled to look like the regular DSM control panel widgets

 

UPDATE – This is no longer the most recent package. I have released a new version and created a new blog post to keep the comments on topic.

My guide for installing Petr Nejedly’s excellent Serviio 0.5.2 on Synology has been a very popular post, and many people have got it running. However, the process is still complex enough to deter a lot of people and, as I learned more about my Synology NAS, I realised that I could automate the whole thing. The biggest obstacle was creating a package for Java, but adding locale support to the syno Linux also proved difficult.

The PHP Web UI is now included which you can use to manage Serviio once it’s installed. I have tried to fix most of the localization issues with it, and have edited the CSS to give it the look and feel of DSM as much as I could. You could also use Serviio Remote Console from another computer if you prefer. Any online content plugins (ending in .groovy) that are found in your NAS ‘public’ share will also be installed into Serviio’s plugins folder automatically during installation.

The package will allow future upgrades while preserving the media database and the online plugins, as long as Serviio itself is ok with that. You can see Serviio’s log by clicking More in the Package Centre. DSM Package Center installs the application to /volume1/@appstore/Serviio though from what I understand, on multi-volume systems the user is prompted for a destination volume. If you need to edit device profiles, add online content plugins, or look at the log in detail that’s where you’ll find the files. Bear in mind that a NAS, even an Intel Atom powered one, is unlikely to have sufficient CPU power to manage realtime video transcoding (e.g. from DivX to MPEG2), though it will manage remuxing MKV to M2TS and realtime audio transcoding.

 

Download

If you have DSM 3.2, you can install directly from Package Center. In Settings -> Package Sources add my package repository URL which is http://packages.pcloadletter.co.uk

If you’re still on DSM 3.1, download one of the following packages. Right-click, Save As:

Serviio uses some open source libraries without which it would not have been possible.
By downloading the software on this page you are agreeing to the terms of the original Serviio End User Licence Agreement.
I accept no liability for any damage that may occur to your data or your cat’s health as a result of using this software :) The scripts are shown in full below, so you are free to assess any risks yourself.

 

Instructions

This package can be installed on an unmodified NAS – no hacking is required. It has been tested on DSM 3.1 and DSM 3.2. Here’s what you need to do:

  • In the DSM User control panel enable the User Home service
  • In the DSM Web Services control panel enable Web Station
  • Using the DSM Package Center install my Java SE for Embedded Synology package
  • Download any online content plugins that you require and leave the .groovy file for each in your NAS’s public shared folder
  • Determine your NAS’s CPU type, and install the appropriate Serviio Synology package from the download link above
  • Give it some time to start (click More Info in Package Center to see the Log tab – check it has loaded all the renderer profiles), then you can use the Serviio icon in the DSM drop down menu in the top-right to launch the Web UI. This Serviio icon will only be visible to admin users in DSM
  • To use the Serviio Remote Console from a Windows PC edit ServiioConsole.exe.vmoptions in the Serviio folder and add the line: -Dserviio.remoteHost=192.168.x.x (replace with your NAS’s IP address). It can take a minute or so to start – this is normal. For details on how to configure the Remote Console on other operating systems refer to the Serviio FAQ. It seems that the first time Serviio starts with a blank database the Remote Console will get stuck showing the message “Serviio is updating its Media Library”. If that happens wait a couple of minutes, stop and restart Serviio via the Package Center. Give it another couple of minutes then the remote console should work fine.
  • Once the console is up, disable ‘Generate thumbnails for local videos’, and set the ‘Transcoded files location’ to /volume1/@tmp. Don’t forget to use the Users control panel in DSM to grant permission for the Serviio user to read your files (if they’re not in the public share)
  • When you add folders to your library you need to use the ‘Add path…’ button (not ‘Add local…’) and give the full Linux path (e.g. /volume1/share-name/Movies). There are issues with the Add Local ajax file browser which mean that it doesn’t work properly even if you give PHP access to the filesystem root
 

The DSM main drop-down menu, showing the Serviio Web UI icon

 

Upgrading from 0.5.2

If you want to upgrade from a manually installed 0.5.2, you will need to follow the steps below. I was considering automating it, but it gets complicated trying to remove people’s edits from /etc/profile which may not be entirely consistent.

  • Stop the Serviio 0.5.2 daemon by running: /opt/etc/init.d/S99serviio.sh stop
  • Copy your media database somewhere safe: cp -R /opt/serviio/library/db /volume1/public
  • Follow the uninstallation steps at the bottom of my original guide
  • Install my Java Synology package
  • Install the Serviio Synology package from the download link above but don’t start it yet
  • Copy your saved database into position: cp -R /volume1/public/db /volume1/@appstore/Serviio/library (warning – for people with multiple volumes, the @appstore folder is not always on /volume1 apparently)
  • Force ownership on database files: chown -R serviio /volume1/@appstore/Serviio/library
  • Force ownership on transcode cache: chown -R serviio /volume1/@tmp/Serviio
  • Start Serviio in the DSM Package Center
  • Follow the rest of the settings guidelines from above
 

Package scripts

For info, here are the scripts inside the package. The security-conscious among you can untar the package and take a look at the contents for yourself.

preinst

#!/bin/sh

#--------SERVIIO preinstall script
#--------package maintained at pcloadletter.co.uk

source /etc/profile

if [ -z ${JAVA_HOME} ]; then
        echo "Java is not installed or not properly configured. JAVA_HOME is not defined. " > $SYNOPKG_TEMP_LOGFILE
        echo "Download and install the Java Synology package from http://wp.me/pVshC-z5" >> $SYNOPKG_TEMP_LOGFILE
        exit 1
fi

if [ ! -f ${JAVA_HOME}/bin/java ]; then
        echo "Java is not installed or not properly configured. The Java binary could not be located. " > $SYNOPKG_TEMP_LOGFILE
        echo "Download and install the Java Synology package from http://wp.me/pVshC-z5" >> $SYNOPKG_TEMP_LOGFILE
        exit 1
fi

exit 0
 

postinst

#!/bin/sh

#--------SERVIIO postinstall script
#--------package maintained at pcloadletter.co.uk

#create serviio daemon user
synouser --add serviio `${SYNOPKG_PKGDEST}/bin/passgen 1 20` "Serviio daemon user" 0 "" ""

#determine the serviio user homedir and save that variable in the user's profile
#this is needed because librtmp needs to write a file called ~/.swfinfo
#and new users seem to inherit a HOME value of /root which they have no permissions for
SERVIIO_HOMEDIR=`cat /etc/passwd | sed -r '/Serviio daemon user/!d;s/^.*:Serviio daemon user:(.*):.*$/\1/'`
su - serviio -s /bin/sh -c "echo export HOME=${SERVIIO_HOMEDIR} >> .profile"

#change owner of Serviio folder tree
chown -R serviio ${SYNOPKG_PKGDEST}

#reset ownership on any pre-existing transcoding temp folder (same volume as appstore)
if [ -d ${SYNOPKG_PKGDEST}/../../@tmp/Serviio ]; then
        chown -R serviio ${SYNOPKG_PKGDEST}/../../@tmp/Serviio
fi
#reset ownership on any pre-existing transcoding temp folder (on volume1 in case app was installed on a different volume)
if [ -d /volume1/@tmp/Serviio ]; then
        chown -R serviio /volume1/@tmp/Serviio
fi

#create symbolic link to Serviio's version of FFmpeg
if [ -f /opt/bin/ffmpeg ]; then
        mv /opt/bin/ffmpeg /opt/bin/ffmpeg.bak.serviio
        ln -s ${SYNOPKG_PKGDEST}/bin/ffmpeg /opt/bin/ffmpeg
else
        ln -s ${SYNOPKG_PKGDEST}/bin/ffmpeg /bin/ffmpeg
fi

#set up symlink for the DSM GUI
if [ -d /usr/syno/synoman/webman/3rdparty ]; then
        ln -s ${SYNOPKG_PKGDEST}/DSM /usr/syno/synoman/webman/3rdparty/Serviio
fi

#move web UI files to Webstation root folder
mv ${SYNOPKG_PKGDEST}/web /volume1/web/serviio

#find path of public share (it might not be on /volume1)
PLUGIN_PICKUP=`cat /usr/syno/etc/smb.conf | sed -r '/\/public$/!d;s/^.*path=(\/volume[0-9]{1,3}\/public).*$/\1/'`

#pick up any plugins from the public share
mv ${PLUGIN_PICKUP}/*.groovy ${SYNOPKG_PKGDEST}/plugins

exit 0
 

start-stop-status

#!/bin/sh

#--------SERVIIO start-stop-status script
#--------package maintained at pcloadletter.co.uk

daemon_status ()
{
        ps | grep '^ *[0-9]* serviio' > /dev/null
}

case $1 in
        start)
                #start Serviio in background mode
                su - serviio -s /bin/sh -c "${SYNOPKG_PKGDEST}/bin/serviio.sh &"
                exit 0

        ;;
        stop)
                su - serviio -s /bin/sh -c "${SYNOPKG_PKGDEST}/bin/serviio.sh -stop"
                exit 0
        ;;
        status)
                if daemon_status ; then
                        exit 0
                else
                        exit 1
                fi
        ;;
        log)
        echo "${SYNOPKG_PKGDEST}/log/serviio.log"
                exit 0
        ;;
esac
 

preuninst

#!/bin/sh

#--------SERVIIO preuninstall script
#--------package maintained at pcloadletter.co.uk

#make sure that Serviio is stopped
${SYNOPKG_PKGDEST}/bin/serviio.sh -stop
sleep 6

exit 0
 

postuninst

#!/bin/sh

#--------SERVIIO postuninstall script
#--------package maintained at pcloadletter.co.uk

#remove serviio daemon user
synouser --del serviio

#remove symlink and reinstate any backed up version of FFmpeg
if [ -L /opt/bin/ffmpeg ] && [ -f /opt/bin/ffmpeg.bak.serviio ]; then
        rm /opt/bin/ffmpeg
        mv /opt/bin/ffmpeg.bak.serviio /opt/bin/ffmpeg
fi
if [ -L /bin/ffmpeg ]; then
        rm /bin/ffmpeg
fi

#remove DSM icon symlink
rm /usr/syno/synoman/webman/3rdparty/Serviio

#remove web UI
if [ -d /volume1/web/serviio ]; then
        rm -r /volume1/web/serviio
fi

exit 0
 

preupgrade

#!/bin/sh

#--------SERVIIO preupgrade script
#--------package maintained at pcloadletter.co.uk

#make sure that Serviio is stopped
${SYNOPKG_PKGDEST}/bin/serviio.sh -stop
sleep 6

#if a media database exists we need to preserve it
if [ -d ${SYNOPKG_PKGDEST}/library/db ]; then
        mkdir ${SYNOPKG_PKGDEST}/../serviio_db_migration
        mv ${SYNOPKG_PKGDEST}/library/db ${SYNOPKG_PKGDEST}/../serviio_db_migration
fi

#if online plugins exist we need to migrate them
if ls ${SYNOPKG_PKGDEST}/plugins/*.groovy; then
        mkdir ${SYNOPKG_PKGDEST}/../serviio_plugin_migration
        mv ${SYNOPKG_PKGDEST}/plugins ${SYNOPKG_PKGDEST}/../serviio_plugin_migration
fi

exit 0
 

postupgrade

#!/bin/sh

#--------SERVIIO postupgrade script
#--------package maintained at pcloadletter.co.uk

#use the backed up media database from the previous version
if [ -d ${SYNOPKG_PKGDEST}/../serviio_db_migration/db ]; then
        mv ${SYNOPKG_PKGDEST}/../serviio_db_migration/db ${SYNOPKG_PKGDEST}/library
        rmdir ${SYNOPKG_PKGDEST}/../serviio_db_migration

        #serviio daemon user has been deleted and recreated so we need to reset ownership (new UID)
        chown -R serviio ${SYNOPKG_PKGDEST}/library/db
fi

#use the backed up plugins from the previous version
if [ -d ${SYNOPKG_PKGDEST}/../serviio_plugin_migration/plugins ]; then
        cp ${SYNOPKG_PKGDEST}/../serviio_plugin_migration/plugins/*.groovy ${SYNOPKG_PKGDEST}/plugins
        if [ ! -z ${SYNOPKG_PKGDEST} ]; then
                if [ -d ${SYNOPKG_PKGDEST}/../serviio_plugin_migration ]; then
                        rm -r ${SYNOPKG_PKGDEST}/../serviio_plugin_migration
                fi
        fi
        #serviio daemon user has been deleted and recreated so we need to reset ownership (new UID)
        chown -R serviio ${SYNOPKG_PKGDEST}/plugins
fi

#reset ownership on transcoding temp folder (same volume as appstore)
if [ -d ${SYNOPKG_PKGDEST}/../../@tmp/Serviio ]; then
        chown -R serviio ${SYNOPKG_PKGDEST}/../../@tmp/Serviio
fi
#reset ownership on transcoding temp folder (on volume1 in case app was installed on a different volume)
if [ -d /volume1/@tmp/Serviio ]; then
        chown -R serviio /volume1/@tmp/Serviio
fi

#restart Web Station to clear webserver caches
if [ -f /usr/syno/etc/rc.d/S97apache-user.sh ]; then
        /usr/syno/etc/rc.d/S97apache-user.sh restart
fi

exit 0
 

Changelog:

  • 0.6.0.1-005 added Web Station dependency, EULA dialog, and links for Web UI and user forum in More Info
  • 0.6.0.1-004 test for package repo to allow update notification
  • 0.6.0.1 v3 hopefully fixed an issue with the Serviio DSM icon in DSM 3.2 on NAS units without Optware installed
  • 0.6.0.1 v2 inclusion of a modified version of the PHP Web UI
  • 0.6.0.1 v1 new minor Serviio release with some updated international translations – will upgrade 0.6 preserving the media library
  • 0.6 v1 first public release
  • 0.6b4 v2 fixed permissions on transcode temporary folder following upgrade, avoiding the need for a reboot
  • 0.6b4 v1 added upgrade scripts to allow media database migration (install future packages over the top of this one – database is preserved)
  • 0.6b3c v2 fixed HOME env var for serviio user (to fix librtmp issues with BBC iPlayer) and removed the need to edit the passwd file to change the shell (safer)
  • 0.6b3c v1 initial spk test release