[FFmpeg-devel] FFmpeg for Mac

Neal Krawetz ffmpeg
Wed May 20 19:27:27 CEST 2009

Hi folks,

I managed to port FFMpeg to Macs as a Universal Binary (runs on both ppc
and x86 architectures).  There were a couple of changes that I needed
to make in order for this work.

I've tested this on the x86 architecture.  It compiles for a PPC, but I
have not tested it yet.  I suspect that it will fail because the ENDIAN
is hard-coded in config.h.

Anyway, here is my notes of things I needed to change for porting to the Mac:

* Install ffmpeg.
  Unforutnately, ffmpeg does not support universal binaries and configure
  does not set all of the configuration variables correctly.  So we will
  force it.
  Edit libavformat/framehook.c and comment out the header check:
        // #if HAVE_DLFCN_H
        #include <dlfcn.h>
        // #endif
  This header DOES exist when Xcode for MacOSX 10.5 is installed.
  Edit libavformat/rtpproto.c and comment out the header check:
        // #if HAVE_SYS_SELECT_H
        #include <sys/select.h>
        // #endif
  Edit ffserver.c and comment out the header check:
        // #if HAVE_DLFCN_H
        #include <dlfcn.h>
        // #endif
  Now compile:
    CFLAGS='-arch ppc -arch i386' ./configure --arch=x86
    CFLAGS='-arch ppc -arch i386' ./configure --arch=x86
    # Yes: Run configure twice! There is a permissions problem for config.h.
    sudo make install
  This will install into /usr/local/.

As far as the endian issue goes, have you considered using a global
variable that sets the endian?  This would simplify portability.
Here's what my code (Piana) does since I have this same issue:

#ifndef BIG_ENDIAN
#define BIG_ENDIAN      4321
#define LITTLE_ENDIAN   1234

/* Set a global that everyone else will use */
int     PianaEndianHost=BIG_ENDIAN;     /* big/Intel ; little/Motorola */

 PianaEndianSet(): Compute the endian for the host system.
 This must be called before running any of the other endian functions.
void    PianaEndianSet  ()
  byte Test[2] = {1,0};
  u_int16_t Num;
  Num = *(u_int16_t *)Test;
  if (Num == 1) PianaEndianHost=BIG_ENDIAN;
  else PianaEndianHost=LITTLE_ENDIAN;
} /* PianaEndianSet() */

Then all endian-specific code just needs to check this variable.
  if (JpegEndian == PianaEndianHost) ...
  else ...

When ffmpeg starts, the first thing it would do is set the endian flag.
The performance cost is a single if-condition.  (Three opcodes: load the
global, test the value, and jump on test.  And this could be reduced to
two opcodes if I used 0/1 instead of 1234/4321 like gcc defines.)

Using this test, the endian does not need to be hard-coded and ffmpeg can
be trivially cross-compiled without changing hard-coded header values that
were set by configure.

Neal Krawetz, Ph.D.
Hacker Factor Solutions
Author of "Introduction to Network Security" (Charles River Media, 2006)
and "Hacking Ubuntu" (Wiley, 2007)

More information about the ffmpeg-devel mailing list