[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.
make
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
#endif
#ifndef LITTLE_ENDIAN
#define LITTLE_ENDIAN 1234
#endif
/* 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
--
Neal Krawetz, Ph.D.
Hacker Factor Solutions
http://www.hackerfactor.com/
Author of "Introduction to Network Security" (Charles River Media, 2006)
and "Hacking Ubuntu" (Wiley, 2007)
More information about the ffmpeg-devel
mailing list