Alasdair on Everything


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
    +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 < int ff_extern;
    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 '""'
    @@ -1896,7 +1896,7 @@
    check_cc < unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E';
    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

    -#ifndef NAN
    +#if !defined(NAN) || defined(__sun__)
    + #undef NAN
    #define NAN 0.0/0.0
    #endif

    — /root/ffmpeg-0.5/Makefile 2009-02-21 18:41:52.000000000 +0000
    +++ Makefile 2009-04-21 04:13:35.950911706 +0100
    @@ -130,20 +130,20 @@
    install: $(INSTALL_TARGETS-yes)

    install-progs: $(PROGS) $(INSTALL_PROGS_TARGETS-yes)
    - install -d “$(BINDIR)”
    - install -c -m 755 $(PROGS) “$(BINDIR)”
    + /opt/sfw/bin/install -d “$(BINDIR)”
    + /opt/sfw/bin/install -c -m 755 $(PROGS) “$(BINDIR)”

    install-data: $(DATA_FILES)
    - install -d “$(DATADIR)”
    - install -m 644 $(DATA_FILES) “$(DATADIR)”
    + /opt/sfw/bin/install -d “$(DATADIR)”
    + /opt/sfw/bin/install -m 644 $(DATA_FILES) “$(DATADIR)”

    install-man: $(MANPAGES)
    - install -d “$(MANDIR)/man1″
    - install -m 644 $(MANPAGES) “$(MANDIR)/man1″
    + /opt/sfw/bin/install -d “$(MANDIR)/man1″
    + /opt/sfw/bin/install -m 644 $(MANPAGES) “$(MANDIR)/man1″

    install-vhook: videohook
    - install -d “$(SHLIBDIR)/vhook”
    - install -m 755 $(HOOKS) “$(SHLIBDIR)/vhook”
    + /opt/sfw/bin/install -d “$(SHLIBDIR)/vhook”
    + /opt/sfw/bin/install -m 755 $(HOOKS) “$(SHLIBDIR)/vhook”

    uninstall: uninstall-progs uninstall-data uninstall-man uninstall-vhook

    — /root/ffmpeg-0.5/subdir.mak 2008-12-13 15:31:30.000000000 +0000
    +++ subdir.mak 2009-04-21 04:13:22.495144385 +0100
    @@ -38,8 +38,8 @@
    endif

    install-lib$(NAME)-shared: $(SUBDIR)$(SLIBNAME)
    - install -d “$(SHLIBDIR)”
    - install -m 755 $(SUBDIR)$(SLIBNAME) “$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)”
    + /opt/sfw/bin/install -d “$(SHLIBDIR)”
    + /opt/sfw/bin/install -m 755 $(SUBDIR)$(SLIBNAME) “$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)”
    $(STRIP) “$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)”
    cd “$(SHLIBDIR)” && \
    $(LN_S) $(SLIBNAME_WITH_VERSION) $(SLIBNAME_WITH_MAJOR)
    @@ -48,15 +48,15 @@
    $(SLIB_INSTALL_EXTRA_CMD)

    install-lib$(NAME)-static: $(SUBDIR)$(LIBNAME)
    - install -d “$(LIBDIR)”
    - install -m 644 $(SUBDIR)$(LIBNAME) “$(LIBDIR)”
    + /opt/sfw/bin/install -d “$(LIBDIR)”
    + /opt/sfw/bin/install -m 644 $(SUBDIR)$(LIBNAME) “$(LIBDIR)”
    $(LIB_INSTALL_EXTRA_CMD)

    install-headers::
    - install -d “$(INCINSTDIR)”
    - install -d “$(LIBDIR)/pkgconfig”
    - install -m 644 $(addprefix “$(SRC_DIR)”/,$(HEADERS)) “$(INCINSTDIR)”
    - install -m 644 $(BUILD_ROOT)/lib$(NAME)/lib$(NAME).pc “$(LIBDIR)/pkgconfig”
    + /opt/sfw/bin/install -d “$(INCINSTDIR)”
    + /opt/sfw/bin/install -d “$(LIBDIR)/pkgconfig”
    + /opt/sfw/bin/install -m 644 $(addprefix “$(SRC_DIR)”/,$(HEADERS)) “$(INCINSTDIR)”
    + /opt/sfw/bin/install -m 644 $(BUILD_ROOT)/lib$(NAME)/lib$(NAME).pc “$(LIBDIR)/pkgconfig”

    uninstall-libs::
    -rm -f “$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR)” \
    — version.sh.orig 2009-04-21 04:01:36.837398303 +0100
    +++ version.sh 2009-03-03 12:47:47.000000000 +0000
    @@ -1,4 +1,4 @@
    -#!/bin/sh
    +#!/bin/ksh

    revision=0.5

  • 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

Required

Required, hidden

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