Android NDK 编译 FFmpeg:从下载源码到生成库的全过程

2024-05-30 1479阅读

文章目录

  • 准备工作
    • 1. 准备 Linux 环境
    • 2. 下载 FFmpeg 源码
    • 3. 下载 ndk 工具
    • 4. 配置系统环境变量
    • 编译 FFmpeg 源码
      • 1. 编译选项简介
      • 2. 编写编译脚本
      • 3. 脚本使用说明
      • 参考资料

        准备工作

        1. 准备 Linux 环境

        搭建 Linux 环境,网上已有很多的教程。本文使用的是 WSL2(Windows Subsystem for Linux) 环境,感兴趣的读者可在最后一章参考资料中了解更多信息。

        2. 下载 FFmpeg 源码

        • 下载地址:https://ffmpeg.org/download.html#releases
        • 下载 5.1.4 版本:wget https://ffmpeg.org/releases/ffmpeg-5.1.4.tar.xz
        • 解压缩:tar -xvf ffmpeg-5.1.4.tar.xz

          3. 下载 ndk 工具

          • 下载地址:https://developer.android.com/ndk/downloads?hl=zh-cn
          • 下载 ndk r26c 版本
          • 解压缩:unzip android-ndk-r26c-linux.zip

            4. 配置系统环境变量

            • 拷贝解压后的 android-ndk-r26c-linux 目录到 ~/ndk 路径下
            • 命令行输入 vim ~/.bashrc 编辑 bashrc 文件
            • 在 bashrc 文件末尾追加以下内容后保存并退出:
              export NDK_PATH=~/ndk/android-ndk-r26c
              export PATH=$NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64/bin/:$PATH
              
              • 命令行输入 source ~/.bashrc

                编译 FFmpeg 源码

                1. 编译选项简介

                FFmpeg 源码使用 configure 脚本进行编译前配置,使用 ./configure --help 可以查看支持的编译配置选项。

                标准选项: 这些选项用于配置基本的编译和安装参数。例如,–prefix=PREFIX 选项用于指定安装路径。

                授权选项: 这些选项用于控制 FFmpeg 的许可证。例如,–enable-gpl 选项允许使用 GPL 许可的代码。

                编译和连接选项: 这些选项用于控制 FFmpeg 的编译配置。例如,–disable-static 选项用于禁用静态库的构建,–enable-shared 选项用于启用动态库的构建。

                可执行程序控制选项: 这些选项用于控制是否构建特定的程序。例如,–disable-ffmpeg 选项用于禁用 ffmpeg 程序的构建。

                文档选项: 这些选项用于控制是否构建文档。例如,–disable-doc 选项用于禁用文 档的构建。

                组件控制选项: 这些选项用于控制是否构建特定的组件。例如,–disable-avdevice。

                2. 编写编译脚本

                新版 ndk 已放弃 gcc,转而使用更高效的 clang,下述脚本以 clang 为例编译 FFmpeg 源码。

                 #!/bin/bash
                 # NDK目录
                 TOOLCHAIN=$NDK_PATH/toolchains/llvm/prebuilt/linux-x86_64
                 # 最低支持的android sdk版本
                 API=21
                 function build_android
                 {
                 echo "Compiling FFmpeg for $CPU"
                 ./configure \
                  --prefix=$PREFIX \
                  --enable-neon \
                  --enable-shared \
                  --enable-small \
                  --disable-vulkan \
                  --disable-gpl \
                  --disable-postproc \
                  --disable-jni \
                  --disable-mediacodec \
                  --disable-decoder=h264_mediacodec \
                  --disable-static \
                  --disable-doc \
                  --disable-programs \
                  --disable-ffmpeg \
                  --disable-ffplay \
                  --disable-ffprobe \
                  --disable-avdevice \
                  --disable-symver \
                  --enable-cross-compile \
                  --cross-prefix=$CROSS_PREFIX \
                  --target-os=android \
                  --arch=$ARCH \
                  --cpu=$CPU \
                  --cc=$CC \
                  --cxx=$CXX \
                  --sysroot=$SYSROOT \
                  --extra-cflags="-mno-stackrealign -Os -fpic -mfpu=neon $OPTIMIZE_CFLAGS" \
                  --extra-ldflags="$ADDI_LDFLAGS"
                  #--disable-debug
                  #--disable-stripping
                  #--disable-linux-perf
                  #--disable-hwaccels
                 make clean
                 make -j4
                 make install
                 echo "The Compilation of FFmpeg for $CPU is completed"
                 }
                 function print_supported_cpus
                 {
                     echo "Supports the following CPUs:"
                     echo "1. armv7-a"
                     echo "2. armv8-a"
                 }
                 function print_usage
                 {
                     echo "Usage: $0 [CPU]"
                     echo "Example: $0 armv7-a"
                     print_supported_cpus
                 }
                 # 传入CPU参数
                 CPU=$1
                 if [ -z "$CPU" ]; then
                     print_usage
                     exit 1
                 elif [ "$CPU" = "help" ]; then
                     print_usage
                 elif [ "$CPU" = "armv7-a" ]; then
                     ARCH=arm
                     CC=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang
                     CXX=$TOOLCHAIN/bin/armv7a-linux-androideabi$API-clang++
                     SYSROOT=$TOOLCHAIN/sysroot
                     CROSS_PREFIX=$TOOLCHAIN/bin/llvm-
                     PREFIX=$(pwd)/android/$CPU
                     ADDI_LDFLAGS=" "
                     OPTIMIZE_CFLAGS="-mfloat-abi=softfp -march=$CPU"
                     build_android
                 elif [ "$CPU" = "armv8-a" ]; then
                     ARCH=arm64
                     CC=$TOOLCHAIN/bin/aarch64-linux-android$API-clang
                     CXX=$TOOLCHAIN/bin/aarch64-linux-android$API-clang++
                     SYSROOT=$TOOLCHAIN/sysroot
                     CROSS_PREFIX=$TOOLCHAIN/bin/llvm-
                     PREFIX=$(pwd)/android/$CPU
                     OPTIMIZE_CFLAGS="-march=$CPU"
                     build_android
                 else
                     echo "Unsupported CPU: $CPU"
                     print_supported_cpus
                 fi
                

                –target-os=xxx :指定编译器目标 os。当我们编译用于 android 平台的库时,指定该选项为 --target-os=android,否则编译出的 so 为软链接,真正的 so 名字后缀带有一长串的主版本号与子版本号,这样的库在 android 平台上无法识别,如下图所示:

                Android NDK 编译 FFmpeg:从下载源码到生成库的全过程

                当指定 --target-os=android ,则编译出的库如下:Android NDK 编译 FFmpeg:从下载源码到生成库的全过程

                –disable-vulkan: 编译时可能出现 fatal error: ‘vulkan_beta.h’ file not found

                #include “vulkan_beta.h” 错误。可在使用 configure 脚本配置编译选项时,使用 --disable-vulkan 禁用 vulkan;或 extra-cflags 参数中添加 -DVK_ENABLE_BETA_EXTENSIONS=0 来防止引用 vulkan_beta.h。

                3. 脚本使用说明

                • 进入 ffmpeg 源码目录,并创建脚本文件:vim build_android.sh
                • 按上一章节内容编辑脚本文件
                • ./build_android.sh help 查看脚本使用说明

                  Android NDK 编译 FFmpeg:从下载源码到生成库的全过程

                  参考资料

                  • 什么是适用于 Linux 的 Windows 子系统?
                  • 如何在 Windows 10 上安装 WSL 2
                  • CPU 优化技术-NEON 自动向量化
                  • FFmpeg - ./configure编译参数全部总结和整理_ffmpeg编译参数详解
                  • FFMPEG 配置选项详细说明_选项
VPS购买请点击我

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们,邮箱:ciyunidc@ciyunshuju.com。本站只作为美观性配图使用,无任何非法侵犯第三方意图,一切解释权归图片著作权方,本站不承担任何责任。如有恶意碰瓷者,必当奉陪到底严惩不贷!

目录[+]