目录
前言
系统版本 :Ubuntu 18
FFmpeg版本 : ffmpeg version N-102948-g79ebdbb9b9(下载最新的,这是编译后的版本信息)
最近有看就整理了一下自己编译ffmpeg的编译过程,方便自己查阅。
正文
下面就记录编译的过程用的编译脚本以及所遇到的问题。
NDK 下载
这个可以参考《[ijkplayer专题] Ubuntu 18.3 编译ijkplayer-android》这篇文章。
NDK下载链接:https://developer.android.google.cn/ndk/downloads/older_releases
我这里用的是android-ndk-r17c
FFmpeg 下载
我是直接clone最新的代码编译的。如果你想编译不同的,自己单独下载对应的版本。
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
修改配置
修改ffmpeg目录中的configure的配置。
# water add # 修改后的 SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)' LIB_INSTALL_EXTRA_CMD='$$(RANLIB) "$(LIBDIR)/$(LIBNAME)"' SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)' SLIB_INSTALL_LINKS='$(SLIBNAME)' # 修改前的,这里是注释了 #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)' # water add end
配置编译脚本
下面是我编译时用的脚本。
在ffmpeg的目录下载创建一个ffmpegmake.sh(名字看你喜好)文件,复制如下内容即可。
PS: 我这是编译arm,如果你的需求不一样,需要修改。
#!/bin/bash NDK=/home/water/ijkdir/ndk-sdk-tool/android-ndk-r17c SYSROOT=${NDK}/platforms/android-23/arch-arm TOOLCHAIN=${NDK}/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64 function build_so { ./configure \ --prefix=$PREFIX \ --enable-shared \ --disable-static \ --disable-doc \ --disable-ffmpeg \ --disable-ffplay \ --disable-ffprobe \ --disable-avdevice \ --disable-doc \ --disable-symver \ --cross-prefix=${TOOLCHAIN}/bin/arm-linux-androideabi- \ --target-os=linux \ --arch=arm \ --enable-cross-compile \ --sysroot=$SYSROOT \ --extra-cflags="-Os -isysroot $ISYSROOT -fpic $ADDI_CFLAGS -I$NDK/sysroot/usr/include -I$NDK/sysroot/usr/include/arm-linux-androideabi" \ --extra-ldflags="$ADDI_LDFLAGS" \ $ADDITIONAL_CONFIGURE_FLAG make clean make make install } CPU=arm PREFIX=./android/$CPU ADDI_CFLAGS="-marm" build_so
执行脚本
哈哈哈 ,想多了,建议先看下面我遇到的问题, [问题四:宏定义冲突] 你一定会遇到,所以在编译前直接修改。 修改后再执行这一步。
./ffmpegmake.sh
然后等待就可以。
如果最后出现如下面内容,表示编译OK
//省略 .... INSTALL libavutil/imgutils.h INSTALL libavutil/intfloat.h INSTALL libavutil/intreadwrite.h INSTALL libavutil/lfg.h INSTALL libavutil/log.h INSTALL libavutil/macros.h INSTALL libavutil/mathematics.h INSTALL libavutil/mastering_display_metadata.h INSTALL libavutil/md5.h INSTALL libavutil/mem.h INSTALL libavutil/motion_vector.h INSTALL libavutil/murmur3.h INSTALL libavutil/opt.h INSTALL libavutil/parseutils.h INSTALL libavutil/pixdesc.h INSTALL libavutil/pixelutils.h INSTALL libavutil/pixfmt.h INSTALL libavutil/random_seed.h INSTALL libavutil/rc4.h INSTALL libavutil/rational.h INSTALL libavutil/replaygain.h INSTALL libavutil/ripemd.h INSTALL libavutil/samplefmt.h INSTALL libavutil/sha.h INSTALL libavutil/sha512.h INSTALL libavutil/spherical.h INSTALL libavutil/stereo3d.h INSTALL libavutil/threadmessage.h INSTALL libavutil/time.h INSTALL libavutil/timecode.h INSTALL libavutil/timestamp.h INSTALL libavutil/tree.h INSTALL libavutil/twofish.h INSTALL libavutil/version.h INSTALL libavutil/video_enc_params.h INSTALL libavutil/xtea.h INSTALL libavutil/tea.h INSTALL libavutil/tx.h INSTALL libavutil/film_grain_params.h INSTALL libavutil/lzo.h INSTALL libavutil/avconfig.h INSTALL libavutil/ffversion.h INSTALL libavutil/libavutil.pc
编译中出现的编译问题
问题一 出现多余的空格符
这个你不一定出现。
Unknown option "". See ./configure --help for available options.
我是复制别人脚本时,在\后面存在空格导致的,如果你那也出现这个问题,需要删除每行最后面的空格即可。
PS: 直接复制代码的代价。
问题二:pkg-config没安装
pkg-config not found, library detection may fail.
直接安装pkg-config即可。
sudo apt-get install pkg-config
后面就没了。
问题三 : 确实stdlib.h库
这个是重点,必须修改,要不然编译不过。
./libavutil/avassert.h:30:20: fatal error: stdlib.h: No such file or directory
出现这个错误是因为使用最新版的NDK造成的,最新版的NDk将头文件和库文件进行了分离。 指定的sysroot文件夹下只有库文件,而头文件放在了NDK目录下的sysroot内。 只需在--extra-cflags中添加 "-isysroot $NDK/sysroot" 即可 还有有关汇编的头文件也进行了分离,需要根据目标平台进行指定 "-I$NDK/sysroot/usr/include/arm-linux-androideabi",将 "arm-linux-androideabi"
不过,上面的脚本已经添加了。
编译ffmpegmake.sh脚本修改的地方是:
--extra-cflags="-Os -isysroot $ISYSROOT -fpic $ADDI_CFLAGS -I$NDK/sysroot/usr/include -I$NDK/sysroot/usr/include/arm-linux-androideabi" \
问题四 : 宏定义冲突
这个问题必须修改。
错误一
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; ^ libavcodec/aaccoder.c:865:28: error: lvalue required as left operand of assignment B0 += b1+b2; ^ libavcodec/aaccoder.c:866:25: error: 'B1' undeclared (first use in this function) B1 += b3+b4; ^ libavcodec/aaccoder.c:866:25: note: each undeclared identifier is reported only once for each function it appears in make: *** [libavcodec/aaccoder.o] Error 1
错误二
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/opus_pvq.c: In function 'quant_band_template': libavcodec/opus_pvq.c:498:9: error: expected identifier or '(' before numeric constant int B0 = blocks; ^ libavcodec/opus_pvq.c:559:12: error: lvalue required as left operand of assignment B0 = blocks; ^ make: *** [libavcodec/opus_pvq.o] Error 1
修改的方式
把下面几个文件中的B0修改为b0,xB0 修改为xb0 ,yB0改成yb0
这个是宏定义命名冲突导致的。
- libavcodec/aaccoder.c
- libavcodec/hevc_mvs.c
- libavcodec/opus_pvq.c
参考文章
- 《NDK r15编译FFmpeg 4.0》
- 《FFmpeg 详尽编译过程》
- 《https://blog.csdn.net/luo0xue/article/details/80048847》
- 《使用android-ndk-r17c构建ffmpeg 4.2.1时遇到的问题》