NDK编译ffmpeg6.0与x264的坑

ffmpeg6.0已经发布有一段时间了,近日特地上官网看了下新增了啥特性,不看不知道,一看果然有惊喜,居然支持直接调用NDK使用MediaCodec进行编解码了, 也就是说不用再通过JNI调用Java层的MediaCodec进行编解码了,性能应该会有一丢丢的提升吧。

看到这里笔者按耐不要想要试一试的欲望,三下五除二,NDK交叉编译起来开干。说到NDK交叉编译FFmpeg这个问题,真是老生常谈了, 在这之前我也记录过几篇编译的博文,详情见:

NDKr20使用clang编译ffmpeg4.2.2

NDK21编译ffmpeg5.0.1

本来正常编译ffmpeg,没有涉及到x264等第三方库的时候应该正常能编译的成功的,但是一般做音视频开发的都会接入x264作为软编码兜底。 笔者在FFmpeg6.0中尝试接入x264时居然发现编译失败了,无法编译成功...

先说说笔者的编译环境是M1芯片的Mac OS。

一个control c加一个control v我们的交叉编译脚本就写好了:

bash 复制代码
#!/bin/bash
#配置你的NDK路径
export NDK=/Users/fly/Documents/Android/SDK/ndk/21.1.6352462
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64

mkdir build
cd build

parentDir=$(dirname "$PWD")

function build_android
{
$parentDir/ffmpeg-6.0/configure \
--prefix=$PREFIX \
--disable-postproc \
--disable-debug \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-doc \
--disable-avdevice \
--disable-static \
--disable-avdevice \
--enable-gpl \
--enable-shared \
--enable-neon \
--enable-libx264 \
--enable-encoder=libx264 \
--enable-hwaccels \
--enable-jni \
--enable-small \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-decoder=hevc_mediacodec \
--enable-decoder=mpeg4_mediacodec \
--enable-hwaccel=h264_mediacodec \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS -I$X264_INCLUDE " \
--extra-ldflags="-L$X264_LIB $ADDI_LDFLAGS" \

make clean
make -j16
make install
}

#arm64-v8a 参数配置

X264_INCLUDE=$parentDir/buildx264/androidOut/armv8-a/include
X264_LIB=$parentDir/buildx264/androidOut/armv8-a/lib
ARCH=arm64
CPU=armv8-a
API=21
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/androidOut/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"

#清空上次的编译
make clean
# 函数调用
build_android

echo "============================build android ffmpeg arm64 end=========================="

#arm-v7a 参数配置

X264_INCLUDE=$parentDir/buildx264/androidOut/armv7a/include
X264_LIB=$parentDir/buildx264/androidOut/armv7a/lib

ARCH=arm
CPU=armv7a
API=21
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/androidOut/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"

#清空上次的编译
make clean
# 函数调用
build_android

echo "============================build android ffmpeg armv7a end=========================="

上面的脚本假设我们已经使用NDK成功编译好了X264,至于X264的交叉编译也不难,这里就不介绍了...

脚本跑起来,泡一杯咖啡静待编译结果,待我咖啡泡好一看,居然编译报错了:

arduino 复制代码
ERROR: x264 not found using pkg-config

我的天呐,这脚本之前笔者在ffmpeg5.0之前是能正常编译的,如今到了ffmpeg6.0居然报错了?

于是我拿出了杀手锏------百度、谷歌...

可恨,非常可恨,居然没能找到能直接copy的解决方案,在这里不得不责备一下各位技术大佬们,你们赶紧更新了,不然我都搜索不到答案了, 搜索不到答案,我堂堂CV工程师的工作如何开展下去?

要解决这个编译问题也不难,按照报错的信息,我们使用pkg-config配置一下x264的信息即可。

两步解决:

1.需要配置--pkg-config

给ffmpeg的编译脚本新增编译参数一个编译参数选项:

ini 复制代码
--pkg-config="pkg-config --static" 

2.设置PKG_CONFIG_PATH路径变量

bash 复制代码
// 以自己的电脑环境为准
export PKG_CONFIG_PATH=/Users/fly/Documents/work/pro/android-ffmpeg/buildx264/androidOut/armv8-a/lib/pkgconfig

于是我们完整的编译脚本是这样的:

bash 复制代码
#!/bin/bash
#配置你的NDK路径
export NDK=/Users/fly/Documents/Android/SDK/ndk/21.1.6352462
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64

mkdir build
cd build

parentDir=$(dirname "$PWD")

function build_android
{
$parentDir/ffmpeg-6.0/configure \
--prefix=$PREFIX \
--disable-postproc \
--disable-debug \
--disable-doc \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-doc \
--disable-avdevice \
--disable-static \
--disable-avdevice \
--enable-gpl \
--enable-shared \
--enable-neon \
--enable-libx264 \
--enable-encoder=libx264 \
--enable-hwaccels \
--enable-jni \
--enable-small \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-decoder=hevc_mediacodec \
--enable-decoder=mpeg4_mediacodec \
--enable-hwaccel=h264_mediacodec \
--cross-prefix=$CROSS_PREFIX \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--cc=$CC \
--cxx=$CXX \
--enable-cross-compile \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $OPTIMIZE_CFLAGS -I$X264_INCLUDE " \
--extra-ldflags="-L$X264_LIB $ADDI_LDFLAGS" \
--pkg-config="pkg-config --static" \

make clean
make -j16
make install
}

#arm64-v8a 参数配置

# 指定X264的库
export PKG_CONFIG_PATH=/Users/fly/Documents/work/pro/android-ffmpeg/buildx264/androidOut/armv8-a/lib/pkgconfig
X264_INCLUDE=$parentDir/buildx264/androidOut/armv8-a/include
X264_LIB=$parentDir/buildx264/androidOut/armv8-a/lib
ARCH=arm64
CPU=armv8-a
API=21
CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/androidOut/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"

echo "PKG_CONFIG_PATH:${PKG_CONFIG_PATH}"
#清空上次的编译
make clean
# 函数调用
build_android

echo "============================build android ffmpeg arm64 end=========================="

#arm-v7a 参数配置

# 指定X264的库
export PKG_CONFIG_PATH=/Users/fly/Documents/work/pro/android-ffmpeg/buildx264/androidOut/armv7a/lib/pkgconfig
echo "PKG_CONFIG_PATH:${PKG_CONFIG_PATH}"

X264_INCLUDE=$parentDir/buildx264/androidOut/armv7a/include
X264_LIB=$parentDir/buildx264/androidOut/armv7a/lib

ARCH=arm
CPU=armv7a
API=21
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/darwin-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/androidOut/$CPU
OPTIMIZE_CFLAGS="-march=$CPU"

#清空上次的编译
make clean
# 函数调用
build_android

echo "============================build android ffmpeg armv7a end=========================="

再次运行脚本即可成功编译,上一张笔者编译成功的目录图

编译成功后我们就可以将ffmpeg引入到工程中进行编码验证使用啦,引入可参考之前的博文:

将ffmpeg引入到Android Studio工程中

关注我,一起进步,人生不止coding!!!

相关推荐
Libraeking16 分钟前
破壁行动:在旧项目中丝滑嵌入 Compose(混合开发实战)
android·经验分享·android jetpack
市场部需要一个软件开发岗位1 小时前
JAVA开发常见安全问题:Cookie 中明文存储用户名、密码
android·java·安全
JMchen1233 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
crmscs3 小时前
剪映永久解锁版/电脑版永久会员VIP/安卓SVIP手机永久版下载
android·智能手机·电脑
localbob3 小时前
杀戮尖塔 v6 MOD整合版(Slay the Spire)安卓+PC端免安装中文版分享 卡牌肉鸽神作!杀戮尖塔中文版,电脑和手机都能玩!杀戮尖塔.exe 杀戮尖塔.apk
android·杀戮尖塔apk·杀戮尖塔exe·游戏分享
冬奇Lab3 小时前
一天一个开源项目(第16篇):Code2Video - 用代码生成高质量教学视频的智能框架
开源·aigc·音视频开发
机建狂魔3 小时前
手机秒变电影机:Blackmagic Camera + LUT滤镜包的专业级视频解决方案
android·拍照·摄影·lut滤镜·拍摄·摄像·录像
hudawei9963 小时前
flutter和Android动画的对比
android·flutter·动画
lxysbly5 小时前
md模拟器安卓版带金手指2026
android
儿歌八万首6 小时前
硬核春节:用 Compose 打造“赛博鞭炮”
android·kotlin·compose·春节