一、准备环境
操作系统:Mac
NDK版本:r17c
FFmpeg版本:4.1.3
二、编译脚本
首先我们需要修改下FFmpeg目录下的configure
文件的内容,
将
代码语言:txt复制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)'
替换为
代码语言:txt复制SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
然后在FFmpeg目录下新建一个build.sh
文件,这个将作为编译脚本使用。
编译脚本内容是:
代码语言:txt复制#!/bin/bash
set -x
API=14
CPU=armv7-a
NDK=/Users/chenqidian/android-ndk-r17c
SYSROOT=$NDK/platforms/android-$API/arch-arm/
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
PREFIX=$(pwd)/android/$CPU
function function_one
{
./configure
--prefix=$PREFIX
--enable-shared
--disable-static
--disable-doc
--disable-ffplay
--disable-ffprobe
--disable-symver
--disable-ffmpeg
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi-
--target-os=android
--arch=arm
--enable-cross-compile
--sysroot=$SYSROOT
--extra-cflags="-I$NDK/sysroot/usr/include/arm-linux-androideabi -isysroot $NDK/sysroot -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm -march=armv7-a"
--enable-neon
make clean all
make
make install
}
function_one
注意:
这里有几个参数需要根据实际情况来配置的;
API
、CPU
、NDK
以及TOOLCHAIN
这个路径最后的文件夹名称(Mac下是darwin-x86_64、linux可能叫linux-x86_64、Windows也不一样);
最后生成的库在PREFIX
这个路径下。
三、操作步骤
代码语言:txt复制# 巴拉巴拉一堆,然后agree就可以
sudo xcodebuild -license
# 这一步很关键,不然跑编译脚本会有一堆文件找不到的错误
./configure
# 真正编译
./build.sh
四、过程踩坑
哪有那么容易的事,以为用了上面那三个命令行就可以编译出FFmpeg,这里记录下上面三个命令行中踩到的坑。
问题一:
首先是./configure
执行后:
nasm/yasm not found or too old. Use --disable-x86asm for a crippled build.
这个还比较简单只要安装下yasm
就能将解决
brew install yasm
问题二:
代码语言:txt复制Unknown option "--prefix=/Users/chenqidian/ffmpeg/android/arm".
See ./configure --help for available options.
解决办法:
复制网上的sh脚本时,将./configure --prefix=$PREFIX
写在同一行了,换行写就可以了,记得后面去掉空格。
问题三:
代码语言:txt复制Unknown option "--disable-ffserver".
解决办法:新版的FFmpeg已经没有这个参数了,去掉就可以了。相关命令参数可以通过./configure --help
来查看。
问题四:
代码语言:txt复制/bin/sh: ranlib/usr/local/lib/libavdevice.a: No such file or directory
make: *** [install-libavdevice-static] Error 127
原因和解决办法:
由于LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
这个命令少打了一个空格,应该改为`LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"'。
之后要重新执行下./configure
,不然还是报这个错。
问题五:
代码语言:txt复制/Users/chenqidian/android-ndk-r20/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-gcc is unable to create an executable file.
**C compiler test failed.**
原因和解决办法:
我之前使用的是ndk-r20时报的这个错误,原因是没有arm-linux-androideabi-gcc
这个文件了。
chenqidiandeMacBook-Pro:~ chenqidian$ cd /Users/chenqidian/android-ndk-r20/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin
chenqidiandeMacBook-Pro:bin chenqidian$ ls
arm-linux-androideabi-addr2line arm-linux-androideabi-ld.gold
arm-linux-androideabi-ar arm-linux-androideabi-nm
arm-linux-androideabi-as arm-linux-androideabi-objcopy
arm-linux-androideabi-c filt arm-linux-androideabi-objdump
arm-linux-androideabi-dwp arm-linux-androideabi-ranlib
arm-linux-androideabi-elfedit arm-linux-androideabi-readelf
arm-linux-androideabi-gprof arm-linux-androideabi-size
arm-linux-androideabi-ld arm-linux-androideabi-strings
arm-linux-androideabi-ld.bfd arm-linux-androideabi-strip
cd到这个目录下看,确实没有gcc这个文件。
原来是ndk在R19C中把GCC,最后一个有gcc的版本是r17c,偷了个懒,换这个有gcc版本的ndk(就是现在的r17c这个版本)。
问题六:
代码语言:txt复制/Users/chenqidian/android-ndk-r17c/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/lib/gcc/arm-linux-androideabi/4.9.x/include/stdint.h:9:26: fatal error: stdint.h: No such file or directory
原因和解决办法:
头文件找不到,是因为r17c这个版本把头文件分离出来了,需在–extra-cflags中添加 “-isysroot $NDK/sysroot”
问题七:
代码语言:txt复制libavcodec/aaccoder.c: In function 'search_for_ms':
libavcodec/aaccoder.c:803:25: error: expected identifier or '(' before numeric constant
int B0 = 0, B1 = 0;
^
compilation terminated due to -Wfatal-errors.
make: *** [libavcodec/aaccoder.o] Error 1
原因和解决办法:变量名冲突了,修改FFmpeg/libavcodec/aaccoder.c
文件B0改成b0或者其他不会冲突的变量名
问题八:
代码语言:txt复制libavcodec/hevc_mvs.c: In function 'derive_spatial_merge_candidates':
libavcodec/hevc_mvs.c:208:15: error: 'y0000000' undeclared (first use in this function)
((y ## v) >> s->ps.sps->log2_min_pu_size))
^
libavcodec/hevc_mvs.c:204:14: note: in definition of macro 'TAB_MVF'
tab_mvf[(y) * min_pu_width x]
^
libavcodec/hevc_mvs.c:274:16: note: in expansion of macro 'TAB_MVF_PU'
(cand && !(TAB_MVF_PU(v).pred_flag == PF_INTRA))
^
libavcodec/hevc_mvs.c:368:23: note: in expansion of macro 'AVAILABLE'
is_available_b0 = AVAILABLE(cand_up_right, B0) &&
^
compilation terminated due to -Wfatal-errors.
make: *** [libavcodec/hevc_mvs.o] Error 1
原因和解决方法:变量名冲突了,将FFmpeg/libavcodec/hevc_mvs.c
文件的变量B0改成b0,xB0改成xb0,yB0改成yb0;
问题九:
代码语言:txt复制libavcodec/opus_pvq.c: In function 'quant_band_template':
libavcodec/opus_pvq.c:498:9: error: expected identifier or '(' before numeric constant
int B0 = blocks;
^
compilation terminated due to -Wfatal-errors.
make: *** [libavcodec/opus_pvq.o] Error 1
原因和解决办法:变量名冲突了,将FFmpeg/libavcodec/opus_pvq.c
文件的变量B0改成b0;
问题十:
编译完一看都是后缀.a
的库,不是我们要的so库?
解决办法:看下你的编译脚本,要这么写
代码语言:txt复制 --enable-shared
--disable-static
五、参考文章
https://blog.csdn.net/qq_34902522/article/details/87879145
http://alientechlab.com/how-to-build-ffmpeg-for-android/