背景
在去年7月发布的Android FFmpeg系列01--编译与集成一文中我们采用的是ndk r21d+FFmpeg5.0.1的版本,一年过去,FFmpeg也迭代到了6.0的版本
本篇文章的主要内容是使用最新的ndk r26来编译FFmpeg6.0,并更新到系列文章中的Demo工程中
编译
在FFmpeg官网上下载6.0的源码后,按照Android FFmpeg系列01--编译与集成和Android FFmpeg系列04--FFmpeg调用MediaCodec进行硬解码两篇文章里面的内容配置好configure和编译脚本sh文件
为什么不继续使用之前的ndk r21d版本?是因为编译时遇到了如下错误
android-ndk-r21d/toolchains/llvm/prebuilt/darwin-x86_64/sysroot/usr/include/media/NdkMediaCodec.h:448:9: error: must use 'struct' tag to refer
to type 'AMediaCodecOnAsyncNotifyCallback'
AMediaCodecOnAsyncNotifyCallback callback,
^
1 error generated.
FFmpeg6.0支持了NDKMediaCodec,编译出现上面的错误也挺符合预期的,所以我们直接改用最新的NDK r26版本(使用最新工具不出意外的必定是要踩坑的,我们根据错误提示一个一个修复就行)
第一个大问题是找不到对应abi的ar、nm、strip工具
查看NDK历史版本的变更记录后发现,从r22b版本开始都使用llvm-xx了
所以我们需要再次改造下configure文件
第二个问题是fatal error: 'vulkan_beta.h' file not found
因为我们暂时不关注Vulkan,所以编译的时候禁用该能力或者关掉vulkan beta extensions
--disable-vulkan \
--extra-cflags="-Os -fpic -DVK_ENABLE_BETA_EXTENSIONS=0 $OPTIMIZE_CFLAGS"
最后的编译脚本如下:
#!/bin/bash
#配置NDK路径
NDK=/Users/xyq/Desktop/tool/SDKandNDK/android-ndk-r26
#配置toolchain路径
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/darwin-x86_64
#配置交叉编译环境的根路径
SYSROOT=$TOOLCHAIN/sysroot
#NDK新版本使用llvm-ar, llvm-nm, llvm-strip等
CROSS_PREFIX_LLVM=$TOOLCHAIN/bin/llvm-
#arm64-v8a
API=30
ARCH=arm64
CPU=armv8-a
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
CROSS_PREFIX_CLANG="$TOOLCHAIN/bin/aarch64-linux-android$API"
OPTIMIZE_CFLAGS="-march=$CPU"
OUTPUT=/Users/xyq/Desktop/ffmpeg-demo-res/ffmpeg-6.0/android/$CPU
#armeabi-v7a
#API=30
#ARCH=arm
#CPU=armv7-a
#CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
#CROSS_PREFIX_CLANG="$TOOLCHAIN/bin/armv7a-linux-androideabi$API"
#OPTIMIZE_CFLAGS="-march=$CPU"
#OUTPUT=/Users/xyq/Desktop/ffmpeg-demo-res/ffmpeg-6.0/android/$CPU
fun build
{
./configure \
--prefix=$OUTPUT \
--target-os=android \
--arch=$ARCH \
--cpu=$CPU \
--enable-neon \
--enable-cross-compile \
--enable-shared \
--enable-jni \
--enable-mediacodec \
--enable-decoder=h264_mediacodec \
--enable-decoder=hevc_mediacodec \
--enable-decoder=mpeg4_mediacodec \
--disable-vulkan \
--disable-static \
--disable-asm \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--disable-symver \
--disable-ffmpeg \
--disable-avdevice \
--disable-debug \
--disable-postproc \
--sysroot=$SYSROOT \
--cross-prefix=$CROSS_PREFIX \
--cross_prefix_clang=$CROSS_PREFIX_CLANG- \
--cross_prefix_llvm=$CROSS_PREFIX_LLVM \
--extra-cflags="-Os -fpic -DVK_ENABLE_BETA_EXTENSIONS=0 $OPTIMIZE_CFLAGS"
make clean all
make -j24
make install
}
build
编译产物如下图所示,然后将Demo工程中的头文件和so文件替换掉就行
更新
之前的FFmpeg5.0.1的Demo工程在升级为6.0的版本后,不需要任何变更即可正常work
不过既然我们升级到6.0,总是要来点不一样用于演示一下
使用NDKMediaCodec解码: 流程和Android FFmpeg系列04--FFmpeg调用MediaCodec进行硬解码一致,只是不设置jvm给ffmpeg即可
新增av_dict_iterate接口用于遍历metadata