FFmepg compilation and integration to Android
- Compile file modification
- Package so execution
- Integration to Android
Preparing for compilation
- Compiled with ubuntu system, the system version does not affect
apt-get update apt-get install yasm apt-get install pkg-config
- Installation of NDK
ndk r15c or ndk r19
After testing, the NDK version has little impact, as long as it is not too low
ndk r15 Download
ndk latest - Download FFmpeg version this article adopts ffmpeg3.4.5
Version 4.1.3 was used, but there are some problems with the script file. It is not easy to use the script file on the Internet. Version 4.1.3 sh is provided at the end of the article (not necessarily easy to use, need to be modified).
-
Modify configure
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)'
-
If you don't need the x264 script, you need to add# Download x264
#!/bin/bash NDK=/home/oblvion/Desktop/ffmpeg/android-ndk-r15c configure() { CPU=$1 PREFIX=$(pwd)/android/$CPU HOST="" CROSS_PREFIX="" SYSROOT="" if [ "$CPU" == "armv7-a" ] then HOST=arm-linux SYSROOT=$NDK/platforms/android-21/arch-arm/ CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi- else HOST=aarch64-linux SYSROOT=$NDK/platforms/android-21/arch-arm64/ CROSS_PREFIX=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android- fi ./configure \ --prefix=$PREFIX \ --host=$HOST \ --enable-pic \ --enable-static \ --enalbe-neon \ --extra-cflags="-fPIE -pie" \ --extra-ldflags="-fPIE -pie" \ --cross-prefix=$CROSS_PREFIX \ --sysroot=$SYSROOT } build() { make clean cpu=$1 echo "build $cpu" configure $cpu #-J < number of CPU cores > make -j4 make install } #build arm64 build armv7-a
-
ffmpeg script
#!/bin/bash NDK=/home/oblvion/Desktop/ffmpeg/android-ndk-r15c ADDI_CFLAGS="-fPIE -pie" ADDI_LDFLAGS="-fPIE -pie" configure() { CPU=$1 PREFIX=$(pwd)/android/$CPU x264=$(pwd)/x264/android/$CPU HOST="" CROSS_PREFIX="" SYSROOT="" ARCH="" if [ "$CPU" == "armv7-a" ] then ARCH="arm" HOST=arm-linux SYSROOT=$NDK/platforms/android-21/arch-arm/ CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi- else ARCH="aarch64" HOST=aarch64-linux SYSROOT=$NDK/platforms/android-21/arch-arm64/ CROSS_PREFIX=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android- fi ./configure \ --prefix=$PREFIX \ --disable-encoders \ --disable-decoders \ --disable-avdevice \ --disable-static \ --disable-doc \ --disable-ffplay \ --disable-network \ --disable-doc \ --disable-symver \ --enable-neon \ --enable-shared \ --enable-libx264 \ --enable-gpl \ --enable-pic \ --enable-jni \ --enable-pthreads \ --enable-mediacodec \ --enable-encoder=aac \ --enable-encoder=gif \ --enable-encoder=libopenjpeg \ --enable-encoder=libmp3lame \ --enable-encoder=libwavpack \ --enable-encoder=libx264 \ --enable-encoder=mpeg4 \ --enable-encoder=pcm_s16le \ --enable-encoder=png \ --enable-encoder=srt \ --enable-encoder=subrip \ --enable-encoder=yuv4 \ --enable-encoder=text \ --enable-decoder=aac \ --enable-decoder=aac_latm \ --enable-decoder=libopenjpeg \ --enable-decoder=mp3 \ --enable-decoder=mpeg4_mediacodec \ --enable-decoder=pcm_s16le \ --enable-decoder=flac \ --enable-decoder=flv \ --enable-decoder=gif \ --enable-decoder=png \ --enable-decoder=srt \ --enable-decoder=xsub \ --enable-decoder=yuv4 \ --enable-decoder=vp8_mediacodec \ --enable-decoder=h264_mediacodec \ --enable-decoder=hevc_mediacodec \ --enable-hwaccel=h264_mediacodec \ --enable-hwaccel=mpeg4_mediacodec \ --enable-ffmpeg \ --enable-bsf=aac_adtstoasc \ --enable-bsf=h264_mp4toannexb \ --enable-bsf=hevc_mp4toannexb \ --enable-bsf=mpeg4_unpack_bframes \ --enable-cross-compile \ --cross-prefix=$CROSS_PREFIX \ --target-os=android \ --arch=$ARCH \ --sysroot=$SYSROOT \ --extra-cflags="-I$x264/include $ADDI_CFLAGS" \ --extra-ldflags="-L$x264/lib" } build() { make clean cpu=$1 echo "build $cpu" configure $cpu make -j4 make install } #build arm64 build armv7-a
Note that the script requires chmod +x build.sh , and sudo. / script executes
- At this time, you finish executing the script. If you are lucky, you can get the so file.
Ready to integrate into the ndk android source code
- Create NDK project
- Import so under the source libs directory
- Import include file
- Modify the build.gradle file
- Edit CMake file
cmake_minimum_required(VERSION 3.4.1) set(lib_src_DIR ${CMAKE_SOURCE_DIR}/../../../libs/${ANDROID_ABI}) add_library( native-lib SHARED native-lib.cpp) add_library( avcodec SHARED IMPORTED) set_target_properties( avcodec PROPERTIES IMPORTED_LOCATION ${lib_src_DIR}/libavcodec.so) add_library( avfilter SHARED IMPORTED) set_target_properties( avfilter PROPERTIES IMPORTED_LOCATION ${lib_src_DIR}/libavfilter.so) add_library( avformat SHARED IMPORTED) set_target_properties( avformat PROPERTIES IMPORTED_LOCATION ${lib_src_DIR}/libavformat.so) add_library( avutil SHARED IMPORTED) set_target_properties( avutil PROPERTIES IMPORTED_LOCATION ${lib_src_DIR}/libavutil.so) add_library( postproc SHARED IMPORTED) set_target_properties( postproc PROPERTIES IMPORTED_LOCATION ${lib_src_DIR}/libpostproc.so) add_library( swresample SHARED IMPORTED) set_target_properties( swresample PROPERTIES IMPORTED_LOCATION ${lib_src_DIR}/libswresample.so) add_library( swscale SHARED IMPORTED) set_target_properties( swscale PROPERTIES IMPORTED_LOCATION ${lib_src_DIR}/libswscale.so) find_library( log-lib log) include_directories(${CMAKE_SOURCE_DIR}/src/main/cpp/include) target_link_libraries( native-lib avcodec avfilter avformat avutil postproc swresample swscale ${log-lib})
- Modify the original native-lib.cpp file
#include <jni.h> #include <string> #include <android/log.h> extern "C" { #include "include/libavcodec/avcodec.h" #include "include/libavfilter/avfilter.h" #include "include/libavformat/avformat.h" #include "include/libavutil/imgutils.h" #include "include/libswresample/swresample.h" #include "include/libswscale/swscale.h" #include "include/libx264/x264.h" } extern "C" JNIEXPORT jstring JNICALL Java_com_wmtc_ndktest_MainActivity_stringFromFFmpeg( JNIEnv *env, jobject /* this */) { char info[10000] = {0}; sprintf(info, "%s\n", avcodec_configuration()); return env->NewStringUTF(info); }
OK. Call, execute, see the following unexpectedly:
Problems encountered
-
ninja: error: xxxxxx missing and no known rule to make it
Because your CMake file is wrong, check it. -
undefined reference to 'avcodec_configuration()'
See if extern "C" is the source file imported like thisextern "C" { #include "include/libavcodec/avcodec.h" #include "include/libavfilter/avfilter.h" #include "include/libavformat/avformat.h" #include "include/libavutil/imgutils.h" #include "include/libswresample/swresample.h" #include "include/libswscale/swscale.h" #include "include/libx264/x264.h" }