Category Archives: Multimedia

Compiling FFmpeg for Windows with libfaac and libmp3lame

Having realised how simple it is to compile stuff on my Synology NAS I decided to finally get something built on Windows using free tools. It’s not really much different, but I had to do a lot of searching to finally gather all the necessary configure parameters.

First we need to set up the build environment. MinGW stands for ‘Minimalist GNU for Windows’. Download the MinGW-get installer, which will install everything you’ll need including MSYS which is a Unix shell complete with all the essential binaries. Run the MinGW-get installer and select Download latest repository catalogs.
In the options add the C++ compiler (needed for FAAC) and select MSYS Basic System and MinGW Developer Toolkit.

Now download the source .tar.gz files of:

Launch MinGW Shell from the Start Menu.
Copy those downloaded files to C:\MinGW\msys\1.0\home\yourusername
For each one run:

tar xvfz packagename.tar.gz
 

Then in order, cd into each extracted directory and…

For NASM and yasm:

./configure
make
make install
 

For FAAC (we need to disable the mp4v2 option to avoid a nasty compiler error – took me a long time to discover):

./bootstrap CC='gcc -mno-cygwin'
./configure --prefix=/mingw --exec-prefix=/mingw --enable-static --disable-shared --with-mp4v2=no
make
make install
 

For LAME:

./configure --prefix=/mingw --exec-prefix=/mingw --enable-static --disable-shared --disable-decoder --enable-nasm
make
make install
 

For FFmpeg:

./configure --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-memalign-hack --enable-libmp3lame --enable-nonfree --enable-libfaac --arch=x86 --enable-runtime-cpudetect --enable-w32threads
make
make install
 

The compiled ffmpeg.exe will be in C:\MinGW\msys\1.0\local\bin

Update – I tried to set this up on my work PC which runs 64 bit Windows 7 and I discovered that it’s a world of pain, so I’ll have to amend this post once I solve it.

5.1 channel audio through ordinary headphones using MPC-HC

Blown-Away Man

Though I have owned a surround sound system before, I don’t currently have the space for one. I was recently considering buying gaming headphones with support for Dolby Digital 5.1 channel audio which I could also use for watching films. With some more reading I discovered that these hardware solutions will only work with a Dolby Digital source (AC-3). The problem is that I have a lot of content with DTS audio which the chips in these products don’t support, not to mention MP4 files with multichannel AAC audio.

Reading the specs of these headphones, I discovered that they license a technology called Dolby Headphone – some clever signal processing developed by Lake DSP in Sydney. Early 5.1 channel headphones actually contained multiple tweeters mounted at different positions inside each ‘can’ which apparently weren’t very convincing, but this better approach is more of an emulation – one that relies on the fact that you only have two ears. It’s able to model the audio delays and reflections of a room containing a 5.1 setup, plus it seems to boost up the low frequencies so you’re really aware of the LFE channel. I don’t really understand why there isn’t much awareness of Dolby Headphone. It’s not at all new – look at this 1998 press release!

What’s also not very widely known is that Dolby Headphone can be encoded in software, through the likes of PowerDVD’s audio decoder, regardless of whether your sound chip is Dolby Headphone certified (as some now are). It’s also not particularly processor intensive – my Sony Vaio P can play H.264 movies and process DH with its Intel GMA 500 GPU and meagre 1.33GHz Intel Atom Z520 CPU.

 

What does Dolby Headphone sound like?

Listen for yourself – plug in some headphones and try these DH encoded samples. The choice of movie trailer isn’t exactly showcasing the 360 degree soundstage, but it was quite tricky to encode so I didn’t want the hassle of sampling a scene from an actual film. I can assure you that the action sequences in District 9 for instance sound a whole lot better with Dolby Headphone enabled.

5.1 channel test Dolby Headphone DH1

I Am Legend trailer 2ch downmix by FAAD decoder normalized (no DH)

I Am Legend trailer 5.1ch Dolby Headphone DH1

These samples are 192Kbps MP3 files for size reasons. The slight metallic high-end ringing to the deep bass is an encoder artifact from the conversion to MP3 using the LAME encoder, and it was still present when I tried 320Kbps. The channel test clip was taken from http://www.lynnemusic.com/surround.html and the I Am Legend trailer was from http://www.h264info.com/clips.html.

 

How to get it working for AC-3, AAC, and DTS multichannel sources

In a previous post I explained how to setup Media Player Classic Home Cinema to use a third party h.264 decoder with DXVA support. MPC-HC has several key advantages as a media player – it’s open source, it’s lean, it’s extremely configurable, and it plays pretty much any format. I use it for my Sony Vaio P to keep CPU use as low as possible on its rather limited Intel Atom processor. Many people use MPC-HC for their Home Theatre PCs, hence this article.

A guide for configuring Dolby Headphone using PowerDVD’s CyberLink Audio Decoder already exists (with files):
http://www.head-fi.org/forum/thread/405417/guide-dolby-headphone-in-mpc-zoom-player

However that information isn’t sufficient. The complication is that when this decoder is used outside the PowerDVD software, it only works with DTS audio streams even though it should also support AC-3. Reading around, it seems that the AC-3 support works in Windows XP but not in Vista nor in Windows 7.

The next piece of the puzzle can be found here on the forum for Zoom Player, a commercial media player:
http://forum.inmatrix.com/index.php?showtopic=7224

The important point is that the CyberLink decoder can accept a multichannel LPCM input, so you can use another decoder (ffdshow tryouts in this case) to convert the source bitstream into LPCM first, then feed that to the CyberLink decoder. This means that multichannel AAC audio found in MP4 containers could have Dolby Headphone applied too. The above post describes how to do this for Zoom Player, but we’re interested in MPC-HC. The next obstacle is figuring out how to link multiple decoders together in MPC-HC – something I couldn’t find any info about despite spending hours searching online.

The key to understanding this is knowing how the modular Windows DirectShow media layer works. If you’ve already played with MPC-HC you will be familiar with adding and removing filters, as well as the concepts of ones that are built into MPC-HC and those that are external. All these DirectShow filters have ‘pins’ which are their inputs and outputs – their connection points in other words. Each pin has a defined list of media types it will and won’t accept. As long as you comply with this, they can be threaded together to create a ‘graph’. The simplest way to illustrate this is with a screenshot of the aptly named GraphStudio, and this example shows the combination of filters I used to make one of the sample audio clips earlier in this post:

So how can we construct a similar sequence in MPC-HC? In the end I finally found the crucial bit of information in a single sentence of the excellent self-explanatory and unofficial All the things you may want to know about Media Player Classic – HomeCinema:

When a video file is loaded in MPC-HC, MPC-HC will run through this list from top to bottom and load the relevant filter(s), create a graph from them and play the file.

Bingo! All you need to do is explicitly list them in the right order in MPC-HC’s External Filters window and MPC-HC should thread them together, compatible pins permitting. Sure enough, it works.

Would you believe it, there is yet another hitch – the CyberLink Audio Decoder expects LPCM input channels to be in a certain order, one that differs from the default order in ffdshow. This is trivial to fix, though it will mess things up if you rely on ffdshow to decode other media formats.

 

The guide

You’ll need MPC-HC obviously, the CyberLink Audio Decoder will need to be installed (from PowerDVD), and you’ll need ffdshow tryouts installed (I used the SVN release, since the beta is years old).

Once ffdshow is installed, open up its Audio Decoder configuration utility from the Start Menu. In the Output section select 16bit LPCM and apply.

Disable the Mixer and configure the Swap Channels menu as follows. Note the different order:

Open MPC-HC and hit O to bring up the options menu. In the Internal Filters section de-select AAC, AC3 and DTS from Transform Filters on the right.

UPDATE – Contrary to what I had originally written here, do not disable the built-in audio switcher! I hadn’t understood that this is needed for when you have a video file with multiple audio tracks. If it’s not enabled then all audio tracks play simultaneously. You could consider disabling Regain volume if you want to minimize the amount of additional processing.

Audio switcher settings

In the External Filters section make sure that ffdshow is set to prefer, and is listed above CyberLink Audio Decoder (also set to prefer). Use Add Filter… to set Microsoft DTV-DVD Audio Decoder to Block.

Remember that DTS audio bitstreams don’t require the ffdshow treatment. To avoid having to reconfigure this for different movie formats we can customize the recognized media types for the ffdshow filter. As per the screenshot above, select ffdshow Audio Decoder then scroll down until you find MEDIASUBTYPE_DTS and delete it. DTS files will now skip ffdshow and will be entirely handled by CyberLink Audio Decoder. If you ever need to revert this change click Reset List.

Open a movie file in MPC-HC, then select Play -> Filters -> CyberLink Audio Decoder and you will be able to select Dolby Headphone like so:

On the next tab you can choose between three DH modes. I found a nice succinct guide to the three modes here:
http://www.head-fi.org/forum/thread/444681/headphones-with-good-sound-stage-better-with-dolby-headphone-or-no-need-for-it#post_6003214

Sadly it seems that every time you load a new file into MPC-HC you need to re-enable Dolby Headphone (the setting doesn’t stick for some reason). Also, owing to the channel order swapping in ffdshow you’ll find that in ordinary stereo mode you’re only getting the Front Left and Front Center channels. As a result you’ll probably want to de-select the Swap Channels setting in the ffdshow Audio decoder tool when you’re not using headphones. A small price to pay though… Enjoy!

 

Further reading

There is a guide to using Dolby Headphone for listening to two channel music in the audio player foobar2000 here:
http://www.head-fi.org/forum/thread/447089/5-1-headphone-experience-foobar-configuration-for-all-stereo-music-files

I’ve given it a try and I don’t really think it’s worth it. When I had a actual surround system I used to play all my music on Dolby Pro Logic IIx and it sounded very good using all the speakers. It meant you could be sitting anywhere in the room and still get nice separation and so on. However, creating those additional channels only to merge them back down to two channels often doesn’t seem to add much since they were virtual to start with. In side by side listening comparisons I often preferred the original stereo mix, but admittedly it does seem to vary with the way they’ve been mastered (remember, to hear the original stereo you have to remove all selected DSPs, not just DH).

Serviio 0.5.2 DLNA server on Synology NAS

last updated 24/08/2011 – fixed typos in locale section
Serviio-Synology

This guide is now redundant – I have released a Synology package for Serviio 0.6!

 

Serviio is an excellent free Java DLNA media server by Petr Nejedly which focuses on minimizing the amount of unnecessary media transcoding, and maximizing the use of renderer devices’ supported features. Some of the more main-stream servers like Windows Media Player just brute-force everything to MPEG2 video and MP3 audio, which degrades quality and wastes power. Though some servers like Mezzmo are better and will play Matroska files, even they tend to transcode all audio to AC-3 regardless of source type. As a Java app Serviio will run on anything that has a JVM, and the media tool it relies on is the open source and therefore highly portable FFmpeg. All these design priorities make Serviio an ideal choice to run on a NAS device since, when paired with a renderer with good format support like a Sony Bluray Player, the NAS will barely ever be transcoding.

I was about to buy a new large external hard disk, but once I realised that Serviio could probably run on a NAS I started looking at one of these instead. Synology seemed to offer a lot of value and seemed to have the sort of user-community enjoyed by my old Linksys NSLU2, which I promptly sold on eBay for almost what I had paid for it in 2007. I considered the value DS110j model but I decided to go for the more expensive DS111 on the basis that the double CPU speed and RAM would probably be a wise move.

This guide outlines how to get Serviio 0.5.2 running on the Marvell Kirkwood ARM CPUs found in most of the 2011 product line-up, but Synology devices also exist with Freescale PowerPC and Intel Atom processors. The key problem is finding a Java virtual machine, but FFmpeg also needs compiling from source. This is because although there is an FFmpeg binary bundled with DSM 3.0, it’s too old and lacks support for features critical to Serviio. This guide could be used for other CPU architectures, but the compilation options for FFmpeg need adapting.

In the Synology DSM go to Control Panel > Terminal > enable SSH.

Read this Synology wiki document about modifying your NAS carefully and install the bootstrap for your model.

Download the PuTTY SSH client.

Connect to your NAS’s IP address using SSH. Use the root account (same password as admin). I suggest that you perform the mod at the bottom of this post to enable colour directory listings and a more descriptive shell prompt which should reduce the chance of accidentally being in the wrong directory.

We need to install the development tools. Type:

ipkg install optware-devel
 

It will halt and complain that package wget-ssl clashes with wget. Continue with:

ipkg remove wget
cp /usr/syno/bin/wget /opt/bin
ipkg install wget-ssl
ipkg update
ipkg upgrade
ipkg install optware-devel
 

This time it will finish successfully.

Update – It seems that there is a serious problem with running ipkg on a clean install of DSM 3.1. This guide was written before it was released, and though I have since upgraded my Synology I haven’t encountered that issue, but there have been many comments about it. User mayk on the Synology forum seems to have the solution here. Use the extra wget verbosity switch to find out the exact package URL for the following two packages, then manually download them with wget and install:

cd /volume1/@tmp
ipkg install -verbose_wget libidn
wget url1
ipkg install -verbose_wget wget-ssl
wget url2
ipkg install filename1
ipkg install filename2
 

Next we need to install Lame MP3 encoder, providing libmp3lame which FFmpeg will be compiled to depend on, and the Nano text editor (much easier to use than vi):

ipkg install lame
ipkg install nano
 

JamVM is a JVM that gets mentioned a lot in connection with NAS systems, but it’s only Java 1.5, and Serviio needs version 1.6. Download the Java SE Embedded Runtime from Oracle, selecting the ARM v5 Linux version (note that there is a PowerPC e500v2 version – the CPU core in Synology products which use the Freescale mpc85x3). Unfortunately for PowerPC Synology owners, this depends on a higher version of glibc than the Synology DSM provides for this architecture. Until JamVM supports Java 1.6, or Synology update to glibc 2.4 you won’t be able to follow this guide on PowerPC models. This may have changed since DSM 3.1 was released.

You will need to sign up to receive the download link by email. It’s free to use for non-commercial self-educational use. Use your computer to save it into the top level shared folder of your NAS, which will probably be /volume1/public on the NAS filesystem. Then:

cd /volume1/public
mv ejre-1_6_0_21-fcs-b09-linux-arm-sflt-eabi-headless-27_sep_2010.tar.gz /volume1/@tmp
cd /volume1/@tmp
tar xvzf ejre-1_6_0_21-fcs-b09-linux-arm-sflt-eabi-headless-27_sep_2010.tar.gz
mkdir /opt/java
mv ejre1.6.0_21 /opt/java
 

Synology’s Linux build has no localisation support built in, though it does use UTF-8 character encoding for the filesystem. That’s no problem for storage, however the Java VM inherits the locale setting of the host OS. Since this is undefined Serviio, and all other Java software, will default to US-ASCII which is a big problem if you have filenames with non-US characters. The solution is to obtain the missing files to add locale support from the Synology toolchain, which is distributed under the GPL:

#-----for ARM CPU
cd /volume1/@tmp
wget http://sourceforge.net/projects/dsgpl/files/DSM%203.1%20Tool%20Chains/Marvell%2088F628x%20Linux%202.6.32/gcc421_glibc25_88f628x.tgz
tar xvfz gcc421_glibc25_88f628x.tgz
cd arm-none-linux-gnueabi/arm-none-linux-gnueabi/libc/usr/bin
cp locale /opt/bin
cp localedef /opt/bin
cp -R arm-none-linux-gnueabi/arm-none-linux-gnueabi/libc/usr/share/i18n /usr/share
#-----keep another copy safe in case DSM is reinstalled later
cp -R arm-none-linux-gnueabi/arm-none-linux-gnueabi/libc/usr/share/i18n /opt/share
mkdir /usr/lib/locale
localedef -c -f UTF-8 -i en_US en_US.utf8

#-----for Intel CPU
cd /volume1/@tmp
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
cd i686-linux-gnu/i686-linux-gnu/bin
cp locale /opt/bin
cp localedef /opt/bin
cp -R i686-linux-gnu/i686-linux-gnu/share/i18n /usr/share
#-----keep another copy safe in case DSM is reinstalled later
cp -R i686-linux-gnu/i686-linux-gnu/share/i18n /opt/share
mkdir /usr/lib/locale
localedef -c -f UTF-8 -i en_US en_US.utf8
 

Now use nano to edit some configuration files (Ctrl-o saves, and Ctrl-x exits).
First edit the profile for all bash shell users:

nano /opt/etc/profile
 

Make the changes shown in bold:

#
# Bash initialization script
#

PS1=”[\u@\h \W]$ ”
PATH=/opt/sbin:/opt/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/java/ejre1.6.0_21/bin
LD_LIBRARY_PATH=/opt/lib:${LD_LIBRARY_PATH}
JAVA_HOME=/opt/java/ejre1.6.0_21
LANG=en_US.utf8

export PS1 PATH LD_LIBRARY_PATH JAVA_HOME LANG

 

Save and exit. Next edit the profile for all ash shell users (root):

nano /etc/profile
 

At the last line make the changes in bold:

PATH=/opt/java/ejre1.6.0_21/bin:/opt/bin:/opt/sbin:$PATH
JAVA_HOME=/opt/java/ejre1.6.0_21
LANG=en_US.utf8
export JAVA_HOME LANG

 

Save and exit. Now install the Serviio application:

cd /volume1/@tmp
wget http://download.serviio.org/releases/serviio-0.5.2-linux.tar.gz
tar xvzf serviio-0.5.2-linux.tar.gz
mv serviio-0.5.2 /opt/serviio
 

In the DSM Control Panel got to Web Services > Web Applications tab > Enable Web Station.
Install AcidumIrae’s PHP web UI for Serviio. You will need to have enabled Web Station for the directory /volume1/web to exist.

wget http://labs.softjourn.com/attachments/download/67/serviio-0.5.2.1b.zip
unzip serviio-0.5.2.1b.zip
mv serviio-0.5.2 /volume1/web/serviio
 

You should already be able to browse to http://your_NAS_IP/serviio and see the user interface, though it will complain with a big red X that Serviio is not running.

FFmpeg depends on the libbz2 and zlib libraries, and although both are installed along with the optware-devel package, FFmpeg will only look for them in /lib rather than in their actual location in /opt/lib. Copies of the existing symbolic links will be fine:

cp /opt/lib/libbz2.so.1.0 /lib
cp /opt/lib/libz.so.1 /lib
 

Compile the patched version 26303 of FFmpeg from the Serviio download page. Running cat /proc/cpuinfo it is clear that the DS111 is an ARM 5TE platform so I enabled those specific optimizations:

cd /volume1/@tmp
wget http://download.serviio.org/opensource/ffmpeg-26303.tar.gz
tar xvzf ffmpeg-26303.tar.gz
cd ffmpeg
./configure --arch=arm --enable-armv5te --prefix=/opt --extra-cflags='-I/opt/include' --extra-ldflags='-L/opt/lib' --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-libmp3lame
make
 

Notice that the ./configure command is line wrapped – it’s all one command. The make command takes approximately 25 minutes on the 1.6GHz CPU and will show many warnings during compilation, but this is expected.

Update – Thanks to bakman for pointing out that for Intel Atom CPUs you will need to install the assembler YASM and also use the following ./configure parameters:

ipkg install yasm
./configure --arch=x86_64 --enable-ssse3 --prefix=/opt --extra-cflags='-I/opt/include' --extra-ldflags='-L/opt/lib' --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-libmp3lame
 

Another Update – Thanks to gregorio for parameters for Freescale PowerPC processors:

./configure --arch=powerpc --disable-altivec --prefix=/opt --extra-cflags='-I/opt/include' --extra-ldflags='-L/opt/lib' --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-libmp3lame
 

When the compile is done, install it.

make install
 

Try running ffmpeg and check the compile time to make sure the newly compiled one is running. You should see this but with your compilation date and time:

FFmpeg version UNKNOWN, Copyright (c) 2000-2011 the FFmpeg developers
built on Feb 6 2011 01:14:38 with gcc 4.2.3
configuration: –arch=arm –enable-armv5te –prefix=/opt –extra-cflags=-I/opt/include –extra-ldflags=-L/opt/lib –enable-static –disable-shared –disable-ffplay –disable-ffserver –enable-libmp3lame
libavutil 50.36. 0 / 50.36. 0
libavcore 0.16. 0 / 0.16. 0
libavcodec 52.108. 0 / 52.108. 0
libavformat 52.92. 0 / 52.92. 0
libavdevice 52. 2. 3 / 52. 2. 3
libavfilter 1.72. 0 / 1.72. 0
libswscale 0.12. 0 / 0.12. 0
Hyper fast Audio and Video encoder
usage: ffmpeg [options] [[infile options] -i infile]… {[outfile options] outfile}…

Use -h to get full help or, even better, run ‘man ffmpeg’

If you see the text below then something is wrong – this is the version included with DSM 3.0:

FFmpeg version SVN-r20167-snapshot, Copyright (c) 2000-2009 Fabrice Bellard, et al.

In the DSM User Control Panel create a new user called serviio and set a password. Give that user access to the paths that contain the media you want to serve. Click the User Home button and enable the User Home Service. Go back to your SSH session and type:

nano /etc/passwd
 

Be very careful editing this file. A wrong move here could trash your system. Notice that the serviio user has a shell of /sbin/nologin. Change this to /bin/sh like the admin user has. Nano may try to line wrap this line as you type if you added an long account description. If it does, delete the carriage return before the line break and pull it back onto one line. Save and exit.

Now we’ll create the Serviio daemon start and stop script:

nano /volume1/@tmp/S99serviio.sh
 

Paste in the following text (mouseover and use the icon in the top right to copy):

#!/bin/sh

User=serviio

case "$1" in

stop)
        echo "Stop Serviio..."
        su -l $User -c "/opt/serviio/bin/serviio.sh -stop" > /dev/null 2>&1 &
        ;;

start)
        # start Serviio in background mode
        su -l $User -c "/opt/serviio/bin/serviio.sh" > /dev/null 2>&1 &
        echo "Start Serviio..."

        #check libs FFmpeg depends on (in case DSM was upgraded)
        if [ ! -f /lib/libbz2.so.1.0 ]; then
                cp /opt/lib/libbz2.so.1.0 /lib
        fi
        if [ ! -f /lib/libz.so.1 ]; then
                cp /opt/lib/libz.so.1 /lib
        fi
        ;;

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

esac
 

Now make it executable and set the serviio user to be the owner of the Serviio folder (so it can create the media database, and log files):

chmod +x /volume1/@tmp/S99serviio.sh
chown -R serviio /opt/serviio
 

Test the script manually by running:

/volume1/@tmp/S99serviio.sh start
ps
 

The running process list should show the serviio user running the Serviio launcher shell script and the JVM like so:

 2542 root      9080 S N  /usr/syno/sbin/synomkflvd
 2589 root      3908 S    /usr/syno/sbin/sshd
 2591 root      5376 S    /usr/syno/apache/bin/httpd -f /usr/syno/apache/conf/
 2599 root      5944 S    /usr/syno/apache/bin/httpd -f /usr/syno/apache/conf/
 2600 root      5936 S    /usr/syno/apache/bin/httpd -f /usr/syno/apache/conf/
 2628 root     58920 S    /usr/syno/apache/bin/httpd
 2687 nobody   58920 S    /usr/syno/apache/bin/httpd
 2688 nobody   58920 S    /usr/syno/apache/bin/httpd
 2689 nobody   59500 S    /usr/syno/apache/bin/httpd
 2695 root     11560 S    /usr/syno/sbin/mDNSResponder -f /tmp/mDNSResponder.c
 2703 root      5568 S    /usr/syno/apache/bin/httpd -f /usr/syno/apache/conf/
 2949 root      5568 S    /usr/syno/apache/bin/httpd -f /usr/syno/apache/conf/
 3025 root      5568 S    /usr/syno/apache/bin/httpd -f /usr/syno/apache/conf/
 3087 root      8664 S N  /bin/ntfs-3g -o uid=1024,gid=100 /dev/sdk1 /volumeUS
 3518 root      8852 S    /usr/syno/sbin/cnid_metad
 3524 root     15132 S    /usr/syno/sbin/afpd -c 256 -g guest -n SynologyDS111
 3566 nobody   58920 S    /usr/syno/apache/bin/httpd
 7747 root      6660 S    sshd: root@pts/0
 7826 root      5404 S    -ash
13567 serviio   2940 S    -sh -c /opt/serviio/bin/serviio.sh
13570 serviio   2940 S    /bin/sh /opt/serviio/bin/serviio.sh
13575 serviio   501m S    /opt/java/ejre1.6.0_21/bin/java -Xmx384M -Djava.net.
13917 root      5404 R    ps
 

Stop the daemon with:

/volume1/@tmp/S99serviio.sh stop
 

Check the web UI or the process list again and make sure it did indeed stop. If it’s all ok, we need to move the daemon launcher script so it starts automatically on boot:

mv /volume1/@tmp/S99serviio.sh /opt/etc/init.d
 

Shutdown the NAS and restart.

Update – previously I had used the directory /usr/syno/etc/rc.d, but this is destroyed when the DSM software is updated. /usr/local/etc/rc.d is the official Synology location for 3rd party daemon init scripts but I found that it doesn’t work, so I used /opt/etc/init.d instead which also survives a DSM upgrade. I just tested this by upgrading to DSM 3.1-1605 and Serviio remained intact. I only had to copy the sym links for the libraries FFmpeg needs (“cp /opt/lib/libbz2.so.1.0 /lib” and “cp /opt/lib/libz.so.1 /lib”).

 

Web UI integration with the Synology DSM

I read the official Synology notes for 3rd party developers and decided to make some icons. The result is pretty neat:

Open an SSH session:

cd /usr/syno/synoman/webman/3rdparty
wget http://dl.dropbox.com/u/1188556/blog/serviio_syno_DSM.zip
unzip serviio_syno_DSM.zip
rm serviio_syno_DSM.zip
nano serviio/config
 

The file loaded into nano will look like this, and you need to edit the IP address to match the IP of your Synology (either put your syno on a static IP, or set a reservation in your broadband router’s DHCP server options).

{
 ".url": {
    "org.serviio.serviio": {
      "type": "legacy",
      "allUsers": true,
      "title": "Serviio",
      "desc": "DLNA Media Server",
      "icon": "images/icon_{0}.png",
      "url": "http://192.168.1.202/serviio/index.php"
    }
  }
}
 

I can’t find a way to avoid manually specifying the IP address like this – relative paths can’t be used because the Synology runs two different webservers: the DSM one on port 5000 without PHP, and the PHP-enabled Web Station one on port 80.

Log out of DSM and log back in. You will see the Serviio icon in the pull down menu in the top left, which you can drag to the desktop if you prefer:

 

Serviio settings

Navigate to the Transcoding tab. Set the transcoded files location to /volume1/@tmp. Failure to do this will result in temporary files being written to /tmp which will fill up the partition it’s on the moment you remux a 4GB movie, which would prevent you from logging into the NAS.

I recommend de-selecting Generate thumbnails for local videos in the Metadata tab. Note that you have to click Save on each tab or any change will not take effect. As you’ll see if you have a DLNA renderer that supports thumbnails, Serviio retrieves good ones from the online databases it checks so they’re not really needed. Often FFmpeg will get stuck trying to generate a thumbnail for a video and will lock the CPU at 100% for long periods of time. This issue was raised in this Serviio forum thread.

You can use the Library tab to add the media folders you want to share. Note that the Add Local… button will fail because the web service user does not have access to the root of the filesystem (probably a good thing security-wise). Use Add Path… instead and express the paths as I have done in the first screenshot above. Be sure that the serviio user has been granted read privileges over the folders you add (User Control Panel in DSM).

Update – If you really want to use the Ajax file browser UI, then go to DSM Control Panel > Web Services > PHP Settings tab > open_basedir and append /volume1: to the start of that list. Then on the Web Applications tab, disable Web Station, Ok, enable Web Station. Go back to your SSH session and run:

nano /volume1/web/serviio/afb/config.php
 

Change the value of $path from / to /volume1/public (or the top level shared folder where your media resides). You’ll notice however that when you use Add local button in the Serviio Library tab it’s very buggy. It will only list a maximum of 5 child folders from each node.

 

Performance

The Synology seems perfectly able to transcode DTS audio in a hi-def Matroska file down to 2 channel AC3 in MPEG-TS while copying the H.264 stream. The CPU use leaps up to 100% but I guess that’s because it’s running ahead transcoding down to the end of the file (and is CPU-bound).

If I play something that’s only remuxing the container and copying both audio and video streams then the CPU stays at around 40% (because it’s I/O-bound) then 5 minutes into a film it falls away to pretty much idle – I guess it has finished remuxing to the temporary file.

Memory use even while running Serviio is around 20% at idle, 30% during a remux with audio transcode, though I have noticed that with a larger library this creeps up to around 70%. I have a 2011 product so it has 256MB of RAM. This seems to indicate that the value line of products (with the j suffix) like the DS211j should run Serviio on their 128MB. They have a 1.2GHz CPU though versus 1.6GHz on mine (and the DS110j is only 800MHz), so it would need testing by someone.

All in all it would seem that the Synology products are very capable Serviio appliances!

 

Uninstalling

Log in as root and stop Serviio, then delete a couple of libraries which had been copied to /lib:

/opt/etc/init.d/S99serviio.sh stop
rm /lib/libbz2.so.1.0
rm /lib/libz.so.1
 

In the DSM User Control Panel delete the user called serviio. Undo the changes that you made to /opt/etc/profile and /etc/profile (the JAVA_HOME and java path modifications marked in bold earlier in the guide).

To remove the web UI, in DSM go to Web Services > Web Applications tab > Disable Web Station. Then:

rm -r /volume1/web/serviio
rm -r /usr/syno/synoman/webman/3rdparty/serviio
 

Finally, re-download the bootstrap for your model of NAS and run it again. It will tell you to delete a few folders and restart. This will completely trash all optware ipkg packages (i.e. everything in /opt) and undo everything else you did in this guide without affecting your data partitions. If you had any other ipkg packages installed since installing Serviio, these would also be lost.

Live H.264 streaming from Digital Rapids to Helix and Wowza

Helix Mobile Server 14

I had a few difficulties with getting this set up so it’s probably worth sharing them here. Digital Rapids apparently don’t support live broadcasting from their hardware encoder companion software ‘Stream’ to Helix Mobile Server even though the latter supports RTP and SDP, and the encoder clearly offers these up as possible exports when you’re using the Digital Rapids AVC for Web codec profile (an optional extra purchase):

Stream encoder RTP broadcast SDP settings

What happens is that when you copy the SDP file into your Helix server’s Content/rtpencodersdp folder and try to connect to the stream pointing a media player at rtsp://helixserver/rtpencoder/live_stream.sdp it will fail, with the following error appearing in rmerror.log:

21-Sep-2010 13:47:14.062 tmplgpln(6076): 32: Error retrieving URL `rtpencoder/live_stream.sdp’ (Invalid path)

Following contact with Helix support, it turns out that the SDP file which the encoder creates does not declare the bandwidth of the audio track using a b= line as per RFC 4566 – though apparently this is an optional field. You will need to manually add this. 64Kbps results in b=AS:64 as below:

v=0
o=- 1287599430 1287599438 IN IP4 10.45.0.155
s=Session Streamed by Digital Rapids Corp Stream Server
t=0 0
a=type:broadcast
c=IN IP4 10.45.0.150/15
m=audio 20002 RTP/AVP 97
a=rtpmap:97 MPEG4-GENERIC/90000/2
a=fmtp:97 streamtype=5;profile-level-id=1;mode=AAC-hbr;sizelength=13;indexlength=3;indexdeltalength=3;bitrate=64000;config=1390
a=control:trackID=1
b=AS:64
m=video 20000 RTP/AVP 96
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=4D4020;sprop-parameter-sets=J01AIJZWDQ/8mApEAAADAAQAAAMAyhA=,KO8GDMg=
a=cliprect:0, 0, 416, 234
a=control:trackID=2

I also discovered that QuickTime Player is not a reliable player to use for testing as it sometimes crashes, and will not play H.264+AAC streams which VLC has no issue with. This view was echoed by Helix support.

I did have another problem – one of aspect ratios. The Digital Rapids Stream encoder will author files with garbage aspect ratio metadata if the resolution isn’t exactly 16:9 to the nearest even number of pixels. I read somewhere else that the chosen picture width should be a multiple of the x part of the aspect ratio. Here is FFMPEG’s analysis of a non-compliant resolution:

Stream #0.0(eng): Video: h264, yuv420p, 412×232 [PAR 37376:14889 DAR 401453:90053], 399 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc

and a correct 16:9 resolution:

Stream #0.0(eng): Video: h264, yuv420p, 416×234 [PAR 1:1 DAR 16:9], 399 kb/s, 25 fps, 25 tbr, 25 tbn, 50 tbc

 

Wowza Media Server 2.1.2

Setting this up was also a little bit confusing, given that the encoder offers you so little insight into what the problem is if it doesn’t start. Anyway, there are excellent tutorials on the Wowza forums – this is the one we need.

As you can see from the screenshot I run Wowza Media Server on port 80 rather than 1935 to make sure that clients using restricted and proxied wifi networks (hotels etc.) are not prevented from viewing the streams:

Digital Rapids Stream RTMP media server settings

There is a gotcha though. In the forum tutorial they mention setting up security, but this is only for RTP encoders, not RTMP. I had been setting the credentials in the dialog above, but in fact you need to leave the drop-down on Server with no password.

Fortunately you can secure RTMP stream publishing in Wowza – you will need to make the following additions to live/application.xml to invoke an additional module:

       <Module>
              <Name>ModuleSecureURLParams</Name>
              <Description>ModuleSecureURLParams</Description>
              <Class>com.wowza.wms.plugin.security.ModuleSecureURLParams</Class>
       </Module> 
</Modules>
<!-- Properties defined here will be added to the IApplication.getProperties() and IApplicationInstance.getProperties() collections -->
<Properties>
       <Property>
              <Name>secureurlparams.publish</Name>
              <Value>mysecret4231.doPublish</Value>
       </Property>
</Properties>

You would then append this secret as a query string on the stream name as below:

Security settings for RTMP stream publishing

The mount point for testing with VLC for this example would be still be rtsp://10.45.0.151:80/live/mystream
or from an iPhone http://10.45.0.151/live/mystream/playlist.m3u8 (assuming AVC Level 3.0 or lower and standard AAC audio).

DXVA VC-1 playback on Intel GMA 500

This will only work on Vista or Windows 7. I suggest using the following test clips since they are already on your computer if using Windows 7:

  • C:\Users\Public\Videos\Sample Videos\Wildlife.wmv
  • C:\Windows\Performance\WinSAT\Clip_1080_5sec_VC1_15mbps.wmv

As you can see from the DXVA Checker tool, the GMA 500 can decode VC-1 in hardware. Though Windows 7 includes DXVA hardware assisted playback of H.264 out of the box, for some reason it only considers the GMA 500 capable of VC-1 motion compensation acceleration which is a small part of the entire decode process – so VC-1 playback is choppy.

The good news is that for Windows Vista Intel released a bundle of DXVA codecs for the GMA 500. They’re not available from the Intel drivers website but fortunately Sony’s US site has them. The installer will only extract the drivers if it’s running on a Vaio P, but you can use a tool like Universal Extractor to unpack them (look in \tempexefolder). On Windows 7 you will need to run Setup.exe in Vista compatibility mode otherwise it will fail.

Once the decoder is installed you may notice that you cannot get it to work in Media Player Classic Home Cinema, even by forcing it to be the preferred decoder (as with H.264 in my other post). This is because MPC-HC works with the DirectShow multimedia framework, but the Intel VC-1 decoder is written for Media Foundation – Microsoft’s replacement framework which launched with Windows Vista.

This unfortunately means that you’re limited to using Windows Media Player for hardware accelerated VC-1 content, so subtitles are not going to be possible. The next problem is that WMP aggressively selects its own decoder in favour of the Intel one. There is no neat way to set preference order as with DirectShow, so we need to make some Registry edits.

Open Regedit and navigate to HKLM\Software\Classes\MediaFoundation\Transforms\Preferred.

Export the whole branch and keep it somewhere safe (say foundation-orig.reg). Still in Regedit, right-click on this Preferred key and edit the permissions. Take ownership (Advanced > Owner tab), then grant Full Control to Administrators.

At the level \Transforms notice that there is an entry with a long alphanumeric CLSID for each registered decoder. Find the one called WMVideo Decoder MFT, which should be {82d353df-90bd-4382-8bc2-3f6192b76e34}. Find the CLSID for Intel® Media Codecs VC-1 Decoder for Intel® System Controller Hub, which ought to be {2b53d708-ffe1-4da3-b3a8-f8ec247c374f}.

Using Notepad, load the registry backup of the Preferred key you exported. This is a list of video formats also represented by CLSIDs, together with the CLSID of the decoder which will be used to play them back. So all we need to do is replace all instances of {82d353df-90bd-4382-8bc2-3f6192b76e34} with {2b53d708-ffe1-4da3-b3a8-f8ec247c374f} and save as foundation-mod.reg (always keep the original just in case!). Then double-click it and commit the changes.

Now if you run DXVA Checker and click on Check DirectShow/MediaFoundation Decoders at the bottom and browse to a VC-1 clip, you should see the following:

Intel Media Codec VC-1 DXVA

Note that some guides will tell you to take ownership then rename the file C:\WINDOWS\SYSTEM32\WMVDECOD.DLL which may well achieve the same result, but it will break the Windows Experience Index test process – it plays a WMV clip with this decoder during the benchmark and will fail with an error if that file is missing.

By switching between the original and modified .reg files and comparing playback you’ll notice that the Intel VC-1 decoder uses around 50% CPU on a 1.33GHz Atom Z520 Vs. 100% and stuttering with the Windows one.

Update – the Intel decoder seems to have difficulty rendering crossfades, as you can see from the artifacting while playing this nVidia demo clip and some of the content on the Microsoft WMV HD content showcase. It’s a shame the decoder doesn’t seem to be actively maintained, however all of these clips are years old so perhaps they were encoded with immature encoders.

Update 2 – I have since noticed that the clips from Microsoft’s showcase and that nVidia one are not in fact VC-1. They’re WMV3 which was a slightly earlier codec. The true VC-1 clips which I have tried are decoded without artifacts. You can check the video codec used in a file by running ffmpeg -i on them.

Continue to DXVA H.264 playback on Intel GMA 500 with subtitles (Windows 7)

DXVA H.264 playback on Intel GMA 500 with subtitles (Windows 7)

Update – This guide was updated on 04/04/2012

Out of the box, Windows 7’s Windows Media Player (WMP) will play HD video using the Intel GMA 500 and DirectX Video Acceleration (DXVA) to do the decode. Using the Matroska Splitter you will also be able to play MKV files. However, they may occasionally stutter and use a fair amount your humble Atom Z series CPU’s power (around 40-50% of 1.33GHz), and you won’t be able to use subtitles.

The PowerDVD H.264 decoder on the other hand will use about 10-20% less CPU, is less prone to locking up, and by using Media Player Classic Home Cinema (MPC-HC) you gain subtitle rendering support. Apparently PowerDVD does itself support MKVs with subtitles but on the several occasions I have attempted this with the trial version it has locked up and crashed. If you don’t have the PowerDVD decoder, you can use the ‘ffdshow tryouts’ open source decoder which is a very good alternative, but seems to suffer some screen tearing during high motion scenes while subtitles are enabled.

Ingredients

  • Media Player Classic Home Cinema (MPC-HC 1.60.4014 at the time of updating this document) – don’t confuse with Media Player Classic, this is a separate version
  • Matroska Splitter (optional) – this reads the MKV container format. MPC-HC has its own implementation included but you could use this if you want to play MKV files in Windows Media Player
  • Optional DirectVobSub subtitle renderer for Windows Media Player (will not work for MKVs), useful for Xvid/DivX files though
  • PowerDVD’s H.264 decoder CyberLink Combo MPEG-2/H.264/VC1 Decoder v.1.0.4960.3320
  • or ffdshow tryouts decoder – don’t use the beta release, it doesn’t have the DXVA decoder. I tested with the SVN build.
  • DirectX End-User Runtimes (June 2010) – required for the EVR Custom Presenter renderer which is needed for subtitle compositing

Method

Firstly disable Aero.

If you want to have subtitles in WMP for Xvid/DivX movies then download and register vsfilter.dll. To do this, copy the DLL to C:\Windows\System32 and open a Command Prompt using right-click & “Run as Administrator”. Then type
regsvr32 c:\windows\system32\vsfilter.dll

If later on you want to remove this, just open the Command Prompt as Administrator and type
regsvr32 /u c:\windows\system32\vsfilter.dll

When it’s registered you can open an Xvid AVI file in WMP and, as long as there’s an SRT subtitle file with the same filename as the AVI then you will see your subtitles. There will be a new icon in the system tray which will allow you to toggle subs, as well as choose the language if there are several sets of subs.

Now install Haali Splitter if you want MKV support in WMP and other players. When you load a MKV, it behaves in a similar way to VSFilter (icon in systray), except it’s even more versatile since MKV containers can have different soundtracks too.

Next, install MPC-HC.

Now use WinRAR to extract the DirectX End-User Runtime file you downloaded. In WinRAR, select File > Open, then change the filename dropdown from All archives to All archives including self-extracting. Browse to your downloaded directx_Jun2010_redist.exe and open it. Inside you will find some more archives. Drag and drop to extract the file Jun2010_d3dx9_43_x86.cab, then open this in WinRAR too. Extract the file d3dx9_43.dll into the folder C:\Program Files\Media Player Classic – Home Cinema.

Finally, install the Cyberlink H.264 decoder or ffdshow. During setup ffdshow will offer a choice of decoders to use, pick libavcodec (not ffmpeg-mt).

Now we need to configure MPC-HC. Load it then go to View -> Options.
Go to Playback, and make sure Auto-load subtitles is set (assuming you want them). Note that you can also set language code preference orders for audio and subs:

Auto load subtitles

Move to the section called Output. If you will never use subtitles select EVR and don’t touch anything else.
If you do want subtitle support, use EVR Custom Presenter, reduce the EVR buffers from 5 to 4, and check the Alternative Vsync and D3D Fullscreen boxes. With the default settings the additional load of compositing subtitles brings the framerate down below 24fps, however by using these last two options we can just maintain 24fps.

Output settings

Now select the heading Internal filters and uncheck both H.264 options on the right. This stops MPC-HC using its own support for those features, since we’re going to use external modules for those. If you’re using the CyberLink Video Decoder version I posted above you can optionally uncheck the MP4/MOV and MKV source filters which will cause the CyberLink ones to be used instead (it doesn’t seem to improve performance).

Internal filters

Under the heading External Filters click Add. Then browse to the CyberLink Video Decoder and add it. Make sure to set it to Prefer on the right as shown. If you’re using ffdshow then instead add ffmpeg DXVA video decoder an set to Prefer.
If you installed the Vsfilter.dll subtitle driver (some other media players/codec packs will register this) we need to add DirectVobSub (auto-loading version) too, but select Block on the right. This prevents it from loading, since we’re using MPC-HC’s subtitle renderer. Apparently the way DirectVobSub renders is fundamentally incompatible with DXVA:

External filters

Close MPC-HC for the settings to take effect. At this point it’s a good idea to associate .mkv files with MPC-HC. If videos are launched by double clicking like this, when you pin MPC-HC to your Start Menu it will have that child menu showing you the last ten or so files you launched which is very useful.

Start an H.264 encoded MKV in MPC-HC and as it starts to play, right-click on the video window and select Filters -> CyberLink Video Decoder. Check that DXVA is selected. I believe that HAM mode uses OpenCL on GPUs that support it (the GMA 500 doesn’t) which if I remember was recommended for ATI GPUs, the early ones having glitchy DXVA implementations apparently. If you’re using EVR Custom Presenter you wont be able to do this with D3D Fullscreen enabled, so toggle it and reload MPC-HC to verify this step.

CyberLink decoder filter settings

Close and reopen MPC-HC and you should be done! Though using D3D Fullscreen reduces tearing and seems to keep the framerate higher when using the EVR Custom Presenter renderer you cannot right-click and see the normal MPC-HC GUI elements. You have to use Ctrl-C to exit playback to modify settings. Two essential keyboard shortcuts are A to switch audio track, and S to switch subtitle track, though shortcut keys do exist for just about everything, and can be customised in the Player > Keys menu in Options.

If using ffdshow you also need to enable hardware acceleration by running Start Menu > All Programs > ffdshow > DXVA video decoder configuration:

DXVA decoder settings

ffdshow’s built-in subtitle rendering seems to produce smeary artifacts on the picture so ignore those options and use MPC-HC’s subtitles instead.

If you have a video that won’t playback nicely with this setup then it’s likely that the bitrate is too high for the GMA 500 to cope with (a straight 1:1 rip from Blu-ray for instance) or perhaps the file has not been encoded to be fully DXVA compliant (quite likely with older stuff). Framerates over 24fps cannot really be played unfortunately.
There are some H.264 movie trailers available here for testing.
In my experience the GMA 500 in my VAIO P will play most 1080p content perfectly well, even outputting to a TV at 1920 x 1080. If in doubt about whether it’s dropping frames, while using EVR Custom Presenter you can press CTRL-J several times to view the frame rate (get rid of the graph and verbose text – they slow it down even more!).

Further reading

This handy guide explains in detail what all the options in MPC-HC mean.

Continue to DXVA VC-1 playback on Intel GMA 500 or learn how to get a surround sound experience from ordinary headphones.

Time lapse video in Apple iMovie 9

iMovie 9 allows you to speed up and slow down clips, but only to a maximum of 2000%. I recently needed to squeeze 25 minutes down to less than 30 seconds, which is more than that limit. I realised that I could speed up the clip, export, then re-import but that would result in a drop in quality caused by yet another transcode.

When you edit the speed of a clip, iMovie asks you to convert the source clip. It’s already performing one transcode to a QuickTime .mov file if it’s not already in that format. Fortunately it’s possible to edit the headers of this resulting .mov file using an Apple developer tool called Dumpster, available here:

http://developer.apple.com/quicktime/download/

You need to expand the branches (work on a copy of your file for safety) and navigate to the timeScale atom:

moov > trak > mdia > mdhd > timeScale

Dumpster QuickTime header editing

I edited this from 50 frames per second to 2500 (so 50x faster). This will give the desired result, allowing fine tuning back in iMovie but if you want to be really thorough you should also edit the duration of your clip. Not doing this means that the clip still shows up as being its original length in the iMovie thumbnails, with the last frame of video displayed over and over. To fix that follow this method:

http://www.dvinfo.net/forum/high-definition-video-editing-solutions/472820-changing-frame-rate-mov-file.html