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> 
 
 

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

  1. tmm1

    Thanks so much for documenting all this! Glad to see that sources for a modern ffmpeg with the evansport patches is finally available.

    I was wondering if you know whether a standard i686-linux compiled binary can be run on the evansport, or if the evansport gcc toolchain provided by Synology has special patches for that platform? I tried to compile a regular 32-bit linux binary on an Ubuntu Trusty i686 VM, but am seeing “exec format errors” when I try to execute it on a DS214play/DS415play

    Reply
    1. patters Post author

      I built a standard i686 version for Evansport which works – but I used the same syno toolchain. I don’t think that the compiler is modified but remember that Evansport is 32bit, not x86_64. You also need to make sure your libc version on your Ubuntu box isn’t newer than the one in the Synology toolchain. The extra Evansport functionality comes from a load of additional libraries (like libismd_videnc etc.). You would need all these libraries and their include files to make a working build with Evansport enhancements, and they may have certain mods specifically for Synology’s hardware implementation.

      Reply
    2. patters Post author

      You still need to cross compile using the methods I’ve outlined here – because there will be libc differences and so on, even though you’re on i686 also. The evansport toolchain is AFAIK identical to the 32bit one Synology makes available for other Intel CPUs.

      Reply
  2. echable

    Sorry for what is probably a very basic question – I have only a very superficial understanding of this – but will compiling this give ffmpeg 3.2.2 with hw transcoding on the evansport synology’s ? Or is this just for educational purposes really, the best currently funtioning ffmpeg (2.7…) is automatically installed with the serviio 1.8 synology package ?

    If I wanted an introduction to how to follow these instructions do anyone have any tips to good websites for beginners ?

    Reply
    1. patters Post author

      No – the hardware transcoding depends on source code modifications which are specific to the Synology-provided sources. The regular 3.2.2 FFmpeg sources won’t have this.

      Reply
    1. patters Post author

      Not yet, but it’s likely they will be using Gstreamer instead of FFmpeg since that appears to be the way Synology have implemented this feature on the 2017 models. This would make it very difficult to integrate with Serviio.

      Reply
      1. tmm1

        It seems they have not published any source related to the rtd1296. I couldn’t find the gstreamer anywhere in dsgpl either.

      2. tmm1

        Oops, I spoke too soon. A few days ago they published 6.2 toolkits, and it includes rtd1296-gcc494_glibc220_armv8-GPL and ds.rtd1296-6.2.dev. What’s interesting is that the dpkg/info list in the rtd1296 env does not list gstreamer, but does include an ARM64 version of the ffmpeg-2.7.x package.

      3. tmm1

        I downloaded the rtd1296 ffmpeg source from https://sourceforge.net/projects/dsgpl/files/Synology NAS GPL Source/22259branch/rtd1296-source/ffmpeg-2.7.x.txz/download, but it doesn’t seem to contain any changes specific to that model/cpu.

        FYI, here’s a clean copy of the diff between ffmpeg 2.7.1 and Synology’s fork: https://gist.github.com/tmm1/280f11b9c252cec87167c4bd406b508c. Most of the diff is the evansport changes. The diff isn’t _too_ bad, and could be applied to ffmpeg 3.4 with a little bit of work.

      4. tmm1

        It appears the DS118 uses “synovideoconversiond” that’s part of VideoStation instead of gstreamer or ffmpeg.

      5. patters Post author

        I’ve taken a look at this tonight finally. Neither the Toolkit nor the DSM sources from Synology contain the headers for these Realtek libraries so I think they’re as good as useless unfortunately.

        I have updated the Java 8 Embedded package though, to add experimental support for installing the full JDK 8 for aarch64. If you own a DS218play then please let me know if it works. Then I’ll try initially to get FFmpeg built with x264 but without OpenMAX support. According to a comment here, even that could be problematic though.

      6. patters Post author

        I’ve got my dev environment set up for aarch64, and I’ve been able to cross compile FFmpeg with libx264, omx, and the other stuff Serviio needs. I have no way to test though, since I don’t own one of these new Realtek SoC equipped systems. Do you have any hardware to test on?

        Reading about the OpenMAX standard on the wiki: Bellagio is an IL – integration layer. It seems to me that it’s still expecting a DL to talk to the HW codec/GPU (probably what the Realtek drivers are for in the VideoStation package). Also, this Bellagio software hasn’t been touched in 7 years.

        EDIT – I see, once Bellagio is compiled you have to register the DL components, which is likely to be possible with those binary drivers I guess. Someone’s gonna have to test this on hardware though. There’s an OMX component registration binary that I can script on Serviio startup.

        Unfortunately for the time being FFmpeg only supports H.264 encoding (via codec h264_omx), but not decoding. It’s stated here. So neither H.264 nor HEVC decoding for this SoC until FFmpeg adds that API support :(

        Assuming what I’ve built works, the integration of rtd1296 hardware H.264 encoding with Serviio should be easy since I can re-use the wrappers I wrote for Intel Evansport.

  3. ArcticXWolf

    Hey,

    I currently own a DS218play and would like to do some encoding on my NAS with ffmpeg. I read your post and also your post in the forum and it seems that you haven’t been able to use hardware acceleration with the DS218play. As I would like to try it myself (or maybe help you, if you are still interested in working on it), I wanted to ask you, if you can share your way to compile ffmpeg with libomx support and the compilation of bellagio.

    Greetings and thanks for your work so far :)

    Reply

Leave a comment