Skip to content
Search

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 before main() 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) (see exit_program()), and especially if you reuse ffmpeg.c multiple times, make sure avfilter_uninit() is not called.

Color space converting

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

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

Guide

Android NDK FFmpeg compilation tutorial

  1. http://www.androidpub.com/1645684 8
  2. http://www.androidpub.com/1646144 9
  3. http://www.androidpub.com/1646529 10
  4. http://www.androidpub.com/1646540 11
  5. Full source code: http://www.androidpub.com/1648388
  6. A new attempt: http://www.androidpub.com/1690105 12

Building the FFmpeg libraries

  1. http://blog.daum.net/hopefullife/205 13
  2. http://blog.daum.net/hopefullife/207 14
  3. http://blog.daum.net/hopefullife/209 15

How to compile FFmpeg with the NDK (Chinese)

ETC

References


  1. Ffmpeg_android_video_player.pdf ↩

  2. Android_ndk_ffmpeg_shared_library.pdf ↩

  3. Android_ndk_ffmpeg-1.2_build_success.pdf ↩

  4. How_to_build_ffmpeg_for_android.pdf ↩

  5. How_to_build_ffmpeg_with_android_ndk.pdf ↩

  6. Ffmpeg_porting_and_jni_library.pdf ↩

  7. Ffmpeg_for_android-install_and_compile.pdf ↩

  8. Android_ndk_ffmpeg_compile_01.pdf ↩

  9. Android_ndk_ffmpeg_compile_02.pdf ↩

  10. Android_ndk_ffmpeg_compile_03.pdf ↩

  11. Android_ndk_ffmpeg_compile_04.pdf ↩

  12. Ffmpeg_compile_for_android_ndk_cross_compiler.pdf ↩

  13. Android_ndk_ffmpeg_library_build_01.pdf ↩

  14. Android_ndk_ffmpeg_library_build_02.pdf ↩

  15. Android_ndk_ffmpeg_library_build_03.pdf ↩

  16. Ubuntu_android_ndk_r4b_ffmpeg_0.6.3.pdf ↩

  17. Macosx_android_ndk_r5b_ffmpeg_0.8.pdf ↩

  18. Windows7_android_ndk_r5c_ffmpeg_0.7.pdf ↩