ffmpeg4.4在Linux下使用android NDK 21新版本编译及其问题解决

一、可参考英文官网
https://trac.ffmpeg.org/wiki/CompilationGuide/Generic
【安装编译、更新、移除】https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu#RevertingChangesmadebythisGuide
https://trac.ffmpeg.org/wiki/CompilationGuide
https://trac.ffmpeg.org/

二、下载步骤

备注:可参考官网【安装编译、更新、移除】

安装依赖脚本,并执行它:【若有已安装的可去掉】

sudo apt-get update -qq && sudo apt-get -y install \
  autoconf \
  automake \
  build-essential \
  cmake \
  git-core \
  libass-dev \
  libfreetype6-dev \
  libgnutls28-dev \
  libsdl2-dev \
  libtool \
  libva-dev \
  libvdpau-dev \
  libvorbis-dev \
  libxcb1-dev \
  libxcb-shm0-dev \
  libxcb-xfixes0-dev \
  meson \
  ninja-build \
  pkg-config \
  texinfo \
  wget \
  yasm \
  zlib1g-dev

在自己的home目录中创建:
mkdir -p ~/ffmpeg_sources

然后直接在官网下载最新tar.gzip压缩包版本,放入linux ffmpeg_sources 中解压出来,进入ffmpeg根目录,创建build_android.h,内容如下可参考别人写的利用NDK(r20) 编译FFmpeg 4.2.1 Android版本,也可参考官网自行优化。

但他这边文章有一个错误配置:
如下,即文中的 --arch=arm64 应该写为:–arch=aarch64

–arch=xxx的参数列表在ffbuild/config.log里面会所有支持的arch列表:
ARCH_LIST=’
aarch64
alpha
arm
avr32
avr32_ap
avr32_uc
bfin
ia64
m68k
mips
mips64
parisc
ppc
ppc64
s390
sh4
sparc
sparc64
tilegx
tilepro
tomi
x86
x86_32
x86_64

三、编译步骤
linux版本编译直接参考官网即可:

Linux下必须安装 yasm汇编器【nasm】对ffmpeg中的汇编部分进行编译,默认配置会使用它,否则报错。

ffmpeg源码目录下,首先执行 ./configure ,看是否一切正常,正常将不会报错,还可以看到许多配置信息。
注意修改编译脚本编译结果为so库,而非静态库。

执行上面的编译脚本,等待编译结果在当前目录的android_shared目录中生成。

备注:多核CPU可使用make -j4来提升编译速度,4表示4核。或者使用 make -j$(nproc) 来适配本机可使用的核数

linux版本编译结果时可在最后使用 ffmpeg命令行来验证编译结果,执行 ./ffmpeg.exe -h ,将会出现ffmpeg安装配置信息。

安卓交叉编译:
直接参考别人写的很不错的文章利用NDK(r20) 编译FFmpeg 4.2.1 Android版本

本文主要记录编译错误和运行错误问题

四、编译失败问题
编译时报错:
Makefile执行过程中出错:make: *** No rule to make target ` ‘, needed by xxx. Stop.
需要去掉 --disable-fserver 配置

注意:xxx : command not found
如–disable-doc: command not found 这种指令找不到错误时,就是shell脚本的该行命令上面写了注释但最后用了 \ 反斜杠,必须去掉

错误:
1、libavfilter/af_acrossover.c:42:9: warning: ‘B0’ macro redefined [-Wmacro-redefined]
#define B0 0
改为B00

2、libavfilter/af_aecho.c:188:9: warning: ‘ECHO’ macro redefined [-Wmacro-redefined]
#define ECHO(name, type, min, max)
改为ECHO2

3、若出现WARNING:/root/android-ndk/…/arm-linux-androideabi-pkg-config not found, library detection may fail. 可忽略。

ffmpeg库在安卓上运行错误:
java.lang.UnsatisfiedLinkError: dlopen failed: library “libclang_rt.ubsan_standalone-aarch64-android.so” not found。
必须将交叉编译下的该so库拷贝出来和ffmpeg的同CPU库一起加载
至于原因,我也不清楚为啥需要这个独立库?,我也不想要这个库,有同学知道原因还请指出

XXX、随记
2016年初,ffmpeg自身AAC编码器质量变好,年底将此前的libfaac替换为新的自身的libfdkaac,并从源码中移除。
ffmpeg全部支持的话,so库比较大,可以通过裁剪操作来去掉一些不需要的编码、封装或协议等。可以在关闭所有的模块之后单独定制支持自己所需的模块。

“ARMv8-A”是指AArch64,带有A64指令集,也称为arm64或ARM64。

android.mk 和 Makefile中打印变量
$(warning $(DVD_SERVICE)) // DVD_SerVICE是Makefile中的变量

Makefile中宏AS一般代表汇编语言编译器,ASFLAGS一般代表编译汇编语言代码时的编译选项
AS和ASFLAGS都是环境变量。
${xxx}就是取出环境变量的值。
makefile中,AS环境变量一般放的是汇编器的名称,ASFLAGS是汇编参数。
于是
${AS} A S F L A G S 就 是 一 条 用 {ASFLAGS} 就是一条用 ASFLAGS就是一条用{AS}汇编器传${ASFLAGS}汇编参数的汇编指令,跟上汇编源文件就一条完整的汇编命令语句了。

BUILD_PREBUILT 是预置so到源码指定out目录中,然后成为系统so来访问

而 PREBUILT_SHARED_LIBRARY 却是AS中使用的:NDK 支持使用预编译库
https://www.cnblogs.com/gamesky/p/11369172.html 可参考

shell脚本中打印
echo “canshu2:${analysis_date}”

shell中写的 export命令将变量myfile输出至任何子shell,例如当执行父脚本程序时产生的子shell。
也就是说调用的子shell可以直接使用父shell中变量,所以如果你执行在当前shell中定义变量使用,则不需要写export

上一篇:2个月面试腾讯、B站、网易等11家公司的面经总结!先收藏了


下一篇:ndk开发入门,Android自定义View详解,终局之战