FFmpeg:Android
lastmod 2024-05-24created 2016-11-0812 edits
Explains how to use FFmpeg on Android.
About the FFmpeg license
- When using AndEngine, which uses the LGPL license, and building a game with the library in jar form, what are the disclosure obligations?
- I don't know how games are developed, but on a project for a large company a while ago, we put a readme file containing the copyright in the same folder as the library, built it into an apk, and uploaded it. I was told that if a problem came up, in my case I'd only need to disclose the jni interface source, so it wouldn't matter. Then again, I've heard that they usually don't go after you unless you're a fairly big company.
- As far as I know it's weaker than the GPL, but if you search around, keeping the source closed isn't easy... I remember that we avoided using anything GPL or LGPL whenever possible. Of course, if you're fine with disclosing your source in keeping with that spirit, there's no harm in just using it.
How to use make-standalone-toolchain.sh with Cygwin on Windows
Extract the toolchain from the Android NDK using Cygwin. The NDK version used is r8e-x64. (If the NDK is x64, you need to add the --system=windows-x86_64 option.)
cwlee@cwlee-zeki-pc /
$ /cygdrive/d/libs/android-ndk-r8e-x64/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=/cygdrive/d/proj/android-8-toolchains/
For reference, if a permission denied problem occurs in Cygwin, run Cygwin with administrator privileges.
build_ffmpeg-android-arm.sh
The script that compiles correctly on Ubuntu is as follows. (See javacv-0.5-cppjars.zip) (Test environment: Ubuntu 12.04 LTS, FFmpeg 1.2.2)
ANDROID_BIN=$ANDROID_NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/
ANDROID_ROOT=$ANDROID_NDK/platforms/android-9/arch-arm/
tar -xjvf ffmpeg-$FFMPEG_VERSION.tar.bz2
mv ffmpeg-$FFMPEG_VERSION ffmpeg-$FFMPEG_VERSION-android-arm
cd ffmpeg-$FFMPEG_VERSION-android-arm
tar -xjvf ../last_stable_x264.tar.bz2
X264=`echo x264-snapshot-*`
cd $X264
./configure --enable-static --enable-pic --disable-cli --cross-prefix=$ANDROID_BIN/arm-linux-androideabi- --sysroot=$ANDROID_ROOT --host=arm-linux --extra-cflags="-DANDROID -fPIC -ffunction-sections -funwind-tables -fstack-protector -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -mfpu=neon -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300" --extra-ldflags="-nostdlib -Wl,--fix-cortex-a8 -lgcc -ldl -lz -lm -lc"
make -j4
cd ../
patch -p1 < ../ffmpeg-$FFMPEG_VERSION-android-arm.patch
./configure --prefix=$HOME/android --enable-shared --enable-gpl --enable-version3 --enable-runtime-cpudetect --disable-outdev=sdl --enable-libx264 --extra-cflags="-I$X264" --extra-ldflags="-L$X264" --enable-cross-compile --cc=$ANDROID_BIN/arm-linux-androideabi-gcc --sysroot=$ANDROID_ROOT --target-os=linux --arch=arm --extra-cflags="-DANDROID -fPIC -ffunction-sections -funwind-tables -fstack-protector -march=armv7-a -mfloat-abi=softfp -mfpu=vfp -mfpu=neon -fomit-frame-pointer -fstrict-aliasing -funswitch-loops -finline-limit=300" --extra-ldflags="-nostdlib -Wl,--fix-cortex-a8" --extra-libs="-lgcc -ldl -lz -lm -lc" --disable-stripping --disable-symver --disable-programs
make -j4
LIBS="libavcodec/libavcodec.so libavdevice/libavdevice.so libavfilter/libavfilter.so libavformat/libavformat.so libavutil/libavutil.so libpostproc/libpostproc.so libswresample/libswresample.so libswscale/libswscale.so"
$ANDROID_NDK/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-strip $LIBS
mkdir -p com/googlecode/javacv/cpp/android-arm/
cp $LIBS com/googlecode/javacv/cpp/android-arm/
jar cvf ../ffmpeg-$FFMPEG_VERSION-android-arm.jar com/
rm -Rf com/
cd ../
If you want to add new files (*.c, *.h) to a library (so) during compilation, check the Makefile in that library's directory again.
-
NAME: Name of the library file you want to apply. -
HEADERS: List of header (*.h) files you want to add. -
OBJS: Object (*.o) files to apply to the library.
Then, to integrate the compiled so files with the NDK, apply Android.mk as follows.
LOCAL_PATH := $(call my-dir)
# include $(CLEAR_VARS)
# LOCAL_MODULE := ffmpeg
# LOCAL_SRC_FILES := libffmpeg.so
# LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
# include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avcodec
LOCAL_SRC_FILES := libs/libavcodec.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avdevice
LOCAL_SRC_FILES := libs/libavdevice.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avfilter
LOCAL_SRC_FILES := libs/libavfilter.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avformat
LOCAL_SRC_FILES := libs/libavformat.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := avutil
LOCAL_SRC_FILES := libs/libavutil.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := postproc
LOCAL_SRC_FILES := libs/libpostproc.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swresample
LOCAL_SRC_FILES := libs/libswresample.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := swscale
LOCAL_SRC_FILES := libs/libswscale.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/ffmpeg
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := cinema
LOCAL_C_INCLUDES := ffmpeg
LOCAL_SRC_FILES := \
jni-event.c \
cinema-jni.c \
util.c \
ffmpeg-recoder.c \
runffmpeg.c \
ffmpeg/ffmpeg.c \
ffmpeg/cmdutils.c \
ffmpeg/ffmpeg_opt.c \
ffmpeg/ffmpeg_filter.c
LOCAL_LDLIBS := -llog
LOCAL_CFLAGS := -Wno-deprecated-declarations
LOCAL_SHARED_LIBRARIES +=\
avcodec \
avdevice \
avfilter \
avformat \
avutil \
postproc \
swresample \
swscale
include $(BUILD_SHARED_LIBRARY)
If you want to use ffmpeg.c (ffmpeg.exe) in the NDK, you need to modify it as follows.
- Make sure atexit() is not used. If there is a function used inside atexit() (e.g.
exit_program()), arrange for that function to be called right beforemain()exits. - Watch out for function attributes such as attribute((noreturn)) (just remove them).
- When
main()exits, initialize the global variables of all files related to ffmpeg.c (ffmpeg.exe) (seeexit_program()), and especially if you reuse ffmpeg.c multiple times, make sureavfilter_uninit()is not called.
Color space converting
- Stackoverflow - How do I downsize a YUV420SP (NV21) frame retrieved from Android camera?
- Stackoverflow - Android (onPreviewFrame): Saving NV21 data as JPEG File
- ConvertNV21.java
- Android-MJPEG-Video-Capture-FFMPEG
- Stackoverflow - Converting NV21 to RGB using OpenCV in Android
Example
- https://github.com/yixia/FFmpeg-Android.git
- Build script written with reference to the FFmpeg-Android.git project: Compile-ffmpeg-android.zip
Project site
- Github: Android-Video-Player-FFmpeg-and-Bitmap
- ffmpeg-android
- this is port of ffmpeg for android
- RockPlayer website
- FFmpeg for Android
- Java binding to FFmpeg libraries
- [Recommended] Building FFmpeg for Android neon, armv7, vfp and armv6, used in VPlayer for Android
Troubleshooting
arm-linux-androideabi-pkg-config not found, library detection may fail
During configure, pkg-config may not be found, and a message like the following may appear.
WARNING: /home/cwlee/ndk-r8e-toolchain/bin/arm-linux-androideabi-pkg-config not found, library detection may fail.
In this case, change pkg_config_default="${cross_prefix}${pkg_config_default}" in the configure file to pkg_config_default="${pkg_config_default}". Or use /usr/bin/pkg-config.
How to deal with an UnsatisfiedLinkError Exception
If an UnsatisfiedLinkError Exception occurs along with an error related to ff_av_get_cpu_flags_arm, add the disable-asm option when compiling FFmpeg. During compilation, error messages like the following may be printed.
- please_use_av_log_instead_of_fprintf
- please_use_av_log_instead_of_printf
- please_use_av_log_instead_of_perror
- time_is_forbidden_due_to_security_issues
In this case, un-define each of those symbols as follows.
- #undef time
- #undef printf
- #undef fprintf
- #undef perror
See also
Favorite site
- [Recommended] Developing an Android video player with FFmpeg 1
- [Recommended] Developing an Android video player with FFmpeg: NHN Video Service Development Team 2
- Android FFmpeg video
- Using libavformat and libavcodec
- How to use the x264 encoder in FFmpeg
- Making an NDK FFmpeg video player
- Using FFmpegFrameRecorder on Android
- FFMPEG on Android
- [Recommended] Effective Color Conversion (YUV->RGB) for Android in Assembly
- How to Port ffmpeg (the Program) to Android?Ideas and Thoughts
- How to Build Android Applications Based on FFmpeg by An Example
- How to Build FFmpeg for Android
- NDK ffmpeg compilation (using neon)
- Problem when building a library for Android with the NDK: missing codec_names.h
- http://hoonkyu.blogspot.kr/2011/12/android-ndk-ffmpeg.html
- http://bluexmas.tistory.com/274
- http://blog.naver.com/ziippy/120138066006
- https://github.com/yixia/FFmpeg-Android
Guide
- How to build FFmpeg as a Shared Library on Android 2
- How to successfully build FFmpeg 1.2 with android ndk-build 3
- How to Build FFmpeg for Android 4
- Build android r5b: How_to_build_ffmpeg_for_android-build_android_r5b.txt.zip
- Build android r6: How_to_build_ffmpeg_for_android-build_android_r6.txt.zip
Android NDK FFmpeg compilation tutorial
- http://www.androidpub.com/1645684 8
- http://www.androidpub.com/1646144 9
- http://www.androidpub.com/1646529 10
- http://www.androidpub.com/1646540 11
- Full source code: http://www.androidpub.com/1648388
- A new attempt: http://www.androidpub.com/1690105 12
Building the FFmpeg libraries
- http://blog.daum.net/hopefullife/205 13
- http://blog.daum.net/hopefullife/207 14
- http://blog.daum.net/hopefullife/209 15
How to compile FFmpeg with the NDK (Chinese)
- How to compile FFmpeg 0.6.3 with NDK r4b on Ubuntu (Chinese) 16
- How to compile FFmpeg 0.8 with NDK r5b on Mac OSX (Chinese) 17
- How to compile FFmpeg 0.7.1 with NDK r5c on Windows 7 (Chinese) 18
ETC
References
-
Ffmpeg_android_video_player.pdf ↩
-
Android_ndk_ffmpeg_shared_library.pdf ↩
-
Android_ndk_ffmpeg-1.2_build_success.pdf ↩
-
How_to_build_ffmpeg_for_android.pdf ↩
-
How_to_build_ffmpeg_with_android_ndk.pdf ↩
-
Ffmpeg_porting_and_jni_library.pdf ↩
-
Ffmpeg_for_android-install_and_compile.pdf ↩
-
Android_ndk_ffmpeg_compile_01.pdf ↩
-
Android_ndk_ffmpeg_compile_02.pdf ↩
-
Android_ndk_ffmpeg_compile_03.pdf ↩
-
Android_ndk_ffmpeg_compile_04.pdf ↩
-
Ffmpeg_compile_for_android_ndk_cross_compiler.pdf ↩
-
Android_ndk_ffmpeg_library_build_01.pdf ↩
-
Android_ndk_ffmpeg_library_build_02.pdf ↩
-
Android_ndk_ffmpeg_library_build_03.pdf ↩
-
Ubuntu_android_ndk_r4b_ffmpeg_0.6.3.pdf ↩
-
Macosx_android_ndk_r5b_ffmpeg_0.8.pdf ↩
-
Windows7_android_ndk_r5c_ffmpeg_0.7.pdf ↩