编译Android平台使用的FFmpeg(armeabi,armeabi-v7a,arm64-v8a,x86,x86_64)

1. 编译平台 Ubuntu

编译Android平台使用的FFmpeg(armeabi,armeabi-v7a,arm64-v8a,x86,x86_64)_第1张图片

2. NDK

linux环境NDK下载
https://developer.android.google.cn/ndk/downloads/
这里编译使用的是
[Android NDK, Revision 15c] 1 (July 2017)

3. 编译过程

3.1 下载FFmpeg源码

FFmpeg下载地址
http://ffmpeg.org/download.html

最新版本: [FFmpeg 4.0]2 (4.0 was released on 2018-04-20.)

下载后解压,打开终端,定位到下载目录
tar -xvf ffmpeg-4.0.tar.xz

3.2 修改configure脚本

为了在Android上使用,我们修改生成so库的脚本,生成以lib为前缀,.so为后置的name,在源文件目录下找到configure脚本,差不多在3566

# 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)'
#修改为以下内容

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'

3.3 编写编译脚本

创建脚本文件 build.sh,编辑内容,脚本文件位于FFmpeg源文件目录下

#!/bin/sh

MY_LIBS_NAME=ffmpeg-4.0
MY_DIR=ffmpeg-4.0

# cd ./${MY_DIR}

#编译的过程中产生的中间件的存放目录,为了区分编译目录,源码目录,install目录
MY_BUILD_DIR=binary


NDK_PATH=/home/as/Android/android-ndk-r15c
BUILD_PLATFORM=linux-x86_64
TOOLCHAIN_VERSION=4.9
ANDROID_VERSION=24

ANDROID_ARMV5_CFLAGS="-march=armv5te"
ANDROID_ARMV7_CFLAGS="-march=armv7-a -mfloat-abi=softfp -mfpu=neon"  #-mfloat-abi=hard -mfpu=vfpv3-d16 #-mfloat-abi=hard -mfpu=vfp
ANDROID_ARMV8_CFLAGS="-march=armv8-a"
ANDROID_X86_CFLAGS="-march=i686 -mtune=intel -mssse3 -mfpmath=sse -m32"
ANDROID_X86_64_CFLAGS="-march=x86-64 -msse4.2 -mpopcnt -m64 -mtune=intel"


# params($1:arch,$2:arch_abi,$3:host,$4:cross_prefix,$5:cflags)
build_bin() {

	echo "-------------------star build $2-------------------------"

	ARCH=$1			# arm arm64 x86 x86_64
	ANDROID_ARCH_ABI=$2 	# armeabi armeabi-v7a x86 mips

	PREFIX=$(pwd)/dist/${MY_LIBS_NAME}/${ANDROID_ARCH_ABI}/

	HOST=$3
	SYSROOT=${NDK_PATH}/platforms/android-${ANDROID_VERSION}/arch-${ARCH}

	CFALGS=$5


	TOOLCHAIN=${NDK_PATH}/toolchains/${HOST}-${TOOLCHAIN_VERSION}/prebuilt/${BUILD_PLATFORM}
	CROSS_PREFIX=${TOOLCHAIN}/bin/$4-

	# build 中间件
    BUILD_DIR=./${MY_BUILD_DIR}/${ANDROID_ARCH_ABI}

	echo "pwd==$(pwd)"
	echo "ARCH==${ARCH}"
	echo "PREFIX==${PREFIX}"
	echo "HOST==${HOST}"
	echo "SYSROOT=${SYSROOT}"
	echo "CFALGS=$5"
	echo "CFALGS=${CFALGS}"
	echo "TOOLCHAIN==${TOOLCHAIN}"
	echo "CROSS_PREFIX=${CROSS_PREFIX}"

	#echo "-------------------------按任意键继续---------------------"
	#read -n 1
	#echo "-------------------------继续执行-------------------------"

	mkdir -p ${BUILD_DIR}   #创建当前arch_abi的编译目录,比如:binary/armeabi-v7a
    cd ${BUILD_DIR}         #此处 进了当前arch_abi的2级编译目录


	sh ../../${MY_DIR}/configure \
		--prefix=${PREFIX} \
		--target-os=linux \
		--arch=${ARCH} \
		--sysroot=$SYSROOT \
		--enable-cross-compile \
		--cross-prefix=${CROSS_PREFIX} \
		--extra-cflags="$CFALGS -Os -fPIC -DANDROID -Wfatal-errors -Wno-deprecated" \
		--extra-cxxflags="-D__thumb__ -fexceptions -frtti" \
		--extra-ldflags="-L${SYSROOT}/usr/lib" \
		--enable-shared \
		--enable-asm \
		--enable-neon \
		--disable-encoders \
		--enable-encoder=aac \
		--enable-encoder=mjpeg \
		--enable-encoder=png \
		--disable-decoders \
		--enable-decoder=aac \
		--enable-decoder=aac_latm \
		--enable-decoder=h264 \
		--enable-decoder=mpeg4 \
		--enable-decoder=mjpeg \
		--enable-decoder=png \
		--disable-demuxers \
		--enable-demuxer=image2 \
		--enable-demuxer=h264 \
		--enable-demuxer=aac \
		--disable-parsers \
		--enable-parser=aac \
		--enable-parser=ac3 \
		--enable-parser=h264 \
		--enable-gpl \
		--disable-doc \
		--disable-ffmpeg \
		--disable-ffplay \
		--disable-ffprobe \
		--disable-symver \
		--disable-debug \
		--enable-small


	make clean
	make
	make install

	#从当前arch_abi编译目录跳出,对应上面的cd ${BUILD_DIR},以便function多次执行
    	cd ../../

	echo "-------------------$2 build end-------------------------"
}


# build armeabi
build_bin arm armeabi arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV5_CFLAGS"

#build armeabi-v7a
build_bin arm armeabi-v7a arm-linux-androideabi arm-linux-androideabi "$ANDROID_ARMV7_CFLAGS"

#build arm64-v8a
build_bin arm64 arm64-v8a aarch64-linux-android aarch64-linux-android "$ANDROID_ARMV8_CFLAGS"

#build x86
build_bin x86 x86 x86 i686-linux-android "$ANDROID_X86_CFLAGS"

#build x86_64
build_bin x86_64 x86_64 x86_64 x86_64-linux-android "$ANDROID_X86_64_CFLAGS"

脚本编写注意事项

1.不要在有换行连接符\的语句中插入注释#,有可能会使后面的内容连接失败,尤其 ./configure语句后面的option选项中

2.FFmpeg 4.0 源码编译中会出现以下两个文件的编译错误

libavcodec / aaccoder.c:函数’search_for_ms’:
libavcodec / aaccoder.c:803:25:错误:预期的标识符或’(‘数字常量之前
libavcodec / hevc_mvs.c:函数’derive_spatial_merge_candidates’
libavcodec / hevc_mvs.c:368:23:错误:'y0000000’未声明(首次在此函数中使用

是因为在include的/usr/arm-linux-androideabi/include/asm/termbits.h文件中定义了B0 0000000的宏,导致aaccooder.c hevc_mvs.c文件中的B0变量被宏替换

#define B0 0000000

解决方法就是,在这两个文件中,把所有的B0,替换成其它字符,比如我替换为:bb, 注意不要和其它变量重复定义

3.--extra-cflags里不要加不被支持的选项,否则会出现C compiler test failed的错误,具体哪些不被识别,请报错之后查看config.log文件,比如在编译arm64-v8a

aarch64-linux-android-gcc: error: unrecognized command line option ‘-mfloat-abi=softfp’

4.每一个arch编译过程中出现以下 WARNING可以忽略

WARNING: /home/as/Android/android-ndk-r15c/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-pkg-config not found, library detection may fail.

3.4 编译

  1. build.sh编译脚本所在的目录打开终端
  2. 执行 sh build.sh,开始编译,脚本文件里指定了--prefix,install目录由--prefix指定在源码目录文件夹下的dist,安装脚本会在dist下生成安装对应CPU架构的的库
    编译Android平台使用的FFmpeg(armeabi,armeabi-v7a,arm64-v8a,x86,x86_64)_第2张图片

编译Android平台使用的FFmpeg(armeabi,armeabi-v7a,arm64-v8a,x86,x86_64)_第3张图片
编译Android平台使用的FFmpeg(armeabi,armeabi-v7a,arm64-v8a,x86,x86_64)_第4张图片

编译Android平台使用的FFmpeg(armeabi,armeabi-v7a,arm64-v8a,x86,x86_64)_第5张图片



  1. https://developer.android.google.cn/ndk/downloads/older_releases#ndk-15c-downloads ↩︎

  2. https://ffmpeg.org/releases/ffmpeg-4.0.tar.bz2 ↩︎

你可能感兴趣的:(Android,JNI,NDK)