Monday, May 19, 2014

Install OSX 10.7.x on iMac5,1

Although Apple has decided to block the installation of OS X 10.7 on older incarnations of the iMac (e.g. iMac5,1), the platform is able to run this OS X version more or less smoothly.
The only real requirement is a 64bit CPU aka Core2Duo.

To trick the installer into accepting your system, one has to modify a file on the installation medium (DVD, USB ...) and add the platform/mainboard ID to the list of supported systems.

The board ID can be determined with a quick call in terminal:

  ioreg -l | grep -A 20 "class IOPlatformExpertDevice"

which should output various information about your iMac, similar to

  +-o iMac5,1  
    | {
    |   "compatible" = <"iMac5,1">
    |   "version" = <"1.0">
    |   "board-id" = <"Mac-F42787C8">
    |   "IOInterruptSpecifiers" = (<0900000005000000>)
    |   "IOPolledInterface" = "SMCPolledInterface is not serializable"
    |   "serial-number" = <553253000xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
    |   "IOInterruptControllers" = ("io-apic-0")
    |   "IOPlatformUUID" = "00000000-0000-1000-8000-0016Cxxxxxxxx"
    |   "IOPlatformArgs" = <0010f10100c0f001902af60100000000>
    |   "clock-frequency" = <00d69327>
    |   "manufacturer" = <"Apple Computer, Inc.">
    |   "IOConsoleSecurityInterest" = "IOCommand is not serializable"
    |   "IOPlatformSerialNumber" = "CKxxxxxxx"
    |   "system-type" = <01>
    |   "product-name" = <"iMac5,1">
    |   "model" = <"iMac5,1">
    |   "name" = <"/">
    |   "IOBusyInterest" = "IOCommand is not serializable"
    | }

If this call does not produce any output, grep for "board-id" straight away.

The crucial line is

  "board-id" = <"Mac-F42787C8">

The string in the brackets has to be added to [...]

After the installation of OSX updates, your OS may fall back to the original files and one has to boot with the installation medium again and patch /System/Library/CoreServices/PlatformSupport.plist
Just add your board-id again at the end of the list.


Friday, May 9, 2014

Adjustment of PHP output buffering in DSM

The HTTP server in DSM is by default configured to buffer and cache the output generated by PHP.

The caching can be disabled in /etc/php/conf.d/user-settings:
 opcache.enable = 0
 opcache.enable_cli = 0

The output buffering does not only take place in PHP but also in the mod_fastcgi module of Apache.

The settings for this module reside in /etc/httpd/conf/extra/mod_fastcgi.conf

Just change
  FastCgiExternalServer /php-fpm-handler [...] -idle-timeout 3600
to
  FastCgiExternalServer /php-fpm-handler [...]  -idle-timeout 3600 -flush

to disable caching if you want to be able to send e.g. status message already during the processeing of a PHP request.

Wednesday, May 7, 2014

Calling DCMTK commands like DCM2PNM from PHP

When a command is called from PHP via the exec command, it runs with the user environment of the Apache/nginx host process (e.g. www, http, wwwrun).

As some of the DCMTK commands rely on the DCMDICTPATH variable, they may fail as this is normally not set for the www user.

You can overcome this by adding
putenv("DCMDICTPATH=/usr/share/dicom.dic:/usr/share/diconde.dic:/usr/share/private.dic");
to the beginning of your PHP script / before calling the respective DCMTK command.

Notice: You may have to adjust the paths according to your installation of DCMTK.


Tuesday, May 6, 2014

Packaging cross compiled libraries and binaries

Since I cross compile for my Synology DSM on a virtual machine that has no direct network access to the NAS, I have to transfer the binaries via USB drives.

The following shell scripts have been handy in this case. You might have to adjust the -N parameter, which causes tar to include only files newer than the provided date.
Use it to exclude all the binaries that come with the Synology toolchain.

Binaries

tar -N '2014-05-01' \
--no-recursion \
--exclude="*.tar.gz" \
--exclude="pack*" \
--exclude="pkgcon*" \
--exclude="xml2Con*" \
--exclude="engines" \
--exclude="gcc" \
--exclude="gcj*" \
--exclude="ldscr*" \
--exclude="*.a" \
--exclude="loggin*" \
-zcvf \
bin_`date +"%Y%m%d_%H%M"`.tar.gz *

Libraries

tar -N '2014-05-01' \
--no-recursion \
--exclude="*.tar.gz" \
--exclude="pack*" \
--exclude="pkgcon*" \
--exclude="xml2Con*" \
--exclude="engines" \
--exclude="gcc" \
--exclude="gcj*" \
--exclude="ldscr*" \
--exclude="*.a" \
--exclude="loggin*" \
--exclude="libdbus*" \
-zcvf \
lib_`date +"%Y%m%d_%H%M"`.tar.gz *

DCMTK for Synology DSM

The DCMTK package provides a profound set of tools for the handling of DICOM data.

Determining all parameters to successfully build it for the Synology DSM on QorIQ / PPC was a bit tricky, that is why I am posting my configuration here.
Especially the last parameter (ac_cv_my_c_rightshift_unsigned=no) is important, as otherwise the configure script for cross compiling will fail.

The prerequisites include OpenSSL and libpng.

You can find the source code for DCMTK on the project homepage. The current official version is 3.6.0, but you can find the 3.6.1 snapshot already on their FTP server.

export DEVROOT="/usr/local/powerpc-none-linux-gnuspe"
export PKG_CONFIG_PATH=/usr/local/powerpc-none-linux-gnuspe/lib/pkgconfig
export AS="$DEVROOT/bin/powerpc-none-linux-gnuspe-as"
export AR="$DEVROOT/bin/powerpc-none-linux-gnuspe-ar"
export LD="$DEVROOT/bin/powerpc-none-linux-gnuspe-ld"
export RANLIB="$DEVROOT/bin/powerpc-none-linux-gnuspe-ranlib"
export LDFLAGS="-L$DEVROOT/lib"
export ARFLAGS=cru
export CC="$DEVROOT/bin/powerpc-none-linux-gnuspe-gcc"
export CXX="$DEVROOT/bin/powerpc-none-linux-gnuspe-g++"
export ARCH=powerpc-linux
export CROSS_COMPILE=powerpc-none-linux-gnuspe-
export STRIP="$DEVROOT/bin/powerpc-none-linux-gnuspe-strip"

./configure --prefix=/usr/local/powerpc-none-linux-gnuspe \
 --host=powerpc-none-linux-gnuspe \
 --disable-dcmjpeg \
 --with-libpng \
 --with-openssl \
 --enable-std-includes \
 --disable-debug \
 --with-zlib \
 --without-libwrap \
 ac_cv_my_c_rightshift_unsigned=no

FFmpeg with h264, AAC and VP8/VP9 support

Credits for the FFmpeg patch go to PC LOAD LETTER blog.

Please excuse the quite inconsistent use of env and export, I will clean this up when I find the time.

Currently this set includes the following libraries:
  • libx264(h264)
  • libmp3lame  (MP3)
  • libfaac (AAC)
  • libvpx (VP8/VP9)

Including
  • libfreetype
  • fontconfig
is only necessary if you want to embed captions or watermarks in your video files. If you do not need it, remove the corresponding lines in the FFmpeg configuration below.

Eventually you also have to add the zlib library.

After configuring each library, compile it with make and then call make install to install it.
The prefix parameter causes the libraries to be placed in lib under /usr/local/powerpc-none-linux-gnuspe as proposed by the Synology toolchain.

zlib

Download it from here and configure it:
CC=powerpc-none-linux-gnuspe-gcc \
./configure --prefix=/usr/local/powerpc-none-linux-gnuspe

libx264

Retrieve the libx264 code via GIT:
 git clone git://git.videolan.org/x264.git libx264

The configuration can be invoked via
env \
CC=/usr/local/powerpc-none-linux-gnuspe/bin/powerpc-none-linux-gnuspe-gcc \
LD=/usr/local/powerpc-none-linux-gnuspe/bin/powerpc-none-linux-gnuspe-ld \
RANLIB=/usr/local/powerpc-none-linux-gnuspe/bin/powerpc-none-linux-gnuspe-ranlib \
CFLAGS="-I/usr/local/powerpc-none-linux-gnuspe/include -mcpu=8548 \
 -mhard-float -mfloat-gprs=double" \
LDFLAGS="-L/usr/local/powerpc-none-linux-gnuspe/lib" && \
./configure \
 --prefix=/usr/local/powerpc-none-linux-gnuspe --cross-prefix=powerpc-none-linux-gnuspe- \
 --enable-shared --disable-asm --host=powerpc-none-linux-gnuspe \
 --disable-opencl \
 --disable-avs \
 --disable-ffms \
 --disable-gpac \
 --disable-lavf \
 --disable-swscale \
 --enable-pic \
 --enable-strip  

libmp3lame

Get the source code on Sourceforge and configure it:
./configure \
  --prefix=/usr/local/powerpc-none-linux-gnuspe \
  --host=powerpc-none-linux-gnuspe \
  --enable-shared \
  --disable-static \
  --disable-decoder

libfaac

Get the source code on www.audiocoding.com and configure it:
./configure --prefix=/usr/local/powerpc-none-linux-gnuspe/ \
   --host=powerpc-none-linux-gnuspe

libvpx

Fetch the source code:
 git clone https://chromium.googlesource.com/webm/libvpx libvpx
and configure it:
export LDFLAGS="-L/usr/local/powerpc-none-linux-gnuspe/lib"
export CROSS=powerpc-none-linux-gnuspe-
export CFLAGS="-I/usr/local/powerpc-none-linux-gnuspe/include -mcpu=8548 \
 -mhard-float -mfloat-gprs=double"
./configure \
 --prefix=/usr/local/powerpc-none-linux-gnuspe \
 --enable-shared \
 --target=ppc32-linux-gcc \
 --enable-vp8 \
 --enable-vp9 \
 --disable-examples \
 --disable-docs \
 --enable-postproc \
 --enable-vp9-postproc \
 --enable-pic \
 --disable-altivec \
 --disable-use_x86inc \
 --disable-unit_tests \
 --libc=/usr/local/powerpc-none-linux-gnuspe/powerpc-none-linux-gnuspe/libc/lib/

FFmpeg

Retrieve the FFmpeg source code via GIT:
  git clone git://source.ffmpeg.org/ffmpeg.git ffmpeg
The compilation of the FFMPEG source code to be run QorIQ/PPC systems requires a little patch.
--- ffmpeg/libavcodec/ppc/dsputil_ppc.c 2012-02-17 18:20:07.000000000 +0000
+++ ffmpeg-patched/libavcodec/ppc/dsputil_ppc.c 2012-10-18 22:15:50.740992688 +0100
@@ -116,7 +116,11 @@
  
     /* below the constraint "b" seems to mean "Address base register"
        in gcc-3.3 / RS/6000 speaks. seems to avoid using r0, so.... */
+    #if 1
+    __asm__ volatile("dcbz %0, %1" : : "r" (fakedata_middle), "r" (zero));
+    #else
     __asm__ volatile("dcbzl %0, %1" : : "b" (fakedata_middle), "r" (zero));
+    #endif
  
     for (i = 0; i < 1024 ; i ++) {
         if (fakedata[i] == (char)0)

A possible configuration for FFmpeg could be as follows.
Important is to disable of the Altivec code. When left enabled, the execution of the binaries fails with a segmentation fault.
Additionally I have disabled debugging, some audio/input/output filters, ffplay and ffserver that are not required in my case.

#
# FFMPEG configuration calling script
# 
env \
CFLAGS="-mcpu=8548 \
  -mhard-float \
  -mfloat-gprs=double" \
MARCH="-mcpu=8548 -mhard-float -mfloat-gprs=double" \
LDFLAGS="-L/usr/local/powerpc-none-linux-gnuspe/lib -L/usr/local/powerpc-none-linux-gnuspe/source/faac-1.28/libfaac/.libs" \
 && export PKG_CONFIG_PATH=/usr/local/powerpc-none-linux-gnuspe/lib/pkgconfig/ \
 && ./configure --prefix=/usr/local/powerpc-none-linux-gnuspe \
  --cross-prefix=/usr/local/powerpc-none-linux-gnuspe/bin/powerpc-none-linux-gnuspe- \
  --enable-cross-compile \
  --disable-yasm \
  --disable-altivec \
  --target-os=linux\
  --arch=ppc \
  --cpu=e500v2 \
  --enable-pic \
  --enable-pthreads \
  --disable-debug \
  --enable-libx264 \
  --enable-libmp3lame \
  --enable-libfaac \
  --disable-swscale-alpha \
  --disable-indev=alsa \
  --disable-indev=dv1394 \
  --disable-outdev=alsa \
  --disable-encoder=dca \
  --disable-encoder=ac3 \
  --disable-encoder=ac3_fixed \
  --disable-encoder=eac3 \
  --disable-decoder=dca \
  --disable-decoder=eac3 \
  --disable-decoder=truehd \
  --disable-iconv \
  --disable-podpages \
  --disable-ffplay \
  --disable-ffserver \
  --enable-gpl \
  --enable-version3 \
  --enable-nonfree --disable-doc \
  --extra-cflags='-I/usr/local/powerpc-none-linux-gnuspe/include' \
  --extra-ldflags='-L/usr/local/powerpc-none-linux-gnuspe/lib' \
  --enable-shared \
  --disable-static \
  --extra-version=ses \
  --enable-libfreetype \
  --pkg-config=pkg-config \
  --enable-fontconfig \
  --enable-optimizations \
  --enable-libvpx
Welcome to Nasology

This blog is dedicated to the extension of Synology QoriIQ based NAS systems with (current version) open source third party applications like FFMPEG, libx264 etc.