This article introduces the compilation and use of ffmpeg in ANDROID/NDK environment, FFmpeg comes with H264, AAC, MP3 decoder, but there is no (or no good) corresponding encoder. The corresponding encoder requires the use of a third-party library. The recommended third party libraries is x264 (H264 encoding), FDK_AAC (AAC encoding), lame (MP3 encoding).
In order, the third-party library should be compiled first, and finally the FFmpeg library will be compiled.
This book explains: This article Shaofa, this article selected from "The FFmpeg Visual Audio Programming Guide". For more information on this book, please visit the official website: http://www.afanihao.cn "
"Rights statement: the author retains all rights in this article. The author authorizes anyone to be free to reprint this article, but when reproduced must abide by the following restrictions: ① reprint must be reproduced in full, no modification, including "rights statement" and "The book description" part of ② Limited to the network reprint, that is, the final results published on the network. Any non-compliance with the above two of the reprint act as a tort. Except as permitted by me, no person shall use this content for any other purpose. 】
Preparing for the 1.1 NDK environment
The demo example in this article uses the android-ndk-r8e version, but it is also theoretically applicable to the updated NDK version. To make your compilation process extremely smooth, you should make the following changes to the NDK:
Go to catalogue Platforms/android-14/arch-arm/usr/lib
You should see some files, such as CRTBEGIN_DYNAMIC.O, CRTBEGIN_STATIC.O crtend_so.o, CRTBEGIN_SO.O, CRTEND_ANDROID.O, and so on.
Copy all the files in this directory to
\toolchains\arm-linux-androideabi-4.6\prebuilt\linux-x86\lib\gcc\arm-linux-androideabi\4.6
Otherwise, the LD will prompt "crtbegin_so.o and crtend_so.o not found" in the link.
The relevant NDK tools should be added to the PATH environment variable, for example,
#!/bin/sh Export path= $PATH:/opt/ndk/android-ndk-r8e/ Export path= $PATH:/opt/ndk/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/ |
1.2 Compilation of FDK_AAC libraries
If you do not plan to use AAC-encoded features, you can skip this section. At present (March 2015), FDK_AAC's official release address is on the Source_forge, may change later, the author can search by himself. The current address is:
http://sourceforge.net/projects/opencore-amr/files/fdk-aac/
This article uses the version of fdk-aac-0.1.3, to reduce unnecessary hassle, readers also please download this package.
1.2.1 Modifying Configure Scripts
The goal of modifying the script is to remove the version number of the target library to accommodate the ANDROID/NDK loading requirements for the library. Simply put, this is because in the Java code of the ANDROID/NDK project, the dynamic library cannot add a version number when the so file is loaded with the system.loadlibrary () function.
In FDK_AAC's configure script, find the following line:
# This must is glibc/elf. Linux * | K*bsd*-gnu | Kopensolaris*-gnu | gnu*) Version_type=linux # Correct to Gnu/linux during the next big refactor Need_lib_prefix=no Need_version=no Library_names_spec= ' ${libname}${shared_ext} ${libname}${shared_ext} $libname ${shared_ext} ' soname_spec= ' ${libname}${shared_ext} ' finish_cmds= ' path= ' \ $PATH:/sbin "Ldconfig-n $libdir ' Shlibpath_var=ld_library_path Shlibpath_overrides_runpath=no |
Replace the bold part with the following:
Library_names_spec= ' $libname ${shared_ext} $libname. A ' |
1.2.2 New Configuration Script
A myconfig.sh script is suggested under the root directory of the source code. This is a shell script that asks the reader to understand a little bit about how some shell scripts are written. Just one thing to emphasize here: the shell script ends with \ n, and if you're editing under Windows, you should use Dos2unix to convert the text's newline character to UNIX format.
To avoid unnecessary hassles, unzip the NDK in the/opt/ndk/android-ndk-r8e directory and set the FDK output directory--prefix in the/opt/ndk/openlib directory. When the reader first time operation, do not modify the directory without authorization, you must be proficient after you modify the directory yourself.
The contents of myconfig.sh are as follows:
#!/bin/sh Export CC=ARM-LINUX-ANDROIDEABI-GCC Export cxx=arm-linux-androideabi-g++ Export Ar=arm-linux-androideabi-ar Export LD=ARM-LINUX-ANDROIDEABI-LD Export AS=ARM-LINUX-ANDROIDEABI-GCC Export cflags= "--sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm-march=armv7-a-MFLOAT-ABI=SOFTFP -mfpu=vfpv3-d16 " Export cxxflags= "--sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm-march=armv7-a-mfloat-abi= Softfp-mfpu=vfpv3-d16 " Export ldflags= "-l/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib-march=armv7-a-Wl,-- Fix-cortex-a8 " ./configure--enable-static--prefix=/opt/ndk/openlib--host=arm-linux |
1.2.3 Compiling
If you follow the steps above, the compilation process will be very simple. Open source software under Linux is generally divided into three-step compilation configure, Make,make install, and FDK_AAC is no exception.
1)./myconfig.sh
Execute the above configuration script to start the configuration
2) Make
3) make install
All normal, will be stored in the/opt/ndk/openlib output library and header files, note that this library is to remove the version number of the LIBFDK-AAC. Obviously, ANDROID/NDK programmers would prefer a library without a version number.
Compilation of 1.3 Lame-mp3
If you do not intend to use MP3 encoding in your project, skip this section.
This section describes the compilation of lame, but unfortunately, there is no way to remove the version number from its dynamic library. Therefore, the target dynamic library generated by this method is a version number.
1.3.1 New Configuration Script
Create a new configuration file myconfig.sh, as follows,
#!/bin/sh Export CC=ARM-LINUX-ANDROIDEABI-GCC Export cxx=arm-linux-androideabi-g++ Export Ar=arm-linux-androideabi-ar Export LD=ARM-LINUX-ANDROIDEABI-LD Export cflags= "--sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm" Export ldflags= "-l/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib" ./configure--enable-static--prefix=/opt/ndk/openlib--host=arm-linux |
1.3.2 Compiling
1)./myconfig.sh
Execute the above configuration script to start the configuration
2) Make
3) make install
All normal, the output library and the header file will be stored under/opt/ndk/openlib.
Compilation of 1.4 x264
x264 is part of VLC, the current source location is:
ftp://ftp.videolan.org/pub/videolan/x264/snapshots/
This article uses the source code version is x264-snapshot-20140723-2245-stable.tar.bz2
1.4.1 Modifying Configure Scripts
The purpose of this step is to make the output library file without a version number. If you insist that the version number does not affect your development, this section is ignored.
Find this location:
Else echo "Sosuffix=so" >> Config.mak echo "soname=libx264.so. $API" >> Config.mak echo "soflags=-shared-wl,-soname,\$ (soname) $SOFLAGS" >> Config.mak Fi |
Change Bold to: (That is, remove the $api suffix)
echo "soname=libx264.so" >> Config.mak |
1.4.2 New Configuration Script
Create a new myconfig.sh configuration script,
#!/bin/sh Export CC=ARM-LINUX-ANDROIDEABI-GCC Export cxx=arm-linux-androideabi-g++ Export Ar=arm-linux-androideabi-ar Export LD=ARM-LINUX-ANDROIDEABI-LD Export AS=ARM-LINUX-ANDROIDEABI-GCC Export cflags= "--sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm-march=armv7-a-MFLOAT-ABI=SOFTFP -mfpu=vfpv3-d16 " Export ldflags= "-l/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib-march=armv7-a-Wl,-- Fix-cortex-a8 " ./configure--enable-static--enable-shared--prefix=/opt/ndk/openlib--host=arm-linux |
1.4.3 Compiling
1)./myconfig.sh
Execute the above configuration script to start the configuration
2) Make
3) make install
Compilation of 1.5 FFmpeg
This example uses the FFmpeg2.1.3 version and can be downloaded from its official website ffmpeg.org. If you do not need x264/aac/lame, you can compile this section directly.
1.5.1 Modifying Configure Scripts
The purpose of this section is to have the output library contain no version number.
First find the following location for configure:
Shflags= '-shared-wl,-soname,$$ (@F) ' Libpref= "Lib" Libsuf= ". A" Fullname= ' $ (NAME) $ (Buildsuf) ' Libname= ' $ (libpref) $ (FULLNAME) $ (Libsuf) ' Slibpref= "Lib" Slibsuf= ". So" Slibname= ' $ (slibpref) $ (FULLNAME) $ (Slibsuf) ' Slibname_with_version= ' $ (slibname). $ (libversion) ' Slibname_with_major= ' $ (slibname). $ (libmajor) ' Lib_install_extra_cmd= ' $$ (ranlib) "$ (libdir)/$ (libname)" ' Slib_install_name= ' $ (slibname_with_version) ' Slib_install_links= ' $ (slibname_with_major) $ (slibname) ' |
Change the corresponding line to: (Bold section indicates the changed line)
Slibname_with_version= ' $ (slibname) ' Slibname_with_major= ' $ (slibname) ' Lib_install_extra_cmd= ' $$ (ranlib) "$ (libdir)/$ (libname)" ' Slib_install_name= ' $ (slibname_with_version) ' slib_install_links= |
1.5.2 Modifying configuration scripts
New myconfig.sh
Export NDK_ROOT=/OPT/NDK Export Tmpdir=/tmp ./configure--prefix= $NDK _root/ffmpeg--sysroot= $NDK _root/android-ndk-r8e/platforms/android-14/arch-arm-- cross-prefix=arm-linux-androideabi---target-os=linux--arch=arm--extra-cflags= "-i$ndk_root/openlib/include-fpic "--extra-ldflags=-l$ndk_root/openlib/lib--disable-programs--disable-doc--enable-shared--enable-cross-compile-- ENABLE-GPL--enable-nonfree--enable-libx264--enable-libmp3lame--ENABLE-LIBFDK-AAC |
This script is to x264, FDK-AAC, lame all compiled, you can view your own situation to modify.
1.5.3 compiling
1)./myconfig.sh
Execute the above configuration script to start the configuration
2) Make
3) make install
1.6 Referencing the FFmpeg library 1.6.1 using the static library in Android.mk
The use of static libraries is recommended. It is important to note that the static library reference order of the FFmpeg library cannot be written casually, and in order to avoid unnecessary hassles, please copy the following configuration.
Add the following lines to your ANDROID.MK (see boldface section)
Local_ldlibs + =-llog-lz # FFmpeg Ffmpeg=/opt/ndk Local_cflags + =-i$ (FFMPEG)/include Local_ldlibs + =-l$ (FFMPEG)/lib/libavformat.a Local_ldlibs + =-l$ (FFMPEG)/lib/libavcodec.a Local_ldlibs + =-l$ (FFMPEG)/lib/libavdevice.a Local_ldlibs + =-l$ (FFMPEG)/lib/libswresample.a Local_ldlibs + =-l$ (FFMPEG)/lib/libavdevice.a Local_ldlibs + =-l$ (FFMPEG)/lib/libswscale.a Local_ldlibs + =-l$ (FFMPEG)/lib/libpostproc.a Local_ldlibs + =-l$ (FFMPEG)/LIB/LIBAVUTIL.A
# FDK_AAC Local_ldlibs + =-L/OPT/NDK/LIB/LIBFDK-AAC.A Local_ldlibs + =-l/opt/ndk/lib/libmp3lame.a Local_ldlibs + =-l/opt/ndk/lib/libx264.a Include $ (build_shared_library) |
1.6.2 Using dynamic libraries
Using dynamic libraries is not recommended, and this process is too complex. Note that there are two points: ① compile, you must remove the library version number ② in Java code loading, pay attention to the order of loading.
The following can be added to the android.mk, but for reference only, encountered their own problems need to debug their own
# FFmpeg Ffmpeg=f:/ndk/ffmpeg Local_cflags + =-i$ (FFMPEG)/include Local_ldlibs + =-l$ (FFMPEG)/lib Local_ldlibs + =-lavformat-lavcodec-lswresample-lswscale-lavutil-lavfilter Include $ (build_shared_library) |
1.6.3 using FFmpeg in C + +
FFmpeg's library is compiled by C, and the symbols are in C format, so if you use it in C + +, use the extern "C" technique. For related syntax, refer to the C + + Grammar Guide (Shaofa, official website http://www.afanihao.cn).
For the convenience of everyone, under the/opt/ndk/ffmpeg/include a new ffmpeg.h, the content is:
#ifndef _ffmpeg_h # Define _ffmpeg_h #ifdef __cplusplus extern "C" { #define Int64_c (val) val# #LL #define Uint64_c (val) val# #ULL #endif #include <libavcodec /avcodec.h> #include <libavformat/avformat.h> #include <libswscale/swscale.h> # Include <libavutil/avutil.h> #include <libavutil/opt.h> #include <libavutil/imgutils.h #include <libswresample/swresample.h> #include <libavutil/error.h> #include <libavfilter/avfiltergraph.h> #include <libavfilter/avcodec.h> #include <libavfilter/buffersink.h> #include <libavfilter/buffersrc.h> #ifdef __cplusplus } #endif #endif |
You can then include "ffmpeg.h" directly in the C + + code.
Compilation of FFmpeg and aac,mp3,x264 under ANDROID/NDK environment