Compiling x64/x86 FFmpeg on 64bit Windows with libfaac and libmp3lame

Once I had compiled FFmpeg for 32bit Windows, I discovered that it’s probably ten times more difficult to find information about doing the same with free tools on 64bit editions of Windows. A perfect topic for PCLOADLETTER then!

For building FFmpeg we must use the build environment MinGW-w64 which is a separate version of MinGW. The complication is that even when compiling natively you need to use configuration options as if you’re cross compiling (for host type x86_64-w64-mingw32). It’s not strictly necessary with all packages, but some will fail to build without these parameters. As a result you have to search around trying to find all the necessary configure commands for each package, and they’re not always identical. It’s a slow and frustrating process. What’s even more confusing, is that some builds of MinGW-w64 are targetted at 32bit, some 64bit, and some both. What is more, I had to try three different ones before I found one that could compile LAME without errors (though that could be LAME’s fault).

Most people will want a toolchain with the flexibility to create both x64 and x86 binaries, so that is what I shall describe in this guide.

On the MinGW-w64 downloads site browse to the Multilib Toolchains (Targetting Win32 and Win64) section, and download the latest megasoft78 binary build prefixed with mingw-w64-bin_x86_64-mingw. Extract the contents of this archive to the root of your C: drive (which at time of writing will create a folder named mingw64_4.5.2_multilib).

There is no installer – it’s not as automated as the 32bit distribution of MinGW. I spent a long time trying to compile LAME with the official MSYS build and eventually gave up, chosing instead to use a working one made by a third party. Download MSYS_MinGW_GCC_460_x86-x64_Full.7z from xhmikosr.1f0.de. Extract that archive into C:\mingw64_4.5.2_multilib so you have a subfolder in there named MSYS.

Update – I now realise that this archive also includes the whole GCC toolchain as well, but by then I’d already written the guide :)

Download the latest DirectX SDK. Install it, but only select the following component:
DirectX SDK installation options

This document provides useful background information to the uninitiated. Crucially it explains that when you compile with a particular host type defined, most configure scripts will look for a compiler whose filename is prefixed with that host type. So gcc.exe might be present in the toolchain distro as x86_64-w64-mingw32-gcc.exe. The toolchain I just recommended you download does not contain prefixes, but we shall need them since FFmpeg’s configure script expects them. On Windows Vista or later (which should cover most 64bit Windows systems) we can use mklink.exe to create symbolic links. We’ll also copy some missing DirectX headers into the toolchain and configure MSYS.

Start a Command Prompt as Administrator:

cd \mingw64_4.5.2_multilib\bin\
for %i in (*.exe) do mklink x86_64-w64-mingw32-%i %i
copy /y "%DXSDK_DIR%\Include\*.*" C:\mingw64_4.5.2_multilib\x86_64-w64-mingw32\include\
cd \mingw64_4.5.2_multilib\msys\postinstall
pi
 

This will launch the post-install script which will configure a filesystem mount for /mingw. When asked, enter your mingw installation path as c:/mingw64_4.5.2_multilib

Once that’s complete, launch the MSYS shell from your Administrator command prompt:

C:\mingw64_4.5.2_multilib\MSYS\msys.bat
 

Download the source .tar.gz files of:

Copy those downloaded files to C:\mingw64_4.5.2_multilib\msys\home\administrator (since you’re running in the Administrator user context). In the MSYS shell this is your home directory (cd ~).

In the MSYS shell, run:

tar xvfz faac-1.28.tar.gz
tar xvfz lame-3.98.4.tar.gz
tar xvfz ffmpeg-HEAD-6fd00e9.tar.gz
 

For a 64bit compile of FFmpeg with libfaac and libmp3lame:

cd ~/faac-1.28
./configure --prefix=/usr/local/x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --with-mp4v2=no
make clean && make
make install
cd ..
cd lame-3.98.4
./configure --prefix=/usr/local/x86_64-w64-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --disable-decoder --enable-nasm
make clean && make
make install
cd ..
cd ffmpeg-HEAD-6fd00e9
CPPFLAGS="$CPPFLAGS -I/usr/local/x86_64-w64-mingw32/include" ./configure --extra-ldflags='-L/usr/local/x86_64-w64-mingw32/lib' --prefix=/usr/local/x86_64-w64-mingw32 --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-memalign-hack --enable-libmp3lame --enable-nonfree --enable-libfaac --arch=x86_64 --enable-runtime-cpudetect --enable-w32threads --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32
make clean && make
make install
 

The compiled ffmpeg.exe will be in C:\mingw64_4.5.2_multilib\MSYS\local\x86_64-w64-mingw32\bin.

In summary what’s happening is we’re compiling FAAC without MP4v2 support (compilation halts if that’s enabled), and we’re making sure the binaries are stored in /usr/local/x86_64-w64-mingw32. Likewise for LAME. FFmpeg needs to be told where to find these new libraries (and headers too). We’re also installing it to /usr/local/x86_64-w64-mingw32, so as to keep x64 and x86 binaries separated.

 

For a 32bit compile of FFmpeg with libfaac and libmp3lame:

cd ~/faac-1.28
CFLAGS="-m32" CXXFLAGS="-m32" ./configure --prefix=/usr/local/i686-pc-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --with-mp4v2=no
make clean && make
make install
cd ..
cd lame-3.98.4
CFLAGS="-m32" CXXFLAGS="-m32" ./configure --prefix=/usr/local/i686-pc-mingw32 --host=x86_64-w64-mingw32 --enable-static --disable-shared --disable-decoder --enable-nasm
make clean && make
make install
cd ..
cd ffmpeg-HEAD-6fd00e9
CPPFLAGS="$CPPFLAGS -I/usr/local/i686-pc-mingw32/include" ./configure --extra-cflags=-m32 --extra-ldflags='-m32 -L/usr/local/i686-pc-mingw32/lib' --prefix=/usr/local/i686-pc-mingw32 --enable-static --disable-shared --disable-ffplay --disable-ffserver --enable-memalign-hack --enable-libmp3lame --enable-nonfree --enable-libfaac --arch=x86_32 --enable-runtime-cpudetect --enable-w32threads --cross-prefix=x86_64-w64-mingw32- --target-os=mingw32
make clean && make
make install
 

The compiled ffmpeg.exe will be in C:\mingw64_4.5.2_multilib\MSYS\local\i686-pc-mingw32\bin.

This is pretty much the same as before, but CFLAGS=”-m32″ and CXXFLAGS=”-m32″ force the 64bit-native C and C++ compilers to produce 32bit binaries. I found that useful option at the bottom of this FFmpeg wiki page. As usual, FFmpeg has its own way of specifying most of these settings (except CPPFLAGS). It is also instructed to use 32bit libraries via –extra-ldflags=’-m32′.

 

Footnote

Until I gave up and used the MSYS distro from xhmikosr.1f0.de, LAME persistently failed to compile with the error undefined reference to `init_xrpow_core_sse’. I tried a newer version of NASM than 2.09.08, replacing nasm.exe with yasm.exe, using LAME 3.98.2 instead of 3.98.4, disabling NASM in the configure, using the Unix makefile, all to no avail. Apart from a problem someone had compiling a Mac universal binary (fixed by using compiler options I could not use with MinGW), the only other link I could find about this is here, and that’s also unsolved. Even taking the nasm.exe (which I notice is 32bit) from the working MSYS bundle and trying it with the SourceForge ‘official’ MSYS bundle, I cannot get LAME to compile. I had no such problem when using the normal MinGW on my 32bit PC from my previous post on this subject, despite compiling my own nasm.exe. If you have any insight into why this might be, please leave a comment!

 
About these ads

11 thoughts on “Compiling x64/x86 FFmpeg on 64bit Windows with libfaac and libmp3lame

  1. Roger Hollamby

    I have followed all the steps listed above and succesfully built both 32 and 64 bit versions of ffmpeg and all the libraries on Windows 7 (64 bit).

    Both versions of ffmpeg works fine but I am having problems linking the libraries with a Visual Studio 2008 project following the instructions in ( http://www.ffmpeg.org/general.html ).

    When I try to link I get the following unresolved externals

    1>libavformat.a(utils.o) : error LNK2019: unresolved external symbol gettimeofday referenced in function av_gettime
    1>libavformat.a(file.o) : error LNK2019: unresolved external symbol __imp__fstat64 referenced in function file_seek
    1>libavformat.a(http.o) : error LNK2019: unresolved external symbol strtoll referenced in function http_read
    1>libavformat.a(tcp.o) : error LNK2019: unresolved external symbol gai_strerrorA referenced in function tcp_open
    1>libavformat.a(udp.o) : error LNK2001: unresolved external symbol gai_strerrorA
    1>libavutil.a(parseutils.o) : error LNK2019: unresolved external symbol __strtod referenced in function av_parse_color
    1>libavutil.a(eval.o) : error LNK2001: unresolved external symbol __strtod

    any ideas ?

    Reply
    1. patters Post author

      Glad you found the guide useful, but I can’t help you with Visual Studio I’m afraid. I know literally nothing about it as I’m not a developer! I took me a good long while to get MinGW figured out.

      Reply
  2. Pingback: Batch FFmpeg transcoding script « Fixing the annoying IT stuff

  3. nicolas

    Thanks a lot for the great Tutorial. One question:

    At the moment I am expierencing following problem, when executing this step (64bit): CPPFLAGS=”$CPPFLAGS -I/usr/local/x86_64-w64-mingw32/include” ./configure –extra-ldflags=’-L/usr/local/x86_64-w64-mingw32/lib’ –prefix=/usr/local/x86_64-w64-mingw32 –enable-static –disable-shared –disable-ffplay –disable-ffserver –enable-memalign-hack –enable-libmp3lame –enable-nonfree –enable-libfaac –arch=x86_64 –enable-runtime-cpudetect –enable-w32threads –cross-prefix=x86_64-w64-mingw32- –target-os=mingw32

    After that, following error message occurs: “ERROR: libfaac not found”

    All previous steps worked fine… Is it eventually I used a different ffmpeg.tar.gz? I used this one: http://www.ffmpeg.org/releases/ffmpeg-0.7-rc1.tar.gz

    (and that FAAC: http://downloads.sourceforge.net/faac/faac-1.28.tar.gz )

    Reply
  4. nicolas

    I found the error: a typo when configuring the faac-1.28 file (I have redone the step, now the file can be found in the correct folder)

    But a different problem occured (after the same command I posted above):
    In the first line after the command it says: “./configure: line 764: x86_64-w64-mingw32-pkg-config: command not found”

    After that, it goes on (enabled decoders etc.). Right now it is stucked since 2 hours at the line “Enabled protocols: applehttp”. It seems to be the case, that my PC is calculating, since the fan is running on a quite high level. Is that normal?

    My PC: MacBook Air with native running Windows 7 x64 (Bootcamp), Dual Core 1,6GHz, 4GB RAM

    Reply
  5. James

    Can you post a tutorial with libvpx and libvorbis also? I found these libraries difficult to compile on mingw.

    Reply
  6. starach

    I cannot compile it ffmpeg with libx264. The library compiles itself perfectly with apropriate configuration options ( used the same as for libfaac ) but ffmpeg configure script shows “ERROR: libx264 not found”.

    Reply
  7. larry

    if someone has a working 64 bit build with x264 and libfaac and pthread for windows please email me at kahn at lgk.com.. i would appreciate it thanks

    Reply
  8. sd

    I’ve followed your post, but 32bit enabled x86_64-w64-mingw32-gcc can’t be executed with -m32 CFLAGS. This means that above tool chain was not enabled as ‘multilib’.
    Could you really build 32bit ffmpeg with cross-prefix=x86_64-w64-mingw32- ?

    If so, how did you do that ?

    Reply
  9. Julia

    I also faced with the “undefined reference to `init_xrpow_core_sse’” error when compiled for x86_64. For Lame, I used “./configure –prefix= –build=x86_64-w64-mingw32 –host=x86_64-w64-mingw32 –enable-static –disable-shared –disable-decoder –disable-frontend”. After that, I removed “#define HAVE_XMMINTRIN_H 1″ from config.h (or maybe to somehow hide the header file can help, but I didn’t try this), then “make”, “make install”, copy lame/lame.h and libmp3lame.a to any place where compiler can find them. For FFmpeg, I used “./configure –prefix=build –arch=x86_64 –enable-shared –disable-static –disable-yasm –extra-libs=-static –enable-libmp3lame”.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s