Archive for May, 2009

64bit Varnish on Solaris

When running a 64bit varnish on Solaris, you may encounter an error similar to:

# /opt/ec/sbin/amd64/varnishd -d
Compiled VCL program failed to load:
  ld.so.1: varnishd: fatal: ./vcl.ORk8t3RP.so: wrong ELF class: ELFCLASS32
VCL compilation failed

The problem is fairly self explanatory, your 64bit Varnish is failing to pass -m64 to the compiler when it compiles up the VCL program. The fix is very straight forward, simply pass:

# /opt/ec/sbin/amd64/varnishd -d -p cc_command='cc -Kpic -G -m64 -o %o %s'
storage_file: filename: ./varnish.NxaavR (unlinked) size 26135 MB.
Creating new SHMFILE
New Pid 22203

Debugging mode, enter "start" to start child

Et voilĂ , fixed. Enjoy!

Add comment May 31st, 2009

Text relocation remains against symbol, libx264

Note (2013-02-14): Please see the comments for useful suggestions – what I’ve written below isn’t a proper fix.


Just a very quick post regarding libx264.

If you are getting errors such as:

# gcc -shared -o libx264.so.67 common/mc.o common/predict.o common/pixel.o common/macroblock.o common/frame.o common/dct.o common/cpu.o common/cabac.o common/common.o common/mdate.o common/set.o common/quant.o common/vlc.o encoder/analyse.o encoder/me.o encoder/ratecontrol.o encoder/set.o encoder/macroblock.o encoder/cabac.o encoder/cavlc.o encoder/encoder.o extras/getopt.o  -Wl,-h,libx264.so.67 -lm -lpthread -s
Text relocation remains                         referenced
    against symbol                  offset      in file
                           0x6be       common/mc.o
                           0x6d5       common/mc.o
                           0xbbe       common/mc.o
                           0xbc5       common/mc.o
...
__udivdi3                           0x3809      common/set.o
__udivdi3                           0x3875      common/set.o
__udivdi3                           0x10cf      encoder/macroblock.o
__divdi3                            0x17865     encoder/analyse.o
__divdi3                            0x1e9       encoder/set.o
ld: fatal: relocations remain against allocatable but non-writable sections
collect2: ld returned 1 exit status

then simply add “-mimpure-text -lrt” to your LDFLAGS.

A quick note to self, “gcc -shared” is better than “gcc -G”. The former tells gcc to build a shared object, which tells the linker (I suppose). The latter just tells the linker. Swapping a -shared for -G can fix the above issue, but creates other issues. Or something along those lines – I’m a bit hazy on this one.

This issue came about because I was getting errors when running a 64bit amd64 ffmpeg linked against libx264:

ld.so.1: ffmpeg: fatal: relocation error: R_AMD64_PC32: file /opt/ec/lib/amd64/libx264.so.67: symbol main: value 0x280018fc805 does not fit

The problem here was that I’d compiled libx264 with gcc -G instead of gcc -shared. However using -shared generated the “Text relocation remains against symbol” errors, which needed the “-mimpure-text -lrt” fix.

5 comments May 19th, 2009

FFMpeg 64bit x86_64 / amd64 on Solaris 10

I wanted to post this before I move onto my next problem, so excuse the brevity. When compiling ffmpeg on Solaris 10 for 64bit, you may encounter this particular block of errors, which come out of the assembly found inside libavcodec/cabac.h:

/var/tmp//ccC7vvHU.s:8035: Error: `-1(%ebx)' is not a valid 64 bit base/index expression
/var/tmp//ccC7vvHU.s:8038: Error: `ff_h264_norm_shift(%ecx)' is not a valid 64 bit base/index expression
/var/tmp//ccC7vvHU.s:8060: Error: `ff_h264_lps_range(%eax,%esi,2)' is not a valid 64 bit base/index expression
/var/tmp//ccC7vvHU.s:8070: Error: `ff_h264_norm_shift(%esi)' is not a valid 64 bit base/index expression
/var/tmp//ccC7vvHU.s:8072: Error: `ff_h264_mlps_state+128(%eax)' is not a valid 64 bit base/index expression
/var/tmp//ccC7vvHU.s:8084: Error: `-1(%ebx)' is not a valid 64 bit base/index expression
/var/tmp//ccC7vvHU.s:8087: Error: `ff_h264_norm_shift(%ecx)' is not a valid 64 bit base/index expression
/var/tmp//ccC7vvHU.s:8107: Error: `ff_h264_lps_range(%eax,%esi,2)' is not a valid 64 bit base/index expression
/var/tmp//ccC7vvHU.s:8117: Error: `ff_h264_norm_shift(%esi)' is not a valid 64 bit base/index expression
...
/var/tmp//ccC7vvHU.s:32827: Error: `ff_h264_norm_shift(%esi)' is not a valid 64 bit base/index expression

The issue is that FFMpeg has failed to detect "BROKEN_RELOCATIONS". Simply set this in your config.h like so:

export CFLAGS=-m64
export LDFLAGS=-m64
./configure --prefix=/tmp/ffmpeg --arch=x86_64 --cpu=nocona --disable-encoder=nellymoser
echo '#define BROKEN_RELOCATIONS 1' >> config.h
gmake-3.81

I’ve missed a lot of detail out here, such as all the patches we use to get ffmpeg building on Solaris, but I’ll hopefully find more time tomorrow to post a blog entry about it.

Some interesting tidbits of information: FFMpeg with –enable-shared is 3 times slower, so I wouldn’t advise enabling this flag unless you absolutely need it. And the 64bit ffmpeg binary is twice as fast at transcoding wmv to flv over a 32bit one (in the basic not-very-fancy test I used). So it is worth investing time in compiling up a 64bit version.

Here’s a performance comparison going from a 32bit ffmpeg with –enable-shared and –disable-mmx on gcc 3.4, to a 64bit ffmpeg with –disable-shared and –enable-mmx on gcc 4.4:

# time /opt/ec/bin/ffmpeg -y -i ~/test2.wmv ~/test2.flv
FFmpeg version 0.5, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  configuration: --prefix=/opt/ec --enable-shared --enable-nonfree --enable-gpl --enable-libamr-nb --enable-libamr-wb --enable-libdirac --enable-libfaac --enable-libfaad --enable-libmp3lame --enable-libopenjpeg --enable-libschroedinger --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --disable-encoder=nellymoser --disable-mmx --enable-avfilter --disable-debug --enable-swscale --enable-postproc --enable-pthreads
  libavutil     49.15. 0 / 49.15. 0
  libavcodec    52.20. 0 / 52.20. 0
  libavformat   52.31. 0 / 52.31. 0
  libavdevice   52. 1. 0 / 52. 1. 0
  libavfilter    0. 4. 0 /  0. 4. 0
  libswscale     0. 7. 1 /  0. 7. 1
  libpostproc   51. 2. 0 / 51. 2. 0
  built on May  1 2009 14:25:24, gcc: 3.4.3 (csl-sol210-3_4-branch+sol_rpath)

Seems stream 1 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 25.00 (25/1)
Input #0, asf, from '/export/home/alasdair/test2.wmv':
  Duration: 00:11:04.65, start: 3.000000, bitrate: 172 kb/s
    Stream #0.0: Audio: wmav2, 44100 Hz, mono, s16, 32 kb/s
    Stream #0.1: Video: wmv1, yuv420p, 320x240, 180 kb/s, 25 tbr, 1k tbn, 1k tbc
Output #0, flv, to '/export/home/alasdair/test2.flv':
    Stream #0.0: Video: flv, yuv420p, 320x240, q=2-31, 200 kb/s, 90k tbn, 25 tbc
    Stream #0.1: Audio: libmp3lame, 44100 Hz, mono, s16, 64 kb/s
Stream mapping:
  Stream #0.1 -> #0.0
  Stream #0.0 -> #0.1
Press [q] to stop encoding
frame=16637 fps=263 q=12.6 Lsize=   22485kB time=665.48 bitrate= 276.8kbits/s
video:16626kB audio:5200kB global headers:0kB muxing overhead 3.016455%

real    1m3.285s
user    1m0.043s
sys     0m0.471s
# time ./ffmpeg-64 -y -i ~/test2.wmv ~/test2.flv
FFmpeg version 0.5, Copyright (c) 2000-2009 Fabrice Bellard, et al.
  configuration: --prefix=/tmp/ffmpeg --arch=x86_64 --cpu=nocona --disable-encoder=nellymoser
  libavutil     49.15. 0 / 49.15. 0
  libavcodec    52.20. 0 / 52.20. 0
  libavformat   52.31. 0 / 52.31. 0
  libavdevice   52. 1. 0 / 52. 1. 0
  built on May  3 2009 04:42:52, gcc: 4.4.0

Seems stream 1 codec frame rate differs from container frame rate: 1000.00 (1000/1) -> 25.00 (25/1)
Input #0, asf, from '/export/home/alasdair/test2.wmv':
  Duration: 00:11:04.65, start: 3.000000, bitrate: 172 kb/s
    Stream #0.0: Audio: wmav2, 44100 Hz, mono, s16, 32 kb/s
    Stream #0.1: Video: wmv1, yuv420p, 320x240, 180 kb/s, 25 tbr, 1k tbn, 1k tbc
Output #0, flv, to '/export/home/alasdair/test2.flv':
    Stream #0.0: Video: flv, yuv420p, 320x240, q=2-31, 200 kb/s, 90k tbn, 25 tbc
    Stream #0.1: Audio: adpcm_swf, 44100 Hz, mono, s16, 64 kb/s
Stream mapping:
  Stream #0.1 -> #0.0
  Stream #0.0 -> #0.1
Press [q] to stop encoding
frame=16637 fps=1799 q=12.0 Lsize=   31483kB time=665.48 bitrate= 387.6kbits/s
video:16624kB audio:14375kB global headers:0kB muxing overhead 1.561981%

real    0m9.356s
user    0m8.937s
sys     0m0.291s

The encode time has gone from 63 seconds to just 9 seconds! That’s a *huge* speed up. I’m rather impressed.

I’m also guessing that compiling all the ffmpeg dependencies as shared object .so files will have the same slowdown as ffmpeg with –enable-shared, so I’m going to try building all the dependencies as static libraries instead.

It’s now approaching 5am so I should really go off to bed, but I’m glad I finally got this knocked on the head.

4 comments May 3rd, 2009