FFMpeg 64bit x86_64 / amd64 on Solaris 10
May 3rd, 2009
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.
Entry Filed under: General

4 Comments Add your own
1. syngen | May 18th, 2009 at 6:07 am
Hi. Can you share some of the patches, steps you took to make ffmpeg compile on Solaris 10?
I’m kinda stuck. Can’t seem to get it to work.
Any assist will be extremely appreciated.
Cheers!
2. Alasdair | May 18th, 2009 at 12:20 pm
(Also sent via email)
I can certainly help, but my build environment is probably quite different from the one you’re using. For example, I spent a weekend compiling up gcc 4.4.0, the latest GNU Binutils (for the GNU Assembler “as”), Yasm (assembler), along with compiling up all the dependencies (x264, faac, faad2, etc).
I’ve attached the patches I use (sent via email). Here is the big configure line I use to build it:
./configure –prefix=/opt/ec –disable-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 –enable-avfilter –disable-debug –enable-swscale –enable-postproc –enable-pthreads –enable-mmx –enable-mmx2 –enable-sse –enable-ssse3 –enable-yasm
However I’d recommend starting off just compiling the base ffmpeg build with no dependencies, so:
export CC=gcc
export CXX=g++
export LDFLAGS=”-L/opt/sfw/lib -R/opt/sfw/lib -L/usr/sfw/lib -R/usr/sfw/lib -L/usr/lib -R/usr/lib”
export CPPFLAGS=”-I/usr/sfw/include -I/opt/sfw/include”
export CFLAGS=$CPPFLAGS
export PATH=/usr/ucb/bin:/usr/sfw/bin:/opt/sfw/bin:$PATH
./configure –prefix=/opt/ec –disable-shared –enable-nonfree –enable-gpl –disable-encoder=nellymoser –disable-debug –enable-swscale –enable-postproc –enable-pthreads –disable-mmx –disable-mmx2 –disable-sse –disable-ssse3 –disable-yasm
The most important options there are “–disable-encoder=nellymoser” and “–disable-mmx”. The nellymosser encoder won’t compile on Solaris 10 (at least not with gcc 3.4)
I’ve attached the patches we use. You’ll need to apply them with gpatch from SFWdiffu (on the Solaris 10 companion CD), and SFWcoreu is needed for the GNU install program.
The avcodec.h and eval.c patches get around an issue with the NAN definition in the Solaris c library/maths includes/something like that.
The configure patch replaces grep with ggrep, and also changes the linker flags from the GNU ld options to Sun ld options. (Eg “-Wl,-soname” gets replaced with “-Wl,-h” and “-shared” gets replaced with “-G”)
The Makefile and subdir.mak patches replace the “install” command with /opt/sfw/bin/install which supports funkier options.
If you get stuck, give me the full details and I’ll try and help.
Cheers,
Alasdair
Patches:
— ../ffmpeg-0.5/libavcodec/avcodec.h 2009-02-26 23:47:32.000000000 +0000
+++ libavcodec/avcodec.h 2009-04-21 03:57:11.489912835 +0100
@@ -3332,6 +3332,11 @@
#define AVERROR_EOF AVERROR(EPIPE) /**< End of file. */
#define AVERROR_PATCHWELCOME -MKTAG('P','A','W','E') /**< Not yet implemented in FFmpeg. Patches welcome. */
+#ifdef __sun__
+#undef isnan
+#define isnan(x) __extension__( { __typeof(x) __x_n = (x); __builtin_isunordered(__x_n, __x_n); })
+#endif
+
/**
* Registers the hardware accelerator \p hwaccel.
*/
--- configure.orig 2009-04-20 17:39:56.149935094 +0100
+++ configure 2009-04-20 17:40:04.056794980 +0100
@@ -1217,7 +1217,7 @@
disable source_path_used
else
source_path="`cd \"$source_path\"; pwd`"
- echo "$source_path" | grep -q '[[:blank:]]' &&
+ echo "$source_path" | ggrep -q '[[:blank:]]' &&
die "Out of tree builds are impossible with whitespace in source path."
fi
@@ -1363,13 +1363,13 @@
fi
rm $TMPSH
-if $cc --version 2>/dev/null | grep -qi gcc; then
int ff_extern;
+if $cc –version 2>/dev/null | ggrep -qi gcc; then
cc_type=gcc
-elif $cc –version 2>/dev/null | grep -q Intel; then
+elif $cc –version 2>/dev/null | ggrep -q Intel; then
cc_type=icc
-elif $cc -v 2>&1 | grep -q xlc; then
+elif $cc -v 2>&1 | ggrep -q xlc; then
cc_type=xlc
-elif $cc -V 2>/dev/null | grep -q Compaq; then
+elif $cc -V 2>/dev/null | ggrep -q Compaq; then
cc_type=ccc
DEPEND_CMD=’$(CC) $(CFLAGS) -M $< | sed -e "/^\#.*/d" -e "s,^[[:space:]]*$(*F)\\.o,$(@D)/$(*F).o,"'
add_ldflags -Wl,-z,now # calls to libots crash without this
@@ -1488,7 +1488,7 @@
# helps building libavcodec
add_cflags -DPIC -fomit-frame-pointer
# 3 gcc releases known for BeOS, each with ugly bugs
- gcc_version="`$cc -v 2>&1 | grep version | cut -d ‘ ‘ -f3-`”
+ gcc_version=”`$cc -v 2>&1 | ggrep version | cut -d ‘ ‘ -f3-`”
case “$gcc_version” in
2.9-beos-991026*|2.9-beos-000224*) echo “R5/GG gcc”
disable mmx
@@ -1503,7 +1503,7 @@
# no need for libm, but the inet stuff
# Check for BONE
# XXX: actually should check for NOT net_server
- if echo $BEINCLUDES | grep -q ‘headers/be/bone’; then
+ if echo $BEINCLUDES | ggrep -q ‘headers/be/bone’; then
network_extralibs=”-lbind -lsocket”
else
enable beos_netserver
@@ -1798,7 +1798,7 @@
check_cc <
EOF
-sym=$($nm -P -g $TMPO | grep ff_extern)
+sym=$($nm -P -g $TMPO | ggrep ff_extern)
extern_prefix=${sym%%ff_extern*}
check_asm inline_asm '""'
unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E';
@@ -1896,7 +1896,7 @@
check_cc <
EOF
-od -A n -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian
+od -A n -t x1 $TMPO | ggrep -q '42 *49 *47 *45' && enable bigendian
# ---
# check availability of some header files
@@ -2413,7 +2413,7 @@
get_version(){
name=$1
file=$source_path/$2
- eval $(grep "#define ${name}_VERSION_M" "$file" | awk '{ print $2"="$3 }')
+ eval $(ggrep "#define ${name}_VERSION_M" "$file" | awk '{ print $2"="$3 }')
eval ${name}_VERSION=\$${name}_VERSION_MAJOR.\$${name}_VERSION_MINOR.\$${name}_VERSION_MICRO
lcname=$(tolower $name)
eval echo "${lcname}_VERSION=\$${name}_VERSION" >> config.mak
— configure.orig 2009-04-30 11:46:11.291955480 +0100
+++ configure 2009-04-30 19:15:18.249680048 +0100
@@ -1186,7 +1186,7 @@
# build settings
add_cflags -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112
-SHFLAGS=’-shared -Wl,-soname,$$(@F)’
+SHFLAGS=’-G -Wl,-h,$$(@F)’
VHOOKSHFLAGS=’$(SHFLAGS)’
FFSERVERLDFLAGS=-Wl,-E
LIBPREF=”lib”
@@ -1511,7 +1511,7 @@
fi ;;
sunos)
FFSERVERLDFLAGS=”"
- SHFLAGS=’-shared -Wl,-h,$$(@F)’
+ SHFLAGS=’-G -Wl,-h,$$(@F)’
network_extralibs=”-lsocket -lnsl”
add_cflags -D__EXTENSIONS__
;;
— libavcodec/eval.c.orig 2009-04-21 03:01:49.851148671 +0100
+++ libavcodec/eval.c 2009-04-21 03:02:20.718605667 +0100
@@ -36,7 +36,8 @@
#include
#include
3. cy | June 15th, 2009 at 4:02 pm
Hi Alasdair,
I was trying to compile ffmpeg on Solaris 10 but hit the error below. I only need it to generate thumbnails out of 3gp and mp4 files.
I used gnu gcc 3.4.6 and make 3.8.1.
Any advice is greatly appreciated. Thanks.
gcc -DHAVE_AV_CONFIG_H -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -I. -I”/export/home/mbit/tmp/ffmpeg-0.5″ -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -fPIC -std=c99 -D__EXTENSIONS__ -fomit-frame-pointer -g -Wdeclaration-after-statement -Wall -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wcast-qual -Wwrite-strings -Wundef -O3 -fno-math-errno -c -o libavdevice/alldevices.o libavdevice/alldevices.c
libavdevice/alldevices.c: In function `avdevice_register_all’:
libavdevice/alldevices.c:47: error: `CONFIG_ALSA_MUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:47: error: (Each undeclared identifier is reported only once
libavdevice/alldevices.c:47: error: for each function it appears in.)
libavdevice/alldevices.c:47: error: `CONFIG_ALSA_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:48: error: `CONFIG_AUDIO_BEOS_MUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:48: error: `CONFIG_AUDIO_BEOS_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:49: error: `CONFIG_BKTR_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:50: error: `CONFIG_DV1394_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:51: error: `CONFIG_OSS_MUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:51: error: `CONFIG_OSS_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:52: error: `CONFIG_V4L2_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:53: error: `CONFIG_V4L_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:54: error: `CONFIG_VFWCAP_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:55: error: `CONFIG_X11_GRAB_DEVICE_DEMUXER’ undeclared (first use in this function)
libavdevice/alldevices.c:58: error: `CONFIG_LIBDC1394_DEMUXER’ undeclared (first use in this function)
make: *** [libavdevice/alldevices.o] Error 1
4. Alasdair | June 19th, 2009 at 12:23 pm
Hi Cy,
Hmm, if it’s complaining about things not being declared, sounds like you might have a duff copy of ffmpeg out the source tree.
Could you report back the version of ffmpeg you’re compiling, your ./configure line, output from “env” utility and full operating system version, and I’ll try and offer more advice.
Cheers,
Alasdair
Leave a Comment
Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>
Trackback this post | Subscribe to the comments via RSS Feed