Contents
Introduction
If you are familiar with a cool little thing named Raspberry Pi (a credit-card-sized single-board computer, shortly called RPi) and you need to compile your FFmpeg source code to be able to run it on Raspbian (a Debian Linux-based operating system optimized for the Raspberry Pi hardware), then this tutorial might help you.
Be aware, though, that Raspberry Pi does not have a very powerful hardware (it has a Broadcom System On a Chip (SoC), which includes 700 MHz ARM processor, with possible overclocking up-to 1 GHz, VideoCore
IV GPU and usually is shipped with 256/512 MB of RAM memory), so you probably won't be able to run any kind of encoder on it, but you can use it as a very cheap 1080 media player.
Compiling directly on RPi (running on Raspbian) is possible and some people do it that way, but since its hardware is very limited, this is not recommended for anything as big as FFmpeg (it took me 9 hours to compile the basic FFmpeg this way, without any additional libraries). Fortunately, there are other ways to compile things for RPi. One of them is emulating Raspberry Pi on your machine using QEMU (emulator). Another way (described in this document) is cross-compilation, which means that you compile everything on your desktop machine, using your own operating system, producing binaries for the Raspbian.
(TODO: The comparison table of different ways to compile FFmpeg for Raspbian)
Cross-compiling FFmpeg for Raspbian
We will describe here the method to cross-compile FFmpeg for Raspbian. First, we will prepare our build environment. Then we will show how to compile common additional libraries that FFmpeg might use (for example libx264). And finally we'll show how to compile the latest (and greatest) version of FFmpeg that will run on Raspbian.
Preparing the environment
To successfully cross-compile things, we need something called a Toolchain (a set of programming tools that are used to create another computer program). We need a toolchain that will be able to produce binaries, specific to the ARM architecture and the Raspbian itself. Now, there are a lot of already created toolchains for Raspbian and if you like to speed up things, you could just go find one of them and install it, but be aware that whatever toolchain you download, it might not be optimized for both your own operating system and Raspbian. If you compile your own toolchain, you can be sure that you'll be able to use all the available optimizations that your operating system and your Raspbian support.
The crosstool-ng is a tool used to create a custom toolchain. We'll use it to create our own toolchain which we can then use to compile anything we want for the Raspbian. So, let's prepare everything to first build our toolchain.
Building the crosstool-ng
The following section is mostly inspired by How to build a cross compiler for your Raspberry Pi.
First, download crosstool-ng, extract the archive and compile the source code. We recommend you to use something like this:
./configure --prefix=/opt/cross make sudo make install export PATH=$PATH:/opt/cross/bin
which will install all the crosstool-ng needed files into the "/opt/cross" directory and add it to the current PATH environment variable.
If something goes wrong, check your "build.log" file to get a clue on what went wrong. I've had some trouble because of some missing system packages, which I installed using:
apt-get install texinfo pkg-config
Although, the error complained about "makeinfo", it appears that, in Debian, this package is named "texinfo". Also consider installing texi2html package.
Building the toolchain
Now that we built crosstool-ng, we can build our RPi toolchain.
First, create a directory that crosstool-ng will use as a staging ground. This directory will contain your toolchain configuration, downloaded files and intermediary build results. This is not where your final toolchain will end up and it does take up quite a lot of space (for example /home/user/ctng). Go into that directory and run "ct-ng menuconfig":
mkdir /home/user/ctng cd /home/user/ctng ct-ng menuconfig
The menu should show up and you should set up things as instructed by the following walkthrough (checkboxes are selected using the SPACEBAR key and text fields can be edited pressing the ENTER/RETURN key on your keyboard, once you select it with your cursor keys):
- Paths and misc options
- (Important) Enable "Try features marked as EXPERIMENTAL"
- (Optional) Change "Prefix directory" (for example, you can put "/opt/cross/x-tools/${CT_TARGET}" there)
- Target options
- (Important) Change "Target architecture" to "arm"
- (Important) Leave "Endianness" set to "Little endian"
- (Important) Leave "Bitness" set to "32-bit"
- Toolchain options
- (Nothing to do here, the defaults are fine)
- Operating system
- (Important) Change "Target OS" to "linux"
- Binary utilities
- (Optional) Change "binutils version" to "2.21.1a" or whichever is the latest that isn't marked as experimental
- C compiler
- (Optional) Enable "Show Linaro versions (EXPERIMENTAL)". In the "gcc version" field, choose the "linaro-4.6-2012.04 (EXPERIMENTAL) compiler". You're free to choose a different one but this one works well. We do recommend the Linaro versions over the vanilla ones for the RPi
- (Optional) Enable "C++" under the group "
*** Additional supported languages: ***
" if you need g++ tool also built for your RPi toolchain
Now, exit the configuration tool, save your changes and run:
ct-ng build
This will take some time and when it finishes, you should have an ARM compiler, in the "Prefix directory" that you chose above - "/opt/cross/x-tools/${CT_TARGET}", ready to build anything for your RPi. One final step is to add that directory to your PATH:
export PATH=$PATH:/opt/cross/x-tools/arm-unknown-linux-gnueabi/bin
It also might help to export one more important environment variable CCPREFIX:
export CCPREFIX="/opt/cross/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-"
Quick test of the toolchain
Let's make a quick sanity check of our ARM compiler:
$ arm-unknown-linux-gnueabi-gcc --version arm-unknown-linux-gnueabi-gcc (crosstool-NG 1.15.2) 4.6.4 20120402 (prerelease) Copyright (C) 2011 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ cat > test.c #include <stdio.h> int main() { printf("Hello, world!\n"); return 0; } ^D $ arm-unknown-linux-gnueabi-gcc -o test test.c
Copy the "test" binary to your RPi and run it. It should display a familiar "Hello, world!" text.
Compiling additional libraries needed for FFmpeg
This section will describe how to compile some common libraries that are usually used by FFmpeg, like libx264 or libaacplus, etc.
Compiling libaacplus
cd /my/path/where/i/keep/my/source/code wget http://217.20.164.161/~tipok/aacplus/libaacplus-2.0.2.tar.gz tar -xzf libaacplus-2.0.2.tar.gz cd libaacplus-2.0.2 ./autogen.sh --with-parameter-expansion-string-replace-capable-shell=/bin/bash --host=arm-unknown-linux-gnueabi --enable-static --prefix=/my/path/were/i/keep/built/arm/stuff make make install
After you finish, all the libraries and binaries will be installed in "/my/path/were/i/keep/built/arm/stuff", so if you are compiling some libraries as dependencies for other things, you will most probably reference this directory later using:
cd /my/path/where/i/keep/my/source/code cd my_other_library CFLAGS="-I/my/path/were/i/keep/built/arm/stuff/include" LDFLAGS="-L/my/path/were/i/keep/built/arm/stuff/libs" ./configure ... --prefix=... make make install
That way you are telling the compiler where are the dependencies, that you also compiled for RPi, located, in order to successfully compile that "other library" too.
Compiling libx264
cd /my/path/where/i/keep/my/source/code git clone git://git.videolan.org/x264 cd x264 ./configure --host=arm-unknown-linux-gnueabi --enable-static --cross-prefix=${CCPREFIX} --prefix=/my/path/were/i/keep/built/arm/stuff --extra-cflags='-march=armv6' --extra-ldflags='-march=armv6' make make install
Note that we use CCPREFIX environment variable here, to specify the prefix of all the tools in a toolchain, to be used for this build (it instructs the shell not to call cc, gcc, g++ and other standard tools, but rather to call /opt/cross/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-cc, /opt/cross/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-gcc, /opt/cross/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi-g++, etc that will build ARM binaries and libraries).
Compiling ALSA library
cd /my/path/where/i/keep/my/source/code wget http://mirrors.zerg.biz/alsa/lib/alsa-lib-1.0.25.tar.bz2 tar xjf alsa-lib-1.0.25.tar.bz2 cd alsa-lib-1.0.25/ ./configure --host=arm-unknown-linux-gnueabi --prefix=/my/path/were/i/keep/built/arm/stuff make make install
Compiling FFmpeg
This part is the same for all the subsequent examples:
cd /my/path/where/i/keep/my/source/code git clone git://source.ffmpeg.org/ffmpeg.git cd ffmpeg
Basic FFmpeg, without additional libraries
./configure --enable-cross-compile --cross-prefix=${CCPREFIX} --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff make make install
FFmpeg with libaacplus, libx264 and alsa-lib
./configure --enable-cross-compile --cross-prefix=${CCPREFIX} --arch=armel --target-os=linux --prefix=/my/path/were/i/keep/built/arm/stuff --enable-gpl --enable-libx264 --enable-nonfree --enable-libaacplus --extra-cflags="-I/my/path/were/i/keep/built/arm/stuff/include" --extra-ldflags="-L/my/path/were/i/keep/built/arm/stuff/lib" --extra-libs=-ldl make make install
Also, if some libraries are dependent on pkg-config
, you'll most probably be able to solve it using PKG_CONFIG_PATH environment variable, like this:
pkg_config=$(which pkg-config) PKG_CONFIG_PATH=/my/path/were/i/keep/built/arm/stuff/lib/pkgconfig ./configure ...
more
Conclusion
After you've built your FFmpeg for RPi, copy ffmpeg
, ffplay
and ffserver
binaries from "/my/path/were/i/keep/built/arm/stuff/bin/" to your Raspberry Pi and try it to see how it works :)
One important note, that might save you days of headaches is that RPi is a very optimized hardware, which consumes very little power and also provides very little power to its USB ports, so if you plan to attach any external USB disks, cameras, wireless/audio/etc USB dongles, then keep in mind to connect all of these USB peripherals through a self-powered USB hub, which can provide enough power for devices to work properly, so your RPi won't be rebooting itself, due to sudden dramatic voltage fluctuations.
Good luck with all that.
Attachments (1)
- Raspberry_Pi_600x400.jpg (48.3 KB ) - added by 12 years ago.
Download all attachments as: .zip