Bohl's Blog

my digital life

building ffmpeg on Windows (3 of n)

In this post we will build FFmpeg with the Intel-compiler ICL - with the usual configure-/make-scripts. First of all we need a Cygwin-shell with the Intel-compiler on the path. It is easiest to call the batch-file "ipsxe-comp-vars.bat" which is installed with the Intel-compiler. So we put together a simple batch-file something like this:

@echo off
call C:\Progra~2\Intel\Compos~1\bin\ipsxe-comp-vars.bat ia32 vs2012
chdir /D d:\cygwin\bin
start .\mintty.exe -

Of course you have to substitute your respective paths. Now, when you launch the Cygwin-shell it should look like this:

Let me say beforehand: I tested the following steps with the FFmpeg-sources as of 06/02/2013. The corresponding git-commit-ID is 582f36ca3fb1c69dbe3478f174d36278f5dd3f63. So, if something goes wrong it might because of changes in the FFmpeg-repository. In order to be sure that you get this specific version you need to run this command after downloading the most recent FFmpeg-repository:

git checkout 582f36ca3fb1c69dbe3478f174d36278f5dd3f63

Now, first of all, we need to get the FFmpeg-sources:

git clone git:// ffmpeg

Now download the two patches below:

cygicl.diff (31.31 kb) 

inlineassembly.diff (60.75 kb)

The first patch modifies the configure - script, adds some files and applies minimal modifications so that FFmpeg compiles without inline-assembly. The second patch contains more extensive changes to the FFmpeg-code in order to make the inline-assembly work with icl.

I will elaborate on the changes in a latter post, in this post I will just list the steps how to make it compile. Change into the ffmpeg-folder and apply both patches:

patch -p1 < ../cygicl.diff
patch -p1 < ../inlineassembly.diff

Now we still need two more scripts - the first one is a little wrapper for the icl-compiler, and the second is required for executing the FATE-test-suite successfully. (1.53 kb) (1.30 kb)

Place them to somewhere on the (Cygwin-) path - e.g. /usr/local/bin.

We can now run the configure-script:

./configure --enable-inline-asm --disable-doc --toolchain=cygicl --host-cc=gcc

If you chose to not apply the inlineassembly.diff-patch, then you need to specify --disable-inline-asm. This will take a while and should finish without any errors.

Then we are ready to fire up make - which can be speeded up by allowing it to run multiple compiler-processes concurrently. Something like this might be a good choice:

make -j "$(grep -c processor /proc/cpuinfo)"

Again, this should finish without errors.

Finally, we can run FATE with this command:

make fate SAMPLES=PATH_TO_FATE_SUITE_SAMPLES  -j "$(grep -c processor /proc/cpuinfo)"

Don't forget to give the correct path (where you have place the fate-samples) instead of PATH_TO_FATE_SUITE_SAMPLES.

At least for me (with the latest icl, version build 20130514) all fate-tests pass.

Comments (3) -

  • Axel

    6/10/2013 5:51:16 PM | Reply

    Hi Jürgen,

    I every now and then I read your blog articles on ffmpeg on windows. Thanks a lot for all the effort you take and for sharing your experiences with us.

    As you are, I'm interested in compiling ffmpeg on windows and thanks to the C99wrap tool originally from libav, it's possible to do this nearly out of the box without patches.

    But there's one exception: this only works if optimization is active. Why? Because ffmpeg relies on dead code elimination.


    If the configure #define HAVE_MMX is zero, MMX isn't available and thus no MMX functions are available. With active dead code elimination this compiles fine. Without already either the compiler whines, but certainly the linker as it won't find the function.

    But why is this an issue? Well the MSVC compiler doesn't have very fine grained optimizer levels. If you disable optimization also dead code elimination is gone.

    So in the end we have a MSVC compiled version of ffmpeg but we still have optimized code so that debugging (and that was the initial reason to compile with MSVC or ICL to get the PDBs) is again fairly inconvenient without all the optimized away local variables, etc.

    A while ago I tried to convince the ffmpeg developers to support generic macros instead of runtime if (inspired by boost preprocessor) so that in the end the not existing calls would already be ifdefed out by the preprocessor, but all I got was a nice flame war Wink

    So how about you? How do you deal with the dead code elimination?


  • Juergen

    6/10/2013 10:57:21 PM | Reply

    Hi Alex,

    the problem you have brought up is a long-running issue and a nasty one. I have seen it discussed several times on the ffmpeg-mailing-lists - once raised by you it seems, once by me and by many more.
    Well, the approach I took is simple and pragmatic (i.e. fishy suppose...) - I take all the "unresolved externals" and create a source-file which "defines" those symbols. For example, a simple line

    int ff_sbrdsp_init_arm;

    will do the trick. And since we are using C (and not C++) no fancy name-mangling gets in our way. If you look into the patch-file "cygicl.diff" you will find this file: fakestubs.c.
    Another option might be - the Microsoft-linker has an option which forces it to ignore "unresolved externals" - cf. . So, the option "/FORCE:UNRESOLVED" should also work.  I am not sure, iirc this turned out to be not really useful (or causing other problems) - but I do not remember why I dismissed this approach.

    Hope this helps and thanks for the encouraging comments!

  • Axel

    6/11/2013 2:18:36 PM | Reply

    Hi Jürgen,

    a big AAAHHH, I see. I read the patch and saw the definitions, but my mind was too dull to get it right. Now it's clear.

    And thanks for the FORCE switch, which is really interesting. I'm gonna try it.

    All the best