前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux下ndk编译移植FFmpeg到Android平台(二)——集成x264和libfdk-aac

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

作者头像
用户2929716
发布2018-08-23 13:37:34
1.6K0
发布2018-08-23 13:37:34
举报
文章被收录于专栏:流媒体流媒体

在前面的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

文章围绕以下几点介绍

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

编译环境

  • linux版本 centos 6.8_64位
代码语言:javascript
复制
[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
  • ndk版本 下载最新即可 我的安装位置在/usr/local/android/ndk-bundle

接下来到了真正编译的时候了,注意我做编译的目录在/opt/下,也就是所有的源码都解压在这个目录下

编译x264

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

2.png

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

代码语言:javascript
复制
#!/bin/bash
NDK=/usr/local/android/ndk-bundle
TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64
PLATFORM=$NDK/platforms/android-16/arch-arm
PREFIX=./android

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。剩下的就是配置编译安装啦。

代码语言:javascript
复制
./build_x264.sh
make -j4
make install

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

代码语言:javascript
复制
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内容为:

代码语言:javascript
复制
NDK=/usr/local/android/ndk-bundle
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='/opt/fdk-aac-0.1.4/android'  

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

代码语言:javascript
复制
./build_fdk.sh
make -j4
make install

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

代码语言:javascript
复制
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 下载地址

下载完源码解压后,我们进入目录新建build_ffmpeg.sh脚本,内容

代码语言:javascript
复制
#!/bin/bash
NDK=/usr/local/android/ndk-bundle
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/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"

build_one

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

代码语言:javascript
复制
./build_x264.sh
make -j4
make install

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

代码语言:javascript
复制
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下了

代码语言:javascript
复制
-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扩展
代码语言:javascript
复制
    --enable-libx264 \
    --enable-decoder=h264 \
    --enable-encoder=libx264 \
  • 支持fdk_aac扩展
代码语言:javascript
复制
    --enable-libfdk-aac \
    --enable-encoder=libfdk_aac \
    --enable-decoder=libfdk_aac \

要支持fdk_aac必须还加上

代码语言:javascript
复制
    --enable-nonfree \
    --enable-gpl \

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

代码语言:javascript
复制
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 报错

代码语言:javascript
复制
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编码器。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.01.31 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 编译环境
  • 编译x264
  • 编译libfdk-aac
  • 编译FFmpeg
  • 踩坑历程
    • configure FFmpeg提示找不到x264
      • make FFmpeg 报错
        • configure FFmpeg是faac不能用
          • 编译好的so ,放在android平台下使用时,提示找不到x264.so
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档