0%

编译 x264

前言

网上的编译方法都比较旧,这回我发个采用最新版 NDK 编译 x264 的方法。

环境说明:

  • NDK 版本:22.0.7026061
  • 操作系统:Ubuntu 20.04.2 LTS

下载 x264

1
$ git clone https://code.videolan.org/videolan/x264.git

编译 so

查看支持的命令

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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
$ cd x264
$ ./configure --help
Usage: ./configure [options]

Help:
-h, --help print this message

Standard options:
--prefix=PREFIX install architecture-independent files in PREFIX
[/usr/local]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
--bindir=DIR install binaries in DIR [EPREFIX/bin]
--libdir=DIR install libs in DIR [EPREFIX/lib]
--includedir=DIR install includes in DIR [PREFIX/include]
--extra-asflags=EASFLAGS add EASFLAGS to ASFLAGS
--extra-cflags=ECFLAGS add ECFLAGS to CFLAGS
--extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS
--extra-rcflags=ERCFLAGS add ERCFLAGS to RCFLAGS

Configuration options:
--disable-cli disable cli
--system-libx264 use system libx264 instead of internal
--enable-shared build shared library
--enable-static build static library
--disable-bashcompletion disable installation of bash-completion script
--enable-bashcompletion force installation of bash-completion script
--bashcompletionsdir=DIR install bash-completion script in DIR [auto]
--disable-opencl disable OpenCL features
--disable-gpl disable GPL-only features
--disable-thread disable multithreaded encoding
--disable-win32thread disable win32threads (windows only)
--disable-interlaced disable interlaced encoding support
--bit-depth=BIT_DEPTH set output bit depth (8, 10, all) [all]
--chroma-format=FORMAT output chroma format (400, 420, 422, 444, all) [all]

Advanced options:
--disable-asm disable platform-specific assembly optimizations
--enable-lto enable link-time optimization
--enable-debug add -g
--enable-gprof add -pg
--enable-strip add -s
--enable-pic build position-independent code

Cross-compilation:
--host=HOST build programs to run on HOST
--cross-prefix=PREFIX use PREFIX for compilation tools
--sysroot=SYSROOT root of cross-build tree

External library support:
--disable-avs disable avisynth support
--disable-swscale disable swscale support
--disable-lavf disable libavformat support
--disable-ffms disable ffmpegsource support
--disable-gpac disable gpac support
--disable-lsmash disable lsmash support

yhz61010@ubuntu-yhz:~/Documents/x264/x264$ ./configure --help
Usage: ./configure [options]

Help:
-h, --help print this message

Standard options:
--prefix=PREFIX install architecture-independent files in PREFIX
[/usr/local]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
[PREFIX]
--bindir=DIR install binaries in DIR [EPREFIX/bin]
--libdir=DIR install libs in DIR [EPREFIX/lib]
--includedir=DIR install includes in DIR [PREFIX/include]
--extra-asflags=EASFLAGS add EASFLAGS to ASFLAGS
--extra-cflags=ECFLAGS add ECFLAGS to CFLAGS
--extra-ldflags=ELDFLAGS add ELDFLAGS to LDFLAGS
--extra-rcflags=ERCFLAGS add ERCFLAGS to RCFLAGS

Configuration options:
--disable-cli disable cli
--system-libx264 use system libx264 instead of internal
--enable-shared build shared library
--enable-static build static library
--disable-bashcompletion disable installation of bash-completion script
--enable-bashcompletion force installation of bash-completion script
--bashcompletionsdir=DIR install bash-completion script in DIR [auto]
--disable-opencl disable OpenCL features
--disable-gpl disable GPL-only features
--disable-thread disable multithreaded encoding
--disable-win32thread disable win32threads (windows only)
--disable-interlaced disable interlaced encoding support
--bit-depth=BIT_DEPTH set output bit depth (8, 10, all) [all]
--chroma-format=FORMAT output chroma format (400, 420, 422, 444, all) [all]

Advanced options:
--disable-asm disable platform-specific assembly optimizations
--enable-lto enable link-time optimization
--enable-debug add -g
--enable-gprof add -pg
--enable-strip add -s
--enable-pic build position-independent code

Cross-compilation:
--host=HOST build programs to run on HOST
--cross-prefix=PREFIX use PREFIX for compilation tools
--sysroot=SYSROOT root of cross-build tree

External library support:
--disable-avs disable avisynth support
--disable-swscale disable swscale support
--disable-lavf disable libavformat support
--disable-ffms disable ffmpegsource support
--disable-gpac disable gpac support
--disable-lsmash disable lsmash support

修改生成的 so 文件名

默认情况下,编译完后生成的文件名是这样的:libx264.so.xxx(例如,libx264.so.161),同时还会生成一个软链接 libx264.so 指向 libx264.so.xxx 文件。

Android 并不能识别 libx264.so.xxx 这样的库,会引发库打开失败(也不能直接将其重命名成 libx264.so,因此文件名并不等同于库名)。因此我们需要在编译时,修改下生成的文件名。

在下载的 x264 文件夹下,修改如下文件:

1
$ vim configure

configuration-libx264-so

修改上述两处高度部分,将他们修改成你希望生成的文件名。例如,可以修改成 libx264.$API.so

创建编译文件

1
$ vim build_x264_all.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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/bin/bash

NDK_PATH=/home/yhz61010/Android/Sdk/ndk/22.0.7026061

HOST_TAG=linux-x86_64
TOOLCHAINS=$NDK_PATH/toolchains/llvm/prebuilt/$HOST_TAG
SYSROOT=$TOOLCHAINS/sysroot

MIN_SDK_VER=21

function build_one
{
if [ $ARCH == "arm" ]
then
CROSS_PREFIX=$TOOLCHAINS/bin/arm-linux-androideabi-
HOST=arm-linux
elif [ $ARCH == "aarch64" ]
then
CROSS_PREFIX=$TOOLCHAINS/bin/aarch64-linux-android-
HOST=aarch64-linux
elif [ $ARCH == "i686" ]
then
CROSS_PREFIX=$TOOLCHAINS/bin/i686-linux-android-
HOST=i686-linux
else
CROSS_PREFIX=$TOOLCHAINS/bin/x86_64-linux-android-
HOST=x86_64-linux
fi

#pushd libx264
#./configure --prefix=$PREFIX \
# --host=$HOST \
# --sysroot=$SYSROOT \
# --cross-prefix=$CROSS_PREFIX \
# --extra-cflags="$OPTIMIZE_CFLAGS" \
# --extra-ldflags="-nostdlib" \
# --enable-pic \
# --enable-static \
# --enable-strip \
# --disable-cli \
# --disable-win32thread \
# --disable-avs \
# --disable-swscale \
# --disable-lavf \
# --disable-ffms \
# --disable-gpac \
# --disable-lsmash



# --disable-static \
./configure \
--prefix=$PREFIX \
--extra-cflags="$OPTIMIZE_CFLAGS" \
--enable-shared \
--enable-pic \
--disable-asm \
--disable-cli \
--host=$HOST \
--cross-prefix=$CROSS_PREFIX \
--sysroot=$SYSROOT

make clean
#make -j4 install V=1
make -j4
make install
#popd
}

#armeabi-v7a
ARCH=arm
OPTIMIZE_CFLAGS="-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security -Oz -DNDEBUG -fPIC --target=armv7-none-linux-androideabi$MIN_SDK_VER --gcc-toolchain=$TOOLCHAINS"
PREFIX=`pwd`/prebuilt/armeabi-v7a
export CC=$TOOLCHAINS/bin/armv7a-linux-androideabi$MIN_SDK_VER-clang
export CXX=$TOOLCHAINS/bin/armv7a-linux-androideabi$MIN_SDK_VER-clang++
build_one

#arm64-v8a
ARCH=aarch64
OPTIMIZE_CFLAGS="-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -O2 -DNDEBUG -fPIC --target=aarch64-none-linux-android$MIN_SDK_VER --gcc-toolchain=$TOOLCHAINS"
PREFIX=`pwd`/prebuilt/arm64-v8a
export CC=$TOOLCHAINS/bin/aarch64-linux-android$MIN_SDK_VER-clang
export CXX=$TOOLCHAINS/bin/aarch64-linux-android$MIN_SDK_VER-clang++
build_one

#x86
ARCH=i686
OPTIMIZE_CFLAGS="-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -mstackrealign -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -O2 -DNDEBUG -fPIC --target=i686-none-linux-android$MIN_SDK_VER --gcc-toolchain=$TOOLCHAINS"
PREFIX=`pwd`/prebuilt/x86
export CC=$TOOLCHAINS/bin/i686-linux-android$MIN_SDK_VER-clang
export CXX=$TOOLCHAINS/bin/i686-linux-android$MIN_SDK_VER-clang++
build_one

#x86_64
ARCH=x86_64
OPTIMIZE_CFLAGS="-g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security -O2 -DNDEBUG -fPIC --target=x86_64-none-linux-android$MIN_SDK_VER --gcc-toolchain=$TOOLCHAINS"
PREFIX=`pwd`/prebuilt/x86_64
export CC=$TOOLCHAINS/bin/x86_64-linux-android$MIN_SDK_VER-clang
export CXX=$TOOLCHAINS/bin/x86_64-linux-android$MIN_SDK_VER-clang++
build_one

开始编译

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$ chmod +x build_x264_all.sh
$ ./build_x264_all.sh
platform: ARM
byte order: little-endian
system: LINUX
cli: no
libx264: internal
shared: yes
static: no
...
...
...
install -d /home/yhz61010/Documents/x264/x264/prebuilt/x86_64/include /home/yhz61010/Documents/x264/x264/prebuilt/x86_64/lib/pkgconfig
install -m 644 ./x264.h x264_config.h /home/yhz61010/Documents/x264/x264/prebuilt/x86_64/include
install -m 644 x264.pc /home/yhz61010/Documents/x264/x264/prebuilt/x86_64/lib/pkgconfig
install -d /home/yhz61010/Documents/x264/x264/prebuilt/x86_64/lib
ln -f -s libx264.161.so /home/yhz61010/Documents/x264/x264/prebuilt/x86_64/lib/libx264.so
install -m 755 libx264.161.so /home/yhz61010/Documents/x264/x264/prebuilt/x86_64/lib

查看编译结果

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
$ tree prebuilt/
prebuilt/
├── arm64-v8a
│   ├── include
│   │   ├── x264_config.h
│   │   └── x264.h
│   └── lib
│   ├── libx264.161.so
│   ├── libx264.so -> libx264.161.so
│   └── pkgconfig
│   └── x264.pc
├── armeabi-v7a
│   ├── include
│   │   ├── x264_config.h
│   │   └── x264.h
│   └── lib
│   ├── libx264.161.so
│   ├── libx264.so -> libx264.161.so
│   └── pkgconfig
│   └── x264.pc
├── x86
│   ├── include
│   │   ├── x264_config.h
│   │   └── x264.h
│   └── lib
│   ├── libx264.161.so
│   ├── libx264.so -> libx264.161.so
│   └── pkgconfig
│   └── x264.pc
└── x86_64
├── include
│   ├── x264_config.h
│   └── x264.h
└── lib
├── libx264.161.so
├── libx264.so -> libx264.161.so
└── pkgconfig
└── x264.pc

16 directories, 20 files

设置 cflags 技巧

设置 configure 参数时,对于 cflags 该如何设置,这个有个小技巧可以帮忙大家设置正常的 cflags

  • 新建一个 Native C++ 工程。

    Create Native C++ Project

    其中 C++ Standard 选择 Toolchain Default

    select-toolchain

    • 如需要指定 ndk 版本,请修改 module 下的 build.gradle,并追加如下代码:
    1
    2
    3
    android {
    ndkVersion "major.minor.build" // e.g., ndkVersion '22.0.7026061'
    }

    specify-ndk-version.png

  • Active Build Variant 选择 release

    release-build-variant

  • 找到 build.ninjarules.ninja 文件(这里以 armeabi-v7a 为例)

    find-ninja-files

    • 使用 build.ninja 中的 FLAGS 的值。

    build-ninja-flags

    例如,我这里得到的值为:

    1
    FLAGS = -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security   -Oz -DNDEBUG  -fPIC
    • 使用 rules.ninja 中的部分参数。

    rules.ninja-parameters

    例如,我这里得到的值为:

    1
    --target=armv7-none-linux-androideabi21 --gcc-toolchain=/home/yhz61010/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64 --sysroot=/home/yhz61010/Android/Sdk/ndk/22.0.7026061/toolchains/llvm/prebuilt/linux-x86_64/sysroot

    得到以上两组参数后,做适当修改就可以得到我们最终需要的 cflags 参数:

    1
    -g -DANDROID -fdata-sections -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -D_FORTIFY_SOURCE=2 -march=armv7-a -mthumb -Wformat -Werror=format-security   -Oz -DNDEBUG  -fPIC --target=armv7-none-linux-androideabi$MIN_SDK_VER --gcc-toolchain=$TOOLCHAINS

    本例是以 armeabi-v7a 架构进行说明的,其它架构的参数获取方法相同,只需要在对应的目录下获取即可。

参考文献

坚持原创及高品质技术分享,您的支持将鼓励我继续创作!