最近在根据项目需求疯狂撸 OpenCL ,FFmpeg 相关的文章落下了不少,后面也准备介绍下 OpenCL 在 Android 上的应用,另外 OpenCL 可以和 OpenGL 结合使用,非常有趣。
前面系列文章已经讲过使用 FFmpeg 对音频和视频进行解码以及视频添加滤镜渲染,接下来文章将会介绍音频和视频编码相关,包括为视频添加好玩的滤镜、音频添加搞笑的变声效果。
关于 x264、fdk-aac、FFmpeg 开源库的编译介绍网上“满大街”都是的,可参考资料很多。本文只是采用高一些的 NDK 版本,使用 clang 编译,以防止后面二次开发时出现编译问题。
编译环境
按照套路先说明编译环境:
- android-ndk-r20b-linux-x86_64
- ffmpeg-4.2.2
- libfdk-aac version:0.1.5
- x264
编译 fdk-aac
fdk-aac 是指:Fraunhofer FDK AAC 编解码器库,是一个开源软件库,用于编码和解码高级音频编码格式 AAC 的音频。
在 fdk-aac 解压目录下创建编译脚本build_fdk_aac_clang.sh
:
#!/bin/bash
NDK=/root/workspace/android-ndk-r20b # 这里需要替换成你本地的 NDK 路径,其他的不用修改
HOST_TAG=linux-x86_64
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/$HOST_TAG
ANDROID_LIB_PATH="$(pwd)/android"
API=21
function build_android
{
echo "Build fdk-aac for android $CPU"
./configure
--host=$HOST
--disable-shared
--enable-static
--prefix="$ANDROID_LIB_PATH/$CPU"
CPPFLAGS="-fPIC"
make clean
make -j8
make install
echo "Build fdk-aac for android $CPU completed"
}
# armeabi-v7a
CPU=armv7-a
HOST=arm-linux-android
export AR=$TOOLCHAIN/bin/arm-linux-androideabi-ar
export AS=$TOOLCHAIN/bin/arm-linux-androideabi-as
export LD=$TOOLCHAIN/bin/arm-linux-androideabi-ld
export RANLIB=$TOOLCHAIN/bin/arm-linux-androideabi-ranlib
export STRIP=$TOOLCHAIN/bin/arm-linux-androideabi-strip
export CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
export CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
build_android
# arm64-v8a
CPU=armv8-a
HOST=aarch64-linux-android
export AR=$TOOLCHAIN/bin/aarch64-linux-android-ar
export AS=$TOOLCHAIN/bin/aarch64-linux-android-as
export LD=$TOOLCHAIN/bin/aarch64-linux-android-ld
export RANLIB=$TOOLCHAIN/bin/aarch64-linux-android-ranlib
export STRIP=$TOOLCHAIN/bin/aarch64-linux-android-strip
export CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
export CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
build_android
修改编译脚本的权限,执行编译:
# 修改 build_fdk_aac_clang.sh 可执行权限
chmod +x build_fdk_aac_clang.sh
# 运行编译脚本
bash build_fdk_aac_clang.sh
编译完成后会在当前目录下自动创建 android 文件夹,并生成 32 & 64 位 libfdk-aac.a 库。
-fdk-aac-0.1.5
---android
-----lib/armeabi-v7a
-------libfdk-aac.a
-----lib/arm64-v8a
-------libfdk-aac.a
编译 x264
x264 是采用 GPL 授权的开源视频编码库,主要用于 H.264/MPEG-4 AVC 的视频编码,仅作为编码器使用。
在 x264 解压目录下创建编译脚本build_x264_clang.sh
:
#!/bin/bash
export NDK=/root/workspace/android-ndk-r20b # 这里需要替换成你本地的 NDK 路径,其他的不用修改
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
export API=21
function build_android
{
./configure
--prefix=$PREFIX
--disable-cli
--disable-shared
--enable-static
--enable-pic
--host=$my_host
--cross-prefix=$CROSS_PREFIX
--sysroot=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
make clean
make -j8
make install
}
#arm64-v8a
PREFIX=./android/arm64-v8a
my_host=aarch64-linux-android
export TARGET=aarch64-linux-android
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
build_android
#armeabi-v7a
PREFIX=./android/armeabi-v7a
my_host=armv7a-linux-android
export TARGET=armv7a-linux-androideabi
export CC=$TOOLCHAIN/bin/$TARGET$API-clang
export CXX=$TOOLCHAIN/bin/$TARGET$API-clang++
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
build_android
同样修改编译脚本的权限,执行编译:
# 修改 build_x264_clang.sh 可执行权限
chmod +x build_x264_clang.sh
# 运行编译脚本
bash build_x264_clang.sh
编译完成后会在当前目录下自动创建 android 文件夹,并生成 32 & 64 位 libx264.a 库。
-x264
---android
-----lib/armeabi-v7a
-------libx264.a
-----lib/arm64-v8a
-------libx264.a
编译 FFmpeg 链接 fdk-aac 和 x264
本节直接介绍编译 FFmpeg 时链接 fdk-aac 和 x264 库。
Android 平台,一般我们要链接第三方库的时候,需要第三方库的头文件和相应的 .a 或 .so 库。前面我们已经对 fdk-aac 和 x264 库进行了编译,可以获取到它们对应的静态库和头文件。
FFmpeg 、fdk-aac 和 x264 目录结构:
在 FFmpeg-4.2.2 解压目录下,新建编译 FFmpeg 并链接 fdk-aac 和 x264 脚本 build_ffmpeg_link_fdk_aac_x264_clang.sh:
#!/bin/bash
export NDK=/root/workspace/android-ndk-r20b # 这里需要替换成你本地的 NDK 路径,其他的不用修改
TOOLCHAIN=$NDK/toolchains/llvm/prebuilt/linux-x86_64
function build_android
{
./configure
--prefix=$PREFIX
--enable-neon
--enable-hwaccels
--enable-gpl
--disable-postproc
--enable-static
--enable-shared
--disable-debug
--enable-small
--enable-jni
--enable-mediacodec
--disable-doc
--enable-ffmpeg
--disable-ffplay
--disable-ffprobe
--disable-avdevice
--disable-doc
--disable-symver
--enable-libx264
--enable-libfdk-aac
--enable-encoder=libx264
--enable-encoder=libfdk-aac
--enable-nonfree
--enable-muxers
--enable-decoders
--enable-demuxers
--enable-parsers
--enable-protocols
--cross-prefix=$CROSS_PREFIX
--target-os=android
--arch=$ARCH
--cpu=$CPU
--cc=$CC
--cxx=$CXX
--enable-cross-compile
--sysroot=$SYSROOT
--extra-cflags="-I$X264_INCLUDE -I$FDK_INCLUDE -Os -fpic $OPTIMIZE_CFLAGS"
--extra-ldflags="-lm -L$FDK_LIB -L$X264_LIB $ADDI_LDFLAGS"
make clean
make -j8
make install
echo "The Compilation of FFmpeg with x264,fdk-aac for $CPU is completed"
}
#armv8-a
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/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/aarch64-linux-android-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
BASE_PATH=/root/workspace
LIB_TARGET_ABI=arm64-v8a
#指定 fdk-aac 的头文件和静态库目录
FDK_INCLUDE=$BASE_PATH/fdk-aac-0.1.5/android/$LIB_TARGET_ABI/include
FDK_LIB=$BASE_PATH/fdk-aac-0.1.5/android/$LIB_TARGET_ABI/lib
#指定 x264 的头文件和静态库目录
X264_INCLUDE=$BASE_PATH/x264/android/$LIB_TARGET_ABI/include
X264_LIB=$BASE_PATH/x264/android/$LIB_TARGET_ABI/lib
build_android
cp $FDK_LIB/libfdk-aac.a $PREFIX/lib
cp $X264_LIB/libx264.a $PREFIX/lib
#armv7-a
ARCH=arm
CPU=armv7-a
API=21
CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
SYSROOT=$NDK/toolchains/llvm/prebuilt/linux-x86_64/sysroot
CROSS_PREFIX=$TOOLCHAIN/bin/arm-linux-androideabi-
PREFIX=$(pwd)/android/$CPU
OPTIMIZE_CFLAGS="-mfloat-abi=softfp -mfpu=vfp -marm -march=$CPU "
BASE_PATH=/root/workspace
LIB_TARGET_ABI=armeabi-v7a
FDK_INCLUDE=$BASE_PATH/fdk-aac-0.1.5/android/$LIB_TARGET_ABI/include
FDK_LIB=$BASE_PATH/fdk-aac-0.1.5/android/$LIB_TARGET_ABI/lib
X264_INCLUDE=$BASE_PATH/x264/android/$LIB_TARGET_ABI/include
X264_LIB=$BASE_PATH/x264/android/$LIB_TARGET_ABI/lib
build_android
cp $FDK_LIB/libfdk-aac.a $PREFIX/lib
cp $X264_LIB/libx264.a $PREFIX/lib
里面有几个关键的地方需要注意下:
# 打开2种编码器的开关
--enable-libx264
--enable-libfdk-aac
--enable-encoder=libx264
--enable-encoder=libfdk-aac
......
#指定第三方库的头文件和静态库目录
--extra-cflags="-I$X264_INCLUDE -I$FDK_INCLUDE -Os -fpic $OPTIMIZE_CFLAGS"
--extra-ldflags="-lm -L$FDK_LIB -L$X264_LIB $ADDI_LDFLAGS"
另外还需要链接标准数学库:
--extra-ldflags="-lm -L$FDK_LIB -L$X264_LIB $ADDI_LDFLAGS" # -lm 即是链接数学库
因为 FFmpeg 链接的 fdk-aac 需要用到数学库,不链接的话会报如下错误:
这里又引出来一个问题,那么一般 FFmpeg 编译错误如何查看?
答案是查看 ffbuild 文件夹下面的 config.log 文件,可以直接跳到文件结尾看报错信息。
最后通过查看编译成功后 FFmpeg 库的编译配置信息,查看我们的编译是否成功,本文通过程序将 FFmpeg 的编译配置信息打印出来了。
进技术交流群,添加我的微信:Byte-Flow
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/18062.html