ffmpeg使用NDK编译时遇到的一些坑

跟着网络上的教程一步一步的走,编写编译脚本,然而总是出现错误,这里记录一下

一、提示头文件未找到

编译时报错:

In file included from libavfilter/aeval.c:26:0:
./libavutil/avassert.h:30:20: fatal error: stdlib.h: No such file or directory
 #include <stdlib.h>
                    ^

出现这个错误是因为使用最新版的NDK造成的,最新版的NDk将头文件和库文件进行了分离,我们指定的sysroot文件夹下只有库文件,而头文件放在了NDK目录下的sysroot内,只需在--extra-cflags中添加 "-isysroot $NDK/sysroot" 即可,还有有关汇编的头文件也进行了分离,需要根据目标平台进行指定 "-I$NDK/sysroot/usr/include/arm-linux-androideabi",将 "arm-linux-androideabi" 改为需要的平台就可以,终于可以顺利的进行编译了

二、在目标机无法运行

库文件终于编译出来了,但是在运行时又又又出现了问题,根本无法运行,开始以为是程序问题,但是发现程序在 Android 7.0 的机子上运行没有任何问题,但在目标机 Android 4.4 的机子上根本无法运行,Android studio 运行信息里提示加载动态库是出错,没有找到mmap64,找到了mmap64的头文件,发现只有 Android L 之后版本才支持 mmap64 


编译时我们没有定义 __ANDROID_API__ ,默认为 1000,同时 ffmpeg 的 configure 生成makefile 时定义了_FILE_OFFSET_BITS=64,所以,mmap 就被重命名为了 mmap64,在--extra-cflags中添加"-U_FILE_OFFSET_BITS"来取消_FILE_OFFSET_BITS的定义就行了


所以在编译时一定要定义__ANDROID_API__,这样才能保证编译的库文件可以在指定平台运行

三、脚本

放上自己的编译脚本,顺便提一句,将--target-os设为android,生成的库文件就不带版本号了,可以不用再去修改configure

#!/bin/bash
export TMPDIR=D:/ffmpeg-3.4.2/tmpdir
NDK=D:/Android/android-ndk-r16b
API=19
PLATFORM=arm-linux-androideabi
TOOLCHAIN=$NDK/toolchains/$PLATFORM-4.9/prebuilt/windows-x86_64
SYSROOT=$NDK/platforms/android-$API/arch-arm/
ISYSROOT=$NDK/sysroot
ASM=$ISYSROOT/usr/include/$PLATFORM
CPU=armv7-a
PREFIX=D:/ffmpeg-3.4.2/Android/$CPU

build_one()
{
./configure \
--prefix=$PREFIX \
--target-os=android \
--arch=arm \
--cpu=$CPU \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--disable-asm \
--enable-cross-compile \
--enable-shared \
--disable-static \
--enable-runtime-cpudetect \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--disable-doc \
--disable-symver \
--enable-small \
--enable-gpl --enable-nonfree --enable-version3 --disable-iconv \
--enable-jni \
--enable-mediacodec \
--disable-decoders --enable-decoder=vp9 --enable-decoder=h264 --enable-decoder=mpeg4 --enable-decoder=aac \
--disable-encoders --enable-encoder=vp9_vaapi --enable-encoder=h264_nvenc --enable-encoder=h264_v4l2m2m --enable-encoder=hevc_nvenc \
--disable-demuxers --enable-demuxer=rtsp --enable-demuxer=rtp --enable-demuxer=flv --enable-demuxer=h264 \
--disable-muxers --enable-muxer=rtsp --enable-muxer=rtp --enable-muxer=flv --enable-muxer=h264 \
--disable-parsers --enable-parser=mpeg4video --enable-parser=aac --enable-parser=h264 --enable-parser=vp9 \
--disable-protocols --enable-protocol=rtmp --enable-protocol=rtp --enable-protocol=tcp --enable-protocol=udp \
--disable-bsfs \
--disable-indevs --enable-indev=v4l2 \
--disable-outdevs \
--disable-filters \
--disable-postproc \
--sysroot=$SYSROOT \
--extra-cflags="-I$ASM -isysroot $ISYSROOT -D__ANDROID_API__=$API -U_FILE_OFFSET_BITS -Os -fPIC -DANDROID -D__thumb__ -mthumb -Wfatal-errors -Wno-deprecated -mfloat-abi=softfp -marm" \
--extra-ldflags="-marm"
$ADDITIONAL_CONFIGURE_FLAG
}
build_one
make clean
make -j4
make install

前几天ffmpeg 4.0出来,尝试编译了一下,在Android上无法运行,可能配置或者脚本还有些问题吧

最后来句题外话,NDK好像后续打算移除gcc,全面改为Clang,不知道有没有大神出一下Clang的脚本

阅读更多

没有更多推荐了,返回首页