Ubuntu 下 FFmpeg 和 x264, x265 交叉编译

环境与准备

我使用的环境

系统:Ubuntu 20.04
FFmpeg:3.4.4
NDK: r13b

FFmpeg 官网中列出了更新内容。选择这个版本是因为 4.x 之后就不支持硬件加速了。(图中演示为 3.4.7 版本)

这个可以下载解压之后,运行./configure --list-hwaccels 查看。

./configure --list-encoders 支持的编码器

./configure --list-decoders 支持的解码器

命令

1
2
3
4
5
6
# 拷贝环境
git clone https://github.com/liaoheng/FFmpegAndoird.git
# 下载NDK
wget https://dl.google.com/android/repository/android-ndk-r13b-linux-x86_64.zip
# 安装依赖库
sudo apt-get install autoconf automake build-essential cmake cmake-curses-gui git-core libass-dev libfreetype6-dev libtool libvorbis-dev pkg-config texinfo axel zlib1g-dev mercurial yasm nasm

说明

  1. 我的依赖库版本

    • autoconf 2.69-11.1
    • build-essential 12.8ubuntu1.1
    • automake 1:1.16.1-4ubuntu6
    • cmake 3.16.3-1ubuntu1
    • cmake-curses-gui 3.16.3-1ubuntu1
    • libass-dev 1:0.14.0-2
    • libfreetype6-dev 2.10.1-2ubuntu0.1
    • libtool 2.4.6-14
    • libvorbis-dev 1.3.6-2ubuntu1
    • pkg-config 0.29.1-0ubuntu4
    • texinfo 6.7.0.dfsg.2-5
    • zlib1g-dev 1:1.2.11.dfsg-2ubuntu1.2
    • axel 2.17.5-1ubuntu1
    • zlib1g-dev 1:1.2.11.dfsg-2ubuntu1.2
    • mercurial 5.3.1-1ubuntu1
    • yasm 1.3.0-2ubuntu1
    • nasm 2.14.02-1
  2. 作者推荐的版本

    • ubuntu 18.04.1
    • ndk r13b
    • cmake 3.10 (安装时已替换)
    • // 以下包已被包含
    • FFmpeg 3.4.4
    • libx265 2.7
    • libfdk-aac 0.1.6
    • x264 snapshot-20180927-2245

安装前修改

fdk

这是一个音频解码库

  1. 找到 fdk-aac-0.1.6 目录,打开 build/android 下的 fdk_aac_build_all.sh,解开

    1
    2
    3
    4
    # Build arm v6 v7a
    ./fdk_aac_arm_build.sh $NDK
    # Build arm64 v8a
    ./fdk_aac_arm64_v8a_build.sh $NDK

    的注释。

  2. 删除 arm,arm64-v8a 文件夹下的内容。

  3. 打开 m4 下的 libtool.m4 文件:

    • 全局搜索 so.1, 替换为 so

    • 全局搜索 $versuffix , 替换为空字符,也就是删除它

    • 全局搜索 $major ,, 替换为空字符,也就是删除它

    • * 我进行了如是操作,可以正常生成的 armeabi-v7a 的 so 包,但 arm64-v8a 依然会生成 so.1 形式的包,因此我放弃了 fdk-aac 的交叉编译。

x264

  1. 找到 x264 目录,进入 build/android 下的 x264_build_all.sh,解开

    1
    2
    3
    4
    # Build arm v6 v7a
    ./x264_arm_build.sh $NDK
    # Build arm64 v8a
    ./x264_arm64_v8a_build.sh $NDK

    的注释。

  2. 删除 arm,arm64-v8a 文件夹下的内容。

x265

  1. 找到 x265_2.7 目录,打开 build/android 下的 x265_build_all.sh,解开

    1
    2
    3
    4
    # Build arm v7a
    ./x265_arm_v7a_build.sh $NDK
    # Build arm64 v8a
    ./x265_arm64_v8a_build.sh $NDK

    的注释。

  2. 删除 armeabi-v7a,arm64-v8a 文件夹下的内容。

  3. 打开 source 下的 CMakeLists.txt,删除或者注释:list(APPEND PLATFORM_LIBS pthread)

FFmpge

  1. 找到 ffmpeg-3.4.4 目录,打开 build/android 下的 ffmpeg_build_all.sh

    • 修改 NDK 的路径,指向解压好的 NDK 目录,例如

      1
      NDK=/home/luov/Documents/NDKtool/android-ndk-r13b
    • 解开

      1
      2
      3
      4
      # Build arm  v7a
      ./ffmpeg_arm_v7a_build.sh $NDK $FDK_AAC $X264 $X265
      # Build arm64 v8a
      ./ffmpeg_arm64_v8a_build.sh $NDK $FDK_AAC $X264 $X265
    • 分别打开 ffmpeg_arm64_v8a_build.shffmpeg_arm_v7a_build.sh,修改 configure 中的编译参数,如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    ./configure # 先要进行一次空设置,不然下面会报错

    ./configure \
    --pkg-config=pkg-config \
    --prefix=$PREFIX \
    --enable-cross-compile \
    --disable-runtime-cpudetect \
    --enable-asm \
    --arch=aarch64 \
    --target-os=android \
    --cc=${CROSS_PREFIX}gcc \
    --cross-prefix=$CROSS_PREFIX \
    --disable-stripping \
    --nm=${CROSS_PREFIX}nm \
    --sysroot=$SYSROOT \
    --enable-gpl \
    --enable-shared \
    --disable-static \
    --enable-version3 \
    --enable-pthreads \
    --enable-small \
    --disable-vda \
    --disable-iconv \
    --enable-encoders \
    --enable-neon \
    --enable-yasm \
    --enable-libx264 \
    --enable-libx265 \
    --enable-jni \
    --enable-encoder=yuv4 \
    --enable-decoder=yuv4 \
    --enable-mediacodec \
    --enable-encoder=libx264 \
    --enable-encoder=libx265 \
    --enable-decoder=libx264 \
    --enable-decoder=libx265 \
    --enable-encoder=h264_mediacodec \
    --enable-encoder=hevc_mediacodec \
    --enable-decoder=h264_mediacodec \
    --enable-decoder=hevc_mediacodec \
    --enable-hwaccel=h264_mediacodec \
    --enable-hwaccel=hevc_mediacodec \
    --enable-bsf=h264_mp4toannexb \
    --enable-bsf=hevc_mp4toannexb \
    --enable-encoder=mjpeg \
    --enable-encoder=png \
    --enable-nonfree \
    --enable-muxers \
    --enable-decoders \
    --enable-demuxers \
    --enable-parsers \
    --enable-protocols \
    --enable-zlib \
    --enable-avfilter \
    --disable-outdevs \
    --disable-ffprobe \
    --disable-ffplay \
    --disable-ffmpeg \
    --disable-ffserver \
    --disable-debug \
    --disable-ffprobe \
    --disable-ffplay \
    --disable-ffmpeg \
    --disable-postproc \
    --disable-avdevice \
    --disable-symver \
    --disable-stripping \
    --extra-cflags="$FF_EXTRA_CFLAGS $FF_CFLAGS" \
    --extra-ldflags=" "
    • 同时注释
      1
      cp $FDK_PKGCONFIG/../libfdk-aac.so $PREFIX/lib

说明

  1. 只为安卓设备编译,因此各软件仅编译 armeabi-v7aarm64-v8a 版本,所有编译语句也仅保留这两个版本语句。
  2. 由于会额外生成 fdk-aac.so.1 包,无法在安卓上正常使用,所以放弃联合编译 fdk-aac 包。

编译

定位到 ffmpeg-3.4.4/build/android,运行 ffmpeg_build_all.sh 进行编译

1
2
chmod +x ffmpeg_build_all.sh
./ffmpeg_build_all.sh

编译完成后,会在当前目录的 armeabi-v7aarm64-v8a 下生成编译好的包,拷贝这两个文件夹即可使用。

感谢 @liaoheng