使用NDKR19C编译最新的FFMPEG和X264给Android平台使用

系统环境:ubuntu18.04

NDK版本:   R19C

X264版本:x264-snapshot-20181217-2245

FFMPEG版本: 4.2.2

一、文件下载

X264库下载地址: http://www.videolan.org/developers/x264.html

NDK下载地址: https://developer.android.google.cn/ndk/downloads/index.html

注意,因为google在 NDK R19C中把GCC删除了。支持gcc版本的最高的ndk是 NDK R17C,后面的版本没有GCC编译器了,只有clang编译器,本文就是使用clang编译编译配置X264。

X264和FFMPEG编译好的库已经上传CSDN,如果不想编译直接使用可以去下载。

二、编译X264生成静态库

X264配置的情况可以在当前目录下的config.log文件中看到详细消息,包括出错的问题。

由于x264只是支持gcc的配置,如果想使用R17C版本的NDK编译,在x264目录下写一个脚本build_android.sh:

#!/bin/sh
ANDROID_NDK="/home/wbyq/work_pc/AndroidPath/android-ndk-r17c"
SDK_VERSION=27
ARCH=arm64
#ARCH=arm

if [ "$ARCH" = "arm64" ]
then
    PLATFORM_PREFIX="aarch64-linux-android-"
    HOST="aarch64"
    PLATFORM_VERSION=4.9
else
    PLATFORM_PREFIX="arm-linux-androideabi-"
    HOST="arm"
    PLATFORM_VERSION=4.9
fi

PREFIX=$(pwd)/android/${ARCH}
SYSROOT=$ANDROID_NDK/platforms/android-${SDK_VERSION}/arch-${ARCH}
TOOLCHAIN=$ANDROID_NDK/toolchains/${PLATFORM_PREFIX}${PLATFORM_VERSION}/prebuilt/linux-x86_64
CROSS_PREFIX=$TOOLCHAIN/bin/${PLATFORM_PREFIX}
echo "PREFIX=$PREFIX"
echo "SYSROOT=$SYSROOT"
echo "TOOLCHAIN=$TOOLCHAIN"
echo "CROSS_PREFIX=$CROSS_PREFIX"
./configure --prefix=$PREFIX --cross-prefix=$CROSS_PREFIX --sysroot=$SYSROOT --enable-static --enable-pic  --disable-asm --host=arm-linux

这个脚本的目的是生成Makefile文件和config.mak文件,如果只是想使用R17C版本的NDK编译的话,生成Makefile之后就可以直接make && make install。

如果想使用R19C版本或者以上的NDK版本编译X264,那么就需要手动修改生成的config.mak文件。

config.mak文件修改的效果示例(只是支持静态库):

注意: 其中ndk相关的路径需要根据自己电脑上的NDK路径修改替换,这里的编译采用的是64位的。

SRCPATH=.
prefix=/home/wbyq/work/rk3399/x264-master/android/arm64
exec_prefix=${prefix}
bindir=${exec_prefix}/bin
libdir=${exec_prefix}/lib
includedir=${prefix}/include
SYS_ARCH=ARM
SYS=LINUX
CC=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang
CFLAGS= -D__ANDROID_API__=21 -target aarch64-none-linux-android -gcc-toolchain /home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/aarch64-linux-android-4.9/prebuilt/linux-x86_64 -fno-limit-debug-info -DANDROID_HAS_WSTRING --sysroot=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/sysroot -isystem /home/wbyq/work_pc/AndroidPath/android-ndk-r19c/sysroot/usr/include/aarch64-linux-android -isystem /home/wbyq/work_pc/AndroidPath/android-ndk-r19c/sources/cxx-stl/llvm-libc++/include -isystem /home/wbyq/work_pc/AndroidPath/android-ndk-r19c/sources/android/support/include -isystem /home/wbyq/work_pc/AndroidPath/android-ndk-r19c/sources/cxx-stl/llvm-libc++abi/include -fstack-protector-strong -DANDROID -O2 -Wall -W -D_REENTRANT -fPIC $(DEFINES) -ffast-math -I. -I$(SRCPATH) -fomit-frame-pointer -fno-tree-vectorize -fvisibility=hidden

CFLAGSSO=
CFLAGSCLI=
COMPILER=GNU
COMPILER_STYLE=GNU
DEPMM=-MM -g0
DEPMT=-MT
LD=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang -o 
LDFLAGS= --sysroot=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/platforms/android-21/arch-arm64 -lm -ldl
LDFLAGSCLI=-ldl 
LIBX264=libx264.a
CLI_LIBX264=$(LIBX264)
AR=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ar rc 
RANLIB=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-ranlib
STRIP=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip
INSTALL=install
AS=
ASFLAGS= -I. -I$(SRCPATH) -DSTACK_ALIGNMENT=4 -DPIC
RC=
RCFLAGS=
EXE=
HAVE_GETOPT_LONG=1
DEVNULL=/dev/null
PROF_GEN_CC=-fprofile-generate
PROF_GEN_LD=-fprofile-generate
PROF_USE_CC=-fprofile-use
PROF_USE_LD=-fprofile-use
HAVE_OPENCL=yes
CC_O=-o $@
default: cli
install: install-cli
default: lib-static
install: install-lib-static

修改之后再编译安装,make && make install。

三、 配置编译ffmpeg支持x264编码库

先参照前面章节编译X264生成静态库,是静态库,不需要动态库。Ffmpeg只支持连接x264的静态库,动态库会报错找不到libx264。

Ffmpeg配置情况可以在ffbuild/config.log文件中查看到。

先下载ffmpeg源码之后在linux下解压。

(1). 第一步修改configure

进入源码根目录,用vim打开configure,找到

SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'  

LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'  

SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'  

SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'  

将其修改为

SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'  

LIB_INSTALL_EXTRA_CMD='$$(RANLIB)"$(LIBDIR)/$(LIBNAME)"'  

SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'  

SLIB_INSTALL_LINKS='$(SLIBNAME)' 

 

然后、配置FFMPEG,使能X264编码,并指定X264编码库的相关库文件头文件的路径:

FFMPEG配置示例:(ARM64-V8)

./configure --prefix=$PWD/android/arm64_v8  --toolchain=clang-usan --enable-cross-compile --target-os=android --arch=arm64 --cpu=armv8-a --sysroot=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/sysroot --cc=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang  --cxx=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android21-clang++ --strip=/home/wbyq/work_pc/AndroidPath/android-ndk-r19c/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android-strip --extra-cflags='-fPIE -pie -march=armv8-a -mfloat-abi=softfp -mfpu=vfp -marm' --extra-ldflags='-fPIE -pie' --enable-gpl  --enable-ffmpeg --enable-libx264 --enable-shared --extra-cflags=-I/home/wbyq/work/rk3399/ffmpeg-4.2.2/x264/android/arm64/include --extra-ldflags=-L/home/wbyq/work/rk3399/ffmpeg-4.2.2/x264/android/arm64/lib

配置之后,make install

(注意: 如果每次改变配置重新编译,需要make clean 之后再make)

编译安装成功之后,在当前目录下会生成android/arm64_x264目录。

详细的文件如下:

wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2$ cd android/arm64_x264/
wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2/android/arm64_x264$ ls
bin  include  lib  share
wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2/android/arm64_x264$ cd lib/
wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2/android/arm64_x264/lib$ ls
libavcodec.so   libavfilter.so  libavutil.so    libswresample.so  pkgconfig
libavdevice.so  libavformat.so  libpostproc.so  libswscale.so
wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2/android/arm64_x264/lib$ file libavdevice.so 
libavdevice.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, stripped
wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2/android/arm64_x264/lib$ cd ..
wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2/android/arm64_x264$ ls
bin  include  lib  share
wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2/android/arm64_x264$ tree
.
├── bin
│   └── ffmpeg
├── include
│   ├── libavcodec
│   │   ├── ac3_parser.h
│   │   ├── adts_parser.h
│   │   ├── avcodec.h
│   │   ├── avdct.h
│   │   ├── avfft.h
│   │   ├── d3d11va.h
│   │   ├── dirac.h
│   │   ├── dv_profile.h
│   │   ├── dxva2.h
│   │   ├── jni.h
│   │   ├── mediacodec.h
│   │   ├── qsv.h
│   │   ├── vaapi.h
│   │   ├── vdpau.h
│   │   ├── version.h
│   │   ├── videotoolbox.h
│   │   ├── vorbis_parser.h
│   │   └── xvmc.h
│   ├── libavdevice
│   │   ├── avdevice.h
│   │   └── version.h
│   ├── libavfilter
│   │   ├── avfilter.h
│   │   ├── buffersink.h
│   │   ├── buffersrc.h
│   │   └── version.h
│   ├── libavformat
│   │   ├── avformat.h
│   │   ├── avio.h
│   │   └── version.h
│   ├── libavutil
│   │   ├── adler32.h
│   │   ├── aes_ctr.h
│   │   ├── aes.h
│   │   ├── attributes.h
│   │   ├── audio_fifo.h
│   │   ├── avassert.h
│   │   ├── avconfig.h
│   │   ├── avstring.h
│   │   ├── avutil.h
│   │   ├── base64.h
│   │   ├── blowfish.h
│   │   ├── bprint.h
│   │   ├── bswap.h
│   │   ├── buffer.h
│   │   ├── camellia.h
│   │   ├── cast5.h
│   │   ├── channel_layout.h
│   │   ├── common.h
│   │   ├── cpu.h
│   │   ├── crc.h
│   │   ├── des.h
│   │   ├── dict.h
│   │   ├── display.h
│   │   ├── downmix_info.h
│   │   ├── encryption_info.h
│   │   ├── error.h
│   │   ├── eval.h
│   │   ├── ffversion.h
│   │   ├── fifo.h
│   │   ├── file.h
│   │   ├── frame.h
│   │   ├── hash.h
│   │   ├── hdr_dynamic_metadata.h
│   │   ├── hmac.h
│   │   ├── hwcontext_cuda.h
│   │   ├── hwcontext_d3d11va.h
│   │   ├── hwcontext_drm.h
│   │   ├── hwcontext_dxva2.h
│   │   ├── hwcontext.h
│   │   ├── hwcontext_mediacodec.h
│   │   ├── hwcontext_qsv.h
│   │   ├── hwcontext_vaapi.h
│   │   ├── hwcontext_vdpau.h
│   │   ├── hwcontext_videotoolbox.h
│   │   ├── imgutils.h
│   │   ├── intfloat.h
│   │   ├── intreadwrite.h
│   │   ├── lfg.h
│   │   ├── log.h
│   │   ├── lzo.h
│   │   ├── macros.h
│   │   ├── mastering_display_metadata.h
│   │   ├── mathematics.h
│   │   ├── md5.h
│   │   ├── mem.h
│   │   ├── motion_vector.h
│   │   ├── murmur3.h
│   │   ├── opt.h
│   │   ├── parseutils.h
│   │   ├── pixdesc.h
│   │   ├── pixelutils.h
│   │   ├── pixfmt.h
│   │   ├── random_seed.h
│   │   ├── rational.h
│   │   ├── rc4.h
│   │   ├── replaygain.h
│   │   ├── ripemd.h
│   │   ├── samplefmt.h
│   │   ├── sha512.h
│   │   ├── sha.h
│   │   ├── spherical.h
│   │   ├── stereo3d.h
│   │   ├── tea.h
│   │   ├── threadmessage.h
│   │   ├── timecode.h
│   │   ├── time.h
│   │   ├── timestamp.h
│   │   ├── tree.h
│   │   ├── twofish.h
│   │   ├── tx.h
│   │   ├── version.h
│   │   └── xtea.h
│   ├── libpostproc
│   │   ├── postprocess.h
│   │   └── version.h
│   ├── libswresample
│   │   ├── swresample.h
│   │   └── version.h
│   └── libswscale
│       ├── swscale.h
│       └── version.h
├── lib
│   ├── libavcodec.so
│   ├── libavdevice.so
│   ├── libavfilter.so
│   ├── libavformat.so
│   ├── libavutil.so
│   ├── libpostproc.so
│   ├── libswresample.so
│   ├── libswscale.so
│   └── pkgconfig
│       ├── libavcodec.pc
│       ├── libavdevice.pc
│       ├── libavfilter.pc
│       ├── libavformat.pc
│       ├── libavutil.pc
│       ├── libpostproc.pc
│       ├── libswresample.pc
│       └── libswscale.pc
└── share
    └── ffmpeg
        ├── examples
        │   ├── avio_dir_cmd.c
        │   ├── avio_reading.c
        │   ├── decode_audio.c
        │   ├── decode_video.c
        │   ├── demuxing_decoding.c
        │   ├── encode_audio.c
        │   ├── encode_video.c
        │   ├── extract_mvs.c
        │   ├── filter_audio.c
        │   ├── filtering_audio.c
        │   ├── filtering_video.c
        │   ├── http_multiclient.c
        │   ├── hw_decode.c
        │   ├── Makefile
        │   ├── metadata.c
        │   ├── muxing.c
        │   ├── qsvdec.c
        │   ├── README
        │   ├── remuxing.c
        │   ├── resampling_audio.c
        │   ├── scaling_video.c
        │   ├── transcode_aac.c
        │   ├── transcoding.c
        │   ├── vaapi_encode.c
        │   └── vaapi_transcode.c
        ├── ffprobe.xsd
        ├── libvpx-1080p50_60.ffpreset
        ├── libvpx-1080p.ffpreset
        ├── libvpx-360p.ffpreset
        ├── libvpx-720p50_60.ffpreset
        └── libvpx-720p.ffpreset

15 directories, 163 files
wbyq@wbyq:~/work/rk3399/ffmpeg-4.2.2/android/arm64_x264$ 

接下来就可以直接集成到AndroidAPP里调用。完成视频录制、转换、添加水印、推流等等。

下篇文章介绍,使用QT5.12调用编译的FFMPEG库部署到Android设备,完成摄像头视频采集、推流。

下面公众号里有全套QT、C、C++基础学习教程:

发布了14 篇原创文章 · 获赞 9 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/xiaolong1126626497/article/details/104734472