Ubuntu 下 x264 和 x265 的 NDK 交叉编译

为 Android 编译 FFmpeg 需要开启 x264 和 x265,因此需要提前编译 x264 和 x265 两个包。、

环境准备

系统:Ubuntu 20.04
NDK:r14b
x264:最新版本
x265:一个 github 上的修改版本

1
2
git clone https://code.videolan.org/videolan/x264.git
git clone https://github.com/kimsan0622/libx265-android.git

交叉编译 x264

在 x264 文件夹下新建 build_x264.sh,写入如下内容

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

NDK=/home/luov/Documents/NDKtools/android-ndk-r14b # NDK的路径
configure()
{
CPU=$1
PREFIX=$(pwd)/android/$CPU
mkdir -p $PREFIX
HOST=""
CROSS_PREFIX=""
SYSROOT=""
if [ "$CPU" == "armeabi-v7a" ]
then
HOST=arm-linux
SYSROOT=$NDK/platforms/android-21/arch-arm/
CROSS_PREFIX=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
elif [ "$CPU" == "arm64-v8a" ]
then
HOST=aarch64-linux
SYSROOT=$NDK/platforms/android-21/arch-arm64/
CROSS_PREFIX=$NDK/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64/bin/aarch64-linux-android-
elif [ "$CPU" == "x86" ]
then
HOST=x86-linux
SYSROOT=$NDK/platforms/android-21/arch-x86/
CROSS_PREFIX=$NDK/toolchains/x86-4.9/prebuilt/linux-x86/bin/i686-linux-android-
elif [ "$CPU" == "x86_64" ]
then
HOST=x86_64-linux
SYSROOT=$NDK/platforms/android-21/arch-x86_64/
CROSS_PREFIX=$NDK/toolchains/x86_64-4.9/prebuilt/linux-x86_64/bin/x86_64-linux-android-
else
echo "nothing build"
fi
echo "build $cpu start"
./configure \
--prefix=$PREFIX \
--host=$HOST \
--enable-pic \
--enable-static \
--enable-shared \
--enalbe-neon \
--extra-cflags="-fPIE -pie" \
--extra-ldflags="-fPIE -pie -shared" \
--cross-prefix=$CROSS_PREFIX \
--sysroot=$SYSROOT
}

build()
{
make clean
cpu=$1
echo "build $cpu"

configure $cpu
#-j<CPU核心数>
make -j8
sudo make install
}


build armeabi-v7a
build arm64-v8a
build x86 # x86会失败,原因不明
build x86_64

编译成功后会在当前目录下生成 android 文件夹,里面有四个系统的编译后文件。文件结构类似

enter description here

1
2
3
4
5
6
7
8
android
├ arm64-v8a
│ ├ bin
│ ├ include
│ └ lib
├ armeabi-v7a
│ ├ ...
└ ...

交叉编译 x265

修改 libx265-android 下的 build.sh 文件中 NDK 的路径,以及 Android API 的版本(我改成了 21,和 x264 一致。)
然后运行 build.sh。最后在 build 下得到输出文件。

文件结构如下:

1
2
3
4
5
6
7
8
9
10
build
├ arm64-v8a
│ └ usr
│ └local
│ ├ bin
│ ├ include
│ └ lib
├ armeabi-v7a
│ ├ ...
└ ...

可能会遭遇到的问题:

  1. 缺失 libncurses.so.5
    1
    libncurses.so.5: cannot open shared object file: No such file or directory
    解决方法,安装缺失的文件:
    1
    2
    3
    4
    5
    6
    sudo apt-get install libncurses*
    ---
    sudo apt install apt-file
    sudo apt-file update
    sudo apt-file find libncurses.so.5
    sudo apt install libncurses5
  2. 找不到 libpthread
    1
    2
    3
    4
    5
    6
    7
    8
    9
    [ 85%] Building CXX object encoder/CMakeFiles/encoder.dir/weightPrediction.cpp.o
    [ 85%] Built target encoder
    Scanning dependencies of target x265-shared
    Linking CXX shared library libx265.so
    /home/heling/android-14-toolchain/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lpthread
    collect2: ld returned 1 exit status
    make[2]: *** [libx265.so.51] 错误 1
    make[1]: *** [CMakeFiles/x265-shared.dir/all] 错误 2
    make: *** [all] 错误 2
    解决方法,修改 source 目录下的 cmakelist.txt
    1
    2
    3
    4
    list(APPEND PLATFORM_LIBS pthread)
    更改为list(APPEND PLATFORM_LIBS)
    list(REMOVE_ITEM PLIBLIST "-lc" "-lpthread" ...)
    更改为list(REMOVE_ITEM PLIBLIST "-lc")
    至此,所有编译完成。