Linux下ndk编译移植FFmpeg到Android平台(二)——集成x264和libfdk-aac

在前面的Linux下ndk编译移植FFmpeg到Android平台文章中介绍了如何将最基本的FFmpeg到Android平台。但只是简单的移植了FFmpeg,没有包含x264编码器,并且AAC编码器也只有默认的。在Android平台下使用FFmpeg进行RTMP推流(摄像头推流)中我实际上已经用到了x264编码器,但没有介绍如何将x264集成到FFmpeg中。而本篇文章将解决这个问题,重点讲解如何集成x264和libfdk-aac,当然也会有问题汇总。

为什么要单独一篇文章来介绍如何去移植FFmpeg、x264和fdk_aac呢?
万事开头难,第一步很难,但也是最重要的,不怕告诉大家,就仅仅编译这几个东西我足足花了两天时间去踩坑。对于有些编译出现各种问题导致没有成功的兄弟,可能非常的挫伤积极性,打击学习这方面知识的积极性。所以我觉得有必要重点讲解下这个环节

在进入这是内容之前我要强调一点,一定要注意安装版本,这个安装版本包括linux系统版本、FFmpeg版本、x264版本、libfdk-aac版本、ndk中android-api版本。你可能会因为版本不匹配导致编译出现各种问题,既然我已经把这些坑踩过了,希望大家不要再掉进去

同步开源库FFmpegSample,里面有我最新编译好的so 和对应的编译脚本build_x264.sh,build_fdk.sh,build_ffmpeg.sh

文章围绕以下几点介绍

  • 编译环境
  • x264编译
  • libfdk-aac编译
  • FFmpeg 编译
  • 踩坑历程

编译环境

  • linux版本 centos 6.8_64位 或 CentOS Linux release 7.4.1708 (Core)
[root@iZ94g6hanmqZ include]# lsb_release -a
LSB Version:    :base-4.0-amd64:base-4.0-noarch:core-4.0-amd64:core-4.0-noarch:graphics-4.0-amd64:graphics-4.0-noarch:printing-4.0-amd64:printing-4.0-noarch
Distributor ID: CentOS
Description:    CentOS release 6.8 (Final)
Release:    6.8
Codename:   Final
[root@localhost /]# cat /etc/centos-release
CentOS Linux release 7.4.1708 (Core)
  • ndk版本 android-ndk-r15c
    我的安装位置在/usr/local/app/android-ndk-r15c

接下来到了真正编译的时候了

编译x264

下载地址下载版本x264-snapshot-20140916-2245-stable.tar

2.png

然后解压为x264目录,进入x264目录,新建build_x264.sh内容为:

#!/bin/bash
#NDK=/usr/local/android/ndk-bundle
NDK=/usr/local/app/android-ndk-r15c
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
PLATFORM=$NDK/platforms/android-16/arch-arm
PREFIX=./android
echo $NDK
echo $TOOLCHAIN
echo $PLATFORM
echo $PREFIX
function build_one
{
    ./configure \
         --prefix=$PREFIX \
         --enable-static \
         --disable-shared \
         --enable-pic \
         --disable-asm \
         --disable-cli \
         --host=arm-linux \
         --cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
         --sysroot=$PLATFORM \
 
}
build_one

然后给文件增加运行权限 chmod +x build_x264.sh。剩下的就是配置编译安装啦。

./build_x264.sh
make -j4
make install

安装目录就在当前目录下生成android目录,当然库文件和头文件就有了

drwxr-xr-x 2 root root 4096 Jan 25 15:06 include
drwxr-xr-x 3 root root 4096 Jan 25 15:06 lib

编译libfdk-aac

先来几个问题:

    1. 为啥要集成libfdk-aac呢?
      嘿嘿!别着急,这个我会在下篇文章介绍ffmpeg进行AAC编码时候讲到,这里我只讲如何编译。
    1. 为什么不集成libfaac?
      不少尝试过的童鞋会发现,在编译FFmpeg时集成libfaac也就是configure增加--enable-libfaac参数时会提示ffmpeg: remove option for libfaac,Unknown option "--enable-libfaac",因为现在FFmpeg不支持libfaac扩展了。而网上很多比较早期的文章都是讲如何集成libfaac的,所以很多童鞋就比较疑惑。
3.png

下面正式进入编译fdk_aac
下载地址版本选择0.1.4

4.png

同样加压到fdk-aac-0.1.4目录,进入目录,新建build_fdk.sh内容为:

#!/bin/bash
NDK_HOME=/usr/local/app/android-ndk-r15c
ANDROID_API=android-14
SYSROOT=$NDK_HOME/platforms/$ANDROID_API/arch-arm
ANDROID_BIN=$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin/
CROSS_COMPILE=${ANDROID_BIN}/arm-linux-androideabi-
ARM_INC=$SYSROOT/usr/include
ARM_LIB=$SYSROOT/usr/lib
LDFLAGS=" -nostdlib -Bdynamic -Wl,--whole-archive -Wl,--no-undefined -Wl,-z,noexecstack  -Wl,-z,nocopyreloc -Wl,-soname,/system/lib/libz.so -Wl,-rpath-link=$ARM_LIB,-dynamic-linker=/system/bin/linker -L$NDK_HOME/sources/cxx-stl/gnu-libstdc++/libs/armeabi -L$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86/arm-linux-androideabi/lib -L$ARM_LIB  -lc -lgcc -lm -ldl  "
FLAGS="--host=arm-androideabi-linux --enable-static --disable-shared"
export CXX="${CROSS_COMPILE}g++ --sysroot=${SYSROOT}"
export LDFLAGS="$LDFLAGS"
export CC="${CROSS_COMPILE}gcc --sysroot=${SYSROOT}"
./configure $FLAGS  --prefix='/usr/local/app/fdk-aac-0.1.4/android'

剩下的就是配置编译安装啦。

./build_fdk.sh
make -j4
make install

安装目录就在当前目录下生成android目录,当然库文件和头文件就有了

drwxr-xr-x 2 root root 4096 Jan 25 15:06 include
drwxr-xr-x 3 root root 4096 Jan 25 15:06 lib

编译FFmpeg

FFmpeg版本3.2.4 下载地址
下载完源码解压后,我们进入目录先修改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)'

这里是修改编译完成后so文件的文件名格式

新建build_ffmpeg.sh脚本,内容

#!/bin/bash
NDK=/usr/local/app/android-ndk-r15c
SYSROOT=$NDK/platforms/android-16/arch-arm/
PREBUILT=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

function build_one
{
./configure  --prefix=$PREFIX \
    --enable-shared \
    --cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
    --disable-static \
    --disable-doc \
    --disable-ffserver \
    --disable-yasm \
    --enable-cross-compile \
    --enable-gpl \
    --enable-libx264 \
    --enable-decoder=h264 \
    --enable-encoder=libx264 \
    --enable-libfdk-aac \
    --enable-encoder=libfdk_aac \
    --enable-decoder=libfdk_aac \
    --enable-nonfree \
    --cross-prefix="$TOOLCHAIN/bin/arm-linux-androideabi-" \
    --target-os=linux \
    --arch=arm \
    --sysroot=$SYSROOT \
    --extra-cflags="-Os -fpic $ADDI_CFLAGS" \
    --extra-ldflags="$ADDI_LDFLAGS" \
    $ADDITIONAL_CONFIGURE_FLAG
}

CPU=arm
PREFIX=$(pwd)/android/$CPU
ADDI_CFLAGS="-marm -I/usr/local/app/x264-snapshot-20140916-2245-stable/android/include -DANDROID -I/usr/local/app/fdk-aac-0.1.4/android/include"
ADDI_LDFLAGS="-L/usr/local/app/x264-snapshot-20140916-2245-stable/android/lib -L/usr/local/app/fdk-aac-0.1.4/android/lib"

build_one

然后给文件增加运行权限 chmod +x build_ffmpeg.sh。剩下的就是配置编译安装啦。

./build_x264.sh
make -j4
make install

安装完之后我们最终的so包就生成了。在当前目录下的 ./android/arm下。

drwxr-xr-x  2 root root 4096 Jan 25 15:23 bin
drwxr-xr-x 10 root root 4096 Jan 25 15:11 include
drwxr-xr-x  3 root root 4096 Jan 25 15:23 lib
drwxr-xr-x  3 root root 4096 Jan 25 15:11 share

我们的动态库就在lib下了

-rwxr-xr-x 1 root root 12983912 Jan 25 15:23 libavcodec-57.so
lrwxrwxrwx 1 root root       16 Jan 25 15:23 libavcodec.so -> libavcodec-57.so
-rwxr-xr-x 1 root root    59384 Jan 25 15:23 libavdevice-57.so
lrwxrwxrwx 1 root root       17 Jan 25 15:23 libavdevice.so -> libavdevice-57.so
-rwxr-xr-x 1 root root  1877548 Jan 25 15:23 libavfilter-6.so
lrwxrwxrwx 1 root root       16 Jan 25 15:23 libavfilter.so -> libavfilter-6.so
-rwxr-xr-x 1 root root  1956464 Jan 25 15:23 libavformat-57.so
lrwxrwxrwx 1 root root       17 Jan 25 15:23 libavformat.so -> libavformat-57.so
-rwxr-xr-x 1 root root   443860 Jan 25 15:23 libavutil-55.so
lrwxrwxrwx 1 root root       15 Jan 25 15:23 libavutil.so -> libavutil-55.so
-rwxr-xr-x 1 root root    42276 Jan 25 15:23 libpostproc-54.so
lrwxrwxrwx 1 root root       17 Jan 25 15:23 libpostproc.so -> libpostproc-54.so
-rwxr-xr-x 1 root root    91532 Jan 25 15:23 libswresample-2.so
lrwxrwxrwx 1 root root       18 Jan 25 15:23 libswresample.so -> libswresample-2.so
-rwxr-xr-x 1 root root   406924 Jan 25 15:23 libswscale-4.so
lrwxrwxrwx 1 root root       15 Jan 25 15:23 libswscale.so -> libswscale-4.so
drwxr-xr-x 2 root root     4096 Jan 25 15:23 pkgconfig

这里对脚本做个解释,增加了几个命令。

  • 支持x264扩展
    --enable-libx264 \
    --enable-decoder=h264 \
    --enable-encoder=libx264 \
  • 支持fdk_aac扩展
    --enable-libfdk-aac \
    --enable-encoder=libfdk_aac \
    --enable-decoder=libfdk_aac \

要支持fdk_aac必须还加上

    --enable-nonfree \
    --enable-gpl \

最后就是制定x264 fdk_aac的头文件和库文件的目录--extra-cflags加入头文件目录,--extra-ldflags包含库文件目录,也就是

ADDI_CFLAGS="-marm -I/opt/x264/android/include -DANDROID -I/opt/fdk-aac-0.1.4/android/include"
ADDI_LDFLAGS="-L/opt/x264/android/lib -L/opt/fdk-aac-0.1.4/android/lib"

到这里我们就完成了整个编译。得到的so库不仅有FFmpeg基础功能,还有x264和fdk_aac的编解码功能


踩坑历程

configure FFmpeg提示找不到x264

看到这个问题,我开始很诧异,我明明都配置正确了,后来查看config日志,提示 找不到什么log2方法。后来发现新版本的x264的config.h中启用了这个方法,所以大家按我选择的版本就没问题啦。

make FFmpeg 报错

libavcodec/libx264.c: In function 'x264_frame' :
libavcodec/libx264.c:282:9 error: 'x264_bit_depth' undeclared(first use in this function)  
             if(x264_bit_depth>8)     

libavcodec/libx264.c: In function 'x264_init_static':
libavcodec/libx264.c:892.9 error: 'x264_bit_depth' undeclared(first use in this function)
             if(x264_bit_depth== 8)  

很明显没有找到x264_bit_depth这个变量。那咋办,还是版本不对应咯。你用的x264,FFmpeg可能不太兼容哦。

configure FFmpeg是faac不能用

这个前面已经提到了,FFmpeg已经不再支持libfaac啦。

编译好的so ,放在android平台下使用时,提示找不到x264.so

这里要注意,我在编译x264和fdk_aac时全部使用的静态编译,编出来的是静态库。那么最终我编译完FFmpeg后就不需要讲x264的so加入到android应用项目中。如果你是动态编译x264和fdk_aac那么你就得把这两个库的so也加入到android应用项目中。
注意编译x264和fdk_aac中间的参数--enable-static --disable-shared


到此所有讲解结束了,先预告下一篇,下一篇将介绍Android平台下使用FFmpeg进行AAC编译。里面会给大家解释为什么要用fdk_aac,而不用默认的AAC编码器。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容