温馨提示:这篇文章已超过473天没有更新,请注意相关的内容是否还可用!
摘要:,,本文介绍了在Android环境下使用.bp文件构建FFmpeg库的全过程。文章涵盖了从搭建编译框架到处理编译错误的步骤。通过详细的指导,帮助读者成功在Android平台上编译FFmpeg库,包括环境配置、源码获取、编译过程及遇到的错误处理。文章旨在为读者提供一个全面的指南,以顺利完成FFmpeg库的构建。
文章目录
- 前言
- 搭建编译框架
- 1. 创建 Android.bp 文件
- 2. 创建 avutil_files.bp
- 3. 创建其他 bp 文件
- armv8-a 编译参数
- 1. configure 源代码
- 2. 查看编译参数
- 3. 添加编译参数
- 4. 添加汇编参数
- 5. 添加链接参数
- 6. HAVE_AV_CONFIG_H 参数
- armv7-a 编译参数
- 1. 查看编译参数
- 2. 添加编译、汇编、链接参数
- 添加 armv8-a 源文件
- 1. 查找需编译的源文件
- 2. 添加 compat 源文件
- 3. 添加 libavutil 源文件
- 4. 添加其他模块源文件
- 添加 armv7-a 源文件
- 1. 重新编写 config.h 文件
- 2. 查找和添加源文件
- 编译错误处理
- 编译源代码
- 整体目录结构
- 源码仓库
- 参考资料
前言
本文基于 FFmpeg 5.1.4 版本,详细讲述了使用 Android.bp 构建 FFmpeg 库的过程,旨在简化 Android 源码中 FFmpeg 库的构建以及集成过程。
- 构建过程需使用 NDK 工具辅助,请参考该专栏之前文章:使用 NDK 编译 FFmpeg
- github 仓库:FFmpegDroidBuilder
搭建编译框架
以编译 libavutil、libavcodec、libavformat、libswresample、libswscale 模块为例,在 FFmpeg 源码根目录下,创建以下 7 个文件:
Android.bp
├── compat_files.bp
├── avutil_files.bp
├── avcodec_files.bp
├── avformat_files.bp
├── swresample_files.bp
└── swscale_files.bp
Android.bp 作为编译入口,定义整体编译架构,其余 6 个 bp 文件作为 Android.bp 的依赖项,声明 FFmpeg 各模块需编译的源文件:
- compat_files.bp 声明 compat 目录下需编译的源码文件,该目录中存在很多为兼容各种平台而创建的头文件
- 其他 bp 文件则分别声明 libavutil、libavcodec、libavformat、libswresample、libswscale 目录下需编译的源文件
1. 创建 Android.bp 文件
首先,搭建整体编译框架,后续章节再补充具体编译参数。
// 依赖项 build = [ "compat_files.bp", "avutil_files.bp", "avcodec_files.bp", "avformat_files.bp", "swresample_files.bp", "swscale_files.bp", ] // 编译选项默认值 cc_defaults { name: "libFFmpeg_defaults", cflags: [ ], arch: { arm: { cflags: [ ], asflags: [ ], }, arm64: { cflags: [ ], asflags: [ ], }, }, } cc_library { name: "libFFmpeg", defaults: ["libFFmpeg_defaults"], local_include_dirs: [ ], vendor_available: true, export_include_dirs: [ ".", ], // android 10 平台需设置该选项为 false 以停用 XOM // xom: false, // 默认同时编译 32 和 64 位的代码。若放开下列注释,则只编译 64 位的代码 // compile_multilib: "64", arch: { arm: { instruction_set: "arm", srcs: [ ":avutil-src-arm", ":avcodec-src-arm", ":swresample-src-arm", ":swrscale-src-arm", ], // ARM 架构编译选项 cflags: [ ], // ARM 架构链接选项 ldflags: [ ], // ARM 架构汇编选项 asflags: [ ] }, arm64: { srcs: [ ":avutil-src-arm64", ":avcodec-src-arm64", ":swresample-src-arm64", ":swrscale-src-arm64", ], // ARM64 架构编译选项 cflags: [ ], // ARM64 架构链接选项 ldflags: [ ], // ARM64 架构汇编选项 asflags: [ ], }, }, srcs: [ ":compat-src", ":avutil-src-common", ":avcodec-src-common", ":swresample-src-common", ":swrscale-src-common", ":avformat-src", ], shared_libs: [ ], static_libs: [ ], // 全局编译选项 cflags: [ ], // 全局链接选项 ldflags: [ ], // 全局汇编选项 asflags: [ ], }
XOM 官当说明:AArch64 二进制文件的只执行内存 (XOM)
Android.bp 中定义的模块间依赖关系如下:
Android.bp
└── libFFmpeg
├── libFFmpeg_defaults
│
├── compat-src
│
├── avutil-src-common
├── avutil-src-arm
├── avutil-src-arm64
│
├── avcodec-src-common
├── avcodec-src-arm
├── avcodec-src-arm64
│
├── swresample-src-common
├── swresample-src-arm
├── swresample-src-arm64
│
├── swrscale-src-common
├── swrscale-src-arm
├── swrscale-src-arm64
│
└── avformat-src
2. 创建 avutil_files.bp
声明 avutil-src-arm、avutil-src-arm64、avutil-src-common 模块,后续章节再补充这些模块所依赖的源文件。
filegroup { name: "avutil-src-arm", // ARM 架构代码 srcs: [ ], } filegroup { name: "avutil-src-arm64", // ARM64 架构代码 srcs: [ ], } filegroup { name: "avutil-src-common", // 多平台共用代码 srcs: [ ], }
3. 创建其他 bp 文件
参考 avutil_files.bp,创建 compat_files.bp、avcodec_files.bp、avformat_files.bp、swresample_files.bp、swscale_files.bp 文件,并添加相应的模块声明。
- compat_files.bp
filegroup { name: "compat-src", // 无需区分 ARM 和 ARM64 架构 srcs: [ ], }
- avcodec_files.bp
filegroup { name: "avcodec-src-arm", // ARM 架构代码 srcs: [ ], } filegroup { name: "avcodec-src-arm64", // ARM64 架构代码 srcs: [ ], } filegroup { name: "avcodec-src-common", // 多平台共用代码 srcs: [ ], }
- avformat_files.bp
filegroup { name: "avformat-src", srcs: [ ] }
- swresample_files.bp
filegroup { name: "swresample-src-arm", // ARM 架构代码 srcs: [ ], } filegroup { name: "swresample-src-arm64", // ARM64 架构代码 srcs: [ ], } filegroup { name: "swresample-src-common", // 多平台共用代码 srcs: [ ], }
- swscale_files.bp
filegroup { name: "swrscale-src-arm", // ARM 架构代码 srcs: [ ], } filegroup { name: "swrscale-src-arm64", // ARM64 架构代码 srcs: [ ], } filegroup { name: "swrscale-src-common", // 多平台共用代码 srcs: [ ], }
armv8-a 编译参数
1. configure 源代码
cpu 架构配置为 armv8-a,参考专栏之前的文章:使用 NDK 编译 FFmpeg。
2. 查看编译参数
configure 指令执行完成后,在生成的 ffbuild/config.mak 文件中,可查看编译过程各阶段所需参数:
CPPFLAGS:预处理标志
CFLAGS:C编译标志
CXXFLAGS:C++编译标志
ASFLAGS:汇编标志
LDFLAGS:链接标志
LDEXEFLAGS:用于链接可执行文件的标志
3. 添加编译参数
前一小节 CPPFLAGS、CFLAGS、CXXFLAGS 中的 flags 可分为以下两类:
- cpu 特定 flags:如 -mfpu=neon、-march=armv8-a
- 多平台共用 flags:如 -fPIC、-fPIE
FFmpeg 源码根目录下,执行 vim find_flags.sh 编辑脚本文件,用于查找 ffbuild/config.mak 中的编译参数:
#!/bin/bash #if [ "$#" -ne 1 ]; then # echo "Usage: config_file" # exit 1 #fi # 获取配置文件 #config_file= config_file=ffbuild/config.mak # 定义需要查找的变量 vars=("CPPFLAGS" "CFLAGS" "CXXFLAGS" "ASFLAGS" "LDFLAGS") # 定义需打印的 cpu 特定参数 cpu_specific_prefixes=("-mfpu" "-march") # 定义需要过滤的标志 filter_prefixes=("CPPFLAGS" "CFLAGS" "CXXFLAGS" "ASFLAGS" "LDFLAGS" "--sysroot" "-mfpu" "-march" "-Wl,-rpath-link") print_flags() { # 将参数转换为数组 local -a local_filter_prefixes="($(echo ""))" local local_should_print= local var_prefix= for var in "${vars[@]}"; do flags=$(grep "^$var" "$config_file") # 分割参数 IFS=' ' read -r -a flagarray "-D_FILE_OFFSET_BITS=64", "-D_ISOC99_SOURCE", "-D_LARGEFILE_SOURCE", "-DPIC", "-Dstrtod=avpriv_strtod", "-DZLIB_CONST", } common_CFLAGS: { "-fno-math-errno", "-fno-signed-zeros", "-fomit-frame-pointer", "-fpic", "-fPIC", "-fPIE", "-g", "-mno-stackrealign", "-mstack-alignment=16", "-Os", "-Oz", "-pthread", "-Qunused-arguments", "-std=c11", "-Wall", "-Wdeclaration-after-statement", "-Wdisabled-optimization", "-Wempty-body", "-Werror=implicit-function-declaration", "-Werror=missing-prototypes", "-Werror=return-type", "-Wmissing-prototypes", "-Wno-bool-operation", "-Wno-char-subscripts", "-Wno-format-zero-length", "-Wno-parentheses", "-Wno-pointer-sign", "-Wno-switch", "-Wno-unused-const-variable", "-Wpointer-arith", "-Wredundant-decls", "-Wstrict-prototypes", "-Wtype-limits", "-Wundef", "-Wwrite-strings", } common_CXXFLAGS: { "-D__STDC_CONSTANT_MACROS", "-std=c++11", } common_ASFLAGS: { "-fpic", "-fPIC", "-g", "-mno-stackrealign", "-Os", "-Qunused-arguments", } common_LDFLAGS: { "-Qunused-arguments", "-Wl,--as-needed", "-Wl,--warn-common", "-Wl,-z,noexecstack", } cpu_specific_CPPFLAGS: { } cpu_specific_CFLAGS: { "-march=armv8-a", "-mfpu=neon", } cpu_specific_CXXFLAGS: { } cpu_specific_ASFLAGS: { "-march=armv8-a", "-mfpu=neon", } cpu_specific_LDFLAGS: { "-march=armv8-a", } name: "libFFmpeg", ... 省略部分代码 arch: { arm: { ... 省略部分代码 }, arm64: { srcs: [ ":avutil-src-arm64", ":avcodec-src-arm64", ":swresample-src-arm64", ":swrscale-src-arm64", ], // ARM64 架构编译选项 cflags: [ "-mfpu=neon", "-march=armv8-a", ], // ARM64 架构链接选项 ldflags: [ ], // ARM64 架构汇编选项 asflags: [ ], }, }, ... 省略部分代码 srcs: [ ":compat-src", ":avutil-src-common", ":avcodec-src-common", ":swresample-src-common", ":swrscale-src-common", ":avformat-src", ], // 全局编译选项 cflags: [ // CPPFLAGS "-D_FILE_OFFSET_BITS=64", "-D_ISOC99_SOURCE", "-D_LARGEFILE_SOURCE", "-DPIC", "-Dstrtod=avpriv_strtod", "-DZLIB_CONST", // CFLAGS "-fno-math-errno", "-fno-signed-zeros", "-fomit-frame-pointer", "-fpic", "-fPIC", "-fPIE", "-g", "-mno-stackrealign", "-mstack-alignment=16", "-Os", "-Oz", "-pthread", "-Qunused-arguments", "-std=c11", "-Wall", "-Wdeclaration-after-statement", "-Wdisabled-optimization", "-Wempty-body", "-Werror=implicit-function-declaration", "-Werror=missing-prototypes", "-Werror=return-type", "-Wmissing-prototypes", "-Wno-bool-operation", "-Wno-char-subscripts", "-Wno-format-zero-length", "-Wno-parentheses", "-Wno-pointer-sign", "-Wno-switch", "-Wno-unused-const-variable", "-Wpointer-arith", "-Wredundant-decls", "-Wstrict-prototypes", "-Wtype-limits", "-Wundef", "-Wwrite-strings", // CXXFLAGS "-D__STDC_CONSTANT_MACROS", "-std=c++11", ], // 全局链接选项 ldflags: [ ], // 全局汇编选项 asflags: [ ], } name: "libFFmpeg", ... 省略部分代码 arch: { arm: { ... 省略部分代码 }, arm64: { ... 省略部分代码 // ARM64 架构链接选项 ldflags: [ ], // ARM64 架构汇编选项 asflags: [ "-march=armv8-a", "-mfpu=neon", ], }, }, ... 省略部分代码 // 全局链接选项 ldflags: [ ], // 全局汇编选项 asflags: [ "-fpic", "-fPIC", "-g", "-mno-stackrealign", "-Os", "-Qunused-arguments", ], } name: "libFFmpeg", ... 省略部分代码 arch: { arm: { ... 省略部分代码 }, arm64: { ... 省略部分代码 // ARM64 架构汇编选项 ldflags: [ "-march=armv8-a", ], ... 省略部分代码 }, }, ... 省略部分代码 // 全局链接选项 ldflags: [ "-Qunused-arguments", "-Wl,--as-needed", "-Wl,--warn-common", "-Wl,-z,noexecstack", ], ... 省略部分代码 } name: "libFFmpeg_defaults", cflags: [ "-DHAVE_AV_CONFIG_H", ], ... 省略部分代码 } name: "libFFmpeg", ... 省略部分代码 arch: { arm: { instruction_set: "arm", ... 省略部分代码 // ARM 架构编译选项 cflags: [ "-marm", "-mfloat-abi=softfp", "-march=armv7-a", "-mfpu=neon", ], // ARM 架构链接选项 ldflags: [ "-march=armv7-a", ], // ARM 架构汇编选项 asflags: [ "-mfloat-abi=softfp", "-march=armv7-a", "-mfpu=neon", ] }, }, ... 省略部分代码 } local dir= local f=`ls $dir/*.o 2/dev/null` echo "$dir: {" for d in $f do local s=${d//.o/.c} if [ -f "$s" ]; then echo " \"${d//.o/.c}\"," else echo " \"${d//.o/.S}\"," fi done echo "}" } # 遍历每个参数并查找源文件 for dir in "$@"; do echo "Source files in $dir:" findSrc $dir done "compat/strtod.c", } "libavutil/adler32.c", "libavutil/aes_ctr.c", "libavutil/aes.c", "libavutil/audio_fifo.c", "libavutil/avsscanf.c", "libavutil/avstring.c", "libavutil/base64.c", "libavutil/blowfish.c", "libavutil/bprint.c", "libavutil/buffer.c", "libavutil/camellia.c", "libavutil/cast5.c", "libavutil/channel_layout.c", "libavutil/color_utils.c", "libavutil/cpu.c", "libavutil/crc.c", "libavutil/csp.c", "libavutil/des.c", "libavutil/detection_bbox.c", "libavutil/dict.c", "libavutil/display.c", "libavutil/dovi_meta.c", "libavutil/downmix_info.c", "libavutil/encryption_info.c", "libavutil/error.c", "libavutil/eval.c", "libavutil/fifo.c", "libavutil/file.c", "libavutil/file_open.c", "libavutil/film_grain_params.c", "libavutil/fixed_dsp.c", "libavutil/float_dsp.c", "libavutil/frame.c", "libavutil/hash.c", "libavutil/hdr_dynamic_metadata.c", "libavutil/hdr_dynamic_vivid_metadata.c", "libavutil/hmac.c", "libavutil/hwcontext.c", "libavutil/hwcontext_stub.c", "libavutil/imgutils.c", "libavutil/integer.c", "libavutil/intmath.c", "libavutil/lfg.c", "libavutil/lls.c", "libavutil/log2_tab.c", "libavutil/log.c", "libavutil/lzo.c", "libavutil/mastering_display_metadata.c", "libavutil/mathematics.c", "libavutil/md5.c", "libavutil/mem.c", "libavutil/murmur3.c", "libavutil/opt.c", "libavutil/parseutils.c", "libavutil/pixdesc.c", "libavutil/pixelutils.c", "libavutil/random_seed.c", "libavutil/rational.c", "libavutil/rc4.c", "libavutil/reverse.c", "libavutil/ripemd.c", "libavutil/samplefmt.c", "libavutil/sha512.c", "libavutil/sha.c", "libavutil/slicethread.c", "libavutil/spherical.c", "libavutil/stereo3d.c", "libavutil/tea.c", "libavutil/threadmessage.c", "libavutil/timecode.c", "libavutil/time.c", "libavutil/tree.c", "libavutil/twofish.c", "libavutil/tx_double.c", "libavutil/tx_float.c", "libavutil/tx_int32.c", "libavutil/tx.c", "libavutil/utils.c", "libavutil/uuid.c", "libavutil/version.c", "libavutil/video_enc_params.c", "libavutil/xga_font_data.c", "libavutil/xtea.c", } Source files in libavutil/aarch64: libavutil/aarch64: { "libavutil/aarch64/cpu.c", "libavutil/aarch64/float_dsp_init.c", "libavutil/aarch64/float_dsp_neon.S", } name: "compat-src", srcs: [ "compat/strtod.c", ], } name: "avutil-src-arm", // ARM 架构代码 srcs: [ ], } filegroup { name: "avutil-src-arm64", // ARM64 架构代码 srcs: [ "libavutil/aarch64/cpu.c", "libavutil/aarch64/float_dsp_init.c", "libavutil/aarch64/float_dsp_neon.S", ], } filegroup { name: "avutil-src-common", // 多平台共用代码 srcs: [ "libavutil/adler32.c", "libavutil/aes_ctr.c", "libavutil/aes.c", "libavutil/audio_fifo.c", "libavutil/avsscanf.c", "libavutil/avstring.c", "libavutil/base64.c", "libavutil/blowfish.c", "libavutil/bprint.c", "libavutil/buffer.c", "libavutil/camellia.c", "libavutil/cast5.c", "libavutil/channel_layout.c", "libavutil/color_utils.c", "libavutil/cpu.c", "libavutil/crc.c", "libavutil/csp.c", "libavutil/des.c", "libavutil/detection_bbox.c", "libavutil/dict.c", "libavutil/display.c", "libavutil/dovi_meta.c", "libavutil/downmix_info.c", "libavutil/encryption_info.c", "libavutil/error.c", "libavutil/eval.c", "libavutil/fifo.c", "libavutil/file.c", "libavutil/file_open.c", "libavutil/film_grain_params.c", "libavutil/fixed_dsp.c", "libavutil/float_dsp.c", "libavutil/frame.c", "libavutil/hash.c", "libavutil/hdr_dynamic_metadata.c", "libavutil/hdr_dynamic_vivid_metadata.c", "libavutil/hmac.c", "libavutil/hwcontext.c", "libavutil/hwcontext_stub.c", "libavutil/imgutils.c", "libavutil/integer.c", "libavutil/intmath.c", "libavutil/lfg.c", "libavutil/lls.c", "libavutil/log2_tab.c", "libavutil/log.c", "libavutil/lzo.c", "libavutil/mastering_display_metadata.c", "libavutil/mathematics.c", "libavutil/md5.c", "libavutil/mem.c", "libavutil/murmur3.c", "libavutil/opt.c", "libavutil/parseutils.c", "libavutil/pixdesc.c", "libavutil/pixelutils.c", "libavutil/random_seed.c", "libavutil/rational.c", "libavutil/rc4.c", "libavutil/reverse.c", "libavutil/ripemd.c", "libavutil/samplefmt.c", "libavutil/sha512.c", "libavutil/sha.c", "libavutil/slicethread.c", "libavutil/spherical.c", "libavutil/stereo3d.c", "libavutil/tea.c", "libavutil/threadmessage.c", "libavutil/timecode.c", "libavutil/time.c", "libavutil/tree.c", "libavutil/twofish.c", "libavutil/tx_double.c", "libavutil/tx_float.c", "libavutil/tx_int32.c", "libavutil/tx.c", "libavutil/utils.c", "libavutil/uuid.c", "libavutil/version.c", "libavutil/video_enc_params.c", "libavutil/xga_font_data.c", "libavutil/xtea.c", ], } name: "libFFmpeg_defaults", cflags: [ "-DHAVE_AV_CONFIG_H", ], arch: { arm: { cflags: [ "-DARCH_ARM=1", "-DARCH_AARCH64=0", ], asflags: [ "-DARCH_ARM=1", "-DARCH_AARCH64=0", ], }, arm64: { cflags: [ "-DARCH_AARCH64=1", "-DARCH_ARM=0", ], asflags: [ "-DARCH_AARCH64=1", "-DARCH_ARM=0", ], }, }, } "libavutil/arm/cpu.c", "libavutil/arm/float_dsp_init_arm.c", "libavutil/arm/float_dsp_init_neon.c", "libavutil/arm/float_dsp_init_vfp.c", "libavutil/arm/float_dsp_neon.S", "libavutil/arm/float_dsp_vfp.S", } name: "avutil-src-arm", // ARM 架构代码 srcs: [ "libavutil/arm/cpu.c", "libavutil/arm/float_dsp_init_arm.c", "libavutil/arm/float_dsp_init_neon.c", "libavutil/arm/float_dsp_init_vfp.c", "libavutil/arm/float_dsp_neon.S", "libavutil/arm/float_dsp_vfp.S", ], }
- swscale_files.bp
- swresample_files.bp
- avformat_files.bp
- avcodec_files.bp
- compat_files.bp
还没有评论,来说两句吧...