Linux下ffmpeg4.x版本编译

前言

最近由于项目要求,需要为android系统机顶盒(32位)的应用提供libffmpeg.so,因此总结了一下编译方法与遇到的坑。


一、编译环境

操作系统:Ubuntu 5.4.0

ffmpeg源码版本:ffmpeg-cd04bb4
---->下载链接:https://git.ffmpeg.org/gitweb/ffmpeg.git/commit/cd04bb4afea111aa85afbaf806ae747103a843fd

ndk使用版本:android-ndk-r17c
---->下载链接:https://developer.android.google.cn/ndk/downloads/older_releases

二、编译步骤

1.修改configure文件内容

刚下载的ffmpeg源码,直接编译出来的so会带有版本号的后缀,无法使用,需要修改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)'

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

2.新建build_android.sh文件

新建build_android.sh文件,用于编译生成libavcodec.a、libavfilter.a、libswresample.a、libavformat.a、libavutil.a、libswscale.a、libavdevice.a、libpostproc.a,并将它们打包生成最终的libffmpeg.so;根据自己的需要修改ndk版本和so生成的路径来修改build_android.sh中的内容:

#!/bin/bash
NDK=/data_ex/qcs/zjz/tools/android-ndk-r17c/
ISYSROOT=$NDK/sysroot
#修改点1
PLATFORM=$NDK/platforms/android-19/arch-arm
#修改点2:如果是Mac系统编译路径则是:xxx/darwin-x86_64/xxx
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
#修改点3:
PREFIX=../

function build_one
{
	./configure \
	 --prefix=$PREFIX \
	--target-os=android \
	--enable-cross-compile \
	--disable-doc \
	--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
	--arch=arm \
	--sysroot=$PLATFORM \
	--extra-cflags="-I$ISYSROOT/usr/include -isystem $ISYSROOT/usr/include/arm-linux-androideabi" \
	--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
	--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
	--enable-static \
	--disable-shared \
	--enable-runtime-cpudetect \
	--enable-gpl \
	--enable-small \
	--enable-ffplay \
	--enable-ffprobe \
	--enable-ffmpeg \
	--disable-debug \
	--disable-symver \
	--disable-stripping \
	--extra-cflags="-Os -pie -fPIE -fpic $ADDI_CFLAGS -U_FILE_OFFSET_BITS -D__ANDROID_API__=19" \
	--extra-ldflags="$ADDI_LDFLAGS" \
$ADDITIONAL_CONFIGURE_FLAG
 
make clean
make -j4
make install
 
$TOOLCHAIN/bin/arm-linux-androideabi-ld \
    -rpath-link=$PLATFORM/usr/lib \
    -L$PLATFORM/usr/lib \
    -L$PREFIX/lib \
    -soname libffmpeg.so -shared -nostdlib -Bsymbolic --whole-archive --no-undefined -o \
    $PREFIX/libffmpeg.so \
    libavcodec/libavcodec.a \
    libavfilter/libavfilter.a \
    libswresample/libswresample.a \
    libavformat/libavformat.a \
    libavutil/libavutil.a \
    libswscale/libswscale.a \
    libavdevice/libavdevice.a \
    libpostproc/libpostproc.a \
    -lc -lm -lz -ldl -llog --dynamic-linker=/system/bin/linker \
    $TOOLCHAIN/lib/gcc/arm-linux-androideabi/4.9.x/libgcc.a #修改点4: 4.8 or 4.9
	echo "编译结束!"
}
 
# arm v7vfp
echo "编译不支持neon和硬解码"
CPU=armv7-a
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
ADDI_CFLAGS="-marm"
build_one #build first task
 
echo "编译支持neon和硬解码"
CPU=armv7-a
PREFIX=./android/armv7-a-neon-hard
CFLAG="-I$INCLUDE -I$INCLUDE/arm-linux-androideabi -fPIC -DANDROID -mfpu=neon -mfloat-abi=softfp"
ADD="--enable-asm \
    --enable-neon \
    --enable-jni \
    --enable-mediacodec \
    --enable-decoder=h264_mediacodec \
    --enable-hwaccel=h264_mediacodec "
build_one #build second task

3.常见编译错误

1.报错一:format/udp.c:290 error: request for member ‘s_addr‘ in something not a structure or union

----试了ndk10-17版本,发现ndk 10-15版本会出现错误,换用高版本(最好是r17c)之后就不会报此问题

2.报错二:xxxxx/include/stdint.h:9:26: fatal error: stdint.h: No such file or directory

----出现这个错误是因为NDK r17c版本将头文件和库文件进行了分离,指定的sysroot文件夹下只有库文件,而头文件放在了NDK目录下的sysroot内. 在build_android.sh文件的–extra-cflags中添加 “-isysroot $NDK/sysroot”即可

3.报错三:libavcodec/aaccoder.c:803:25: error: expected identifier or ‘(’ before numeric constant int B0 = 0, B1 = 0;

----将里面的B0都改为其他变量(如b0)即可;后续其他文件也会报类似错误,都是把B0改为b0或其他变量

4.报错四:在编译完毕32位libffmpeg.so后,使用盒子无法加载动态库,报出dlopen("/data/app-lib/com.example.freeviewpoint_demo-2/libffmpeg.so") failed: dlopen failed: cannot locate symbol “mmap64” referenced by “libffmpeg.so”…

----这是因为盒子为Android4.4版本,对应android platform版本为19,而之前编译使用的是21

5.报错五(接报错四)修改build_android.sh中android platform版本为19后编译,报出libavcodec/v4l2_buffers.c:434:44: error: call to ‘mmap’ declared with attribute error: mmap is not available > with _FILE_OFFSET_BITS=64 when using GCC until android-21. Either raise your minSdkVersion, disable > _FILE_OFFSET_BITS=64, or switch to Clang.

----21版本以下,需要取消 _FILE_OFFSET_BITS宏定义。添加编译参数: -U_FILE_OFFSET_BITS

总结

编译ffmpeg竟然遇到这么多坑,也是服了,不过网上查了n多资料,加上自己试验总算编译成功。最后附上自己编译的32位libffmpeg.so链接:https://download.csdn.net/download/qq_31366471/15174217

参考链接

https://blog.csdn.net/u010164190/article/details/107581146

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在 Linux编译适用于 ARMv7a 架构的 FFmpeg,你需要先安装 ARMv7a 架构的交叉编译器,然后下载 FFmpeg 源代码并编译。 以下是具体步骤: 1. 安装 ARMv7a 架构的交叉编译器 在 Ubuntu 下,你可以使用以下命令安装: ``` sudo apt-get install gcc-arm-linux-gnueabihf ``` 如果你使用的是其他发行版的 Linux,你需要找到对应的包管理器来安装交叉编译器。 2. 下载 FFmpeg 源代码 你可以从 FFmpeg 的官网下载最新版本的源代码,也可以从 Git 仓库中获取。 ``` git clone https://git.ffmpeg.org/ffmpeg.git ``` 3. 配置编译选项 进入 FFmpeg 源代码目录,执行以下命令进行配置: ``` ./configure --arch=arm --target-os=linux --enable-gpl --enable-libx264 --enable-nonfree --enable-shared --enable-pic --cross-prefix=arm-linux-gnueabihf- --prefix=/usr/local/arm/ffmpeg --extra-cflags="-I/usr/local/arm/include" --extra-ldflags="-L/usr/local/arm/lib" ``` 解释一下各个参数的含义: - `--arch=arm`:指定目标架构为 ARM。 - `--target-os=linux`:指定目标操作系统为 Linux。 - `--enable-gpl`:开启 GPL 协议的组件。 - `--enable-libx264`:开启 x264 编码器。 - `--enable-nonfree`:开启非自由的组件。 - `--enable-shared`:生成共享库。 - `--enable-pic`:生成位置独立的代码。 - `--cross-prefix=arm-linux-gnueabihf-`:指定交叉编译器的前缀。 - `--prefix=/usr/local/arm/ffmpeg`:指定安装路径。 - `--extra-cflags="-I/usr/local/arm/include"`:指定头文件搜索路径。 - `--extra-ldflags="-L/usr/local/arm/lib"`:指定库文件搜索路径。 4. 编译和安装 执行以下命令进行编译: ``` make ``` 然后执行以下命令进行安装: ``` sudo make install ``` 安装完成后,你可以在 `/usr/local/arm/ffmpeg` 目录下找到编译好的 FFmpeg 库文件和可执行文件。 在编译 FFmpeg 的时候,你可以根据自己的需要添加或删除一些选项。如果你需要支持其他编解码器或协议,可以查看 FFmpeg 的文档,找到相应的选项。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值