Android/NDK环境下FFmpeg及AAC,MP3,X264的编译

本篇介绍在Android/Ndk环境下FFmpeg的编译及使用, FFmpeg自带了H264、AAC、MP3的解码器,但却没有(或没有好的)相应的编码器。相应的编码器需要使用第三方库。推荐使用的第三方库为x264(H264编码) 、FDK_AAC(AAC编码),lame(MP3编码)。

在顺序上,应该先编译好第三方库,最后再编译FFmpeg库。

【本书说明:本文作者:邵发,本文选自《FFmpeg视音频编程指南》。有关本书的详细信息请访问官网:http://www.afanihao.cn 】

【权利声明:作者保留本文的全部权利。作者授权任何人都可以自由转载本文,但转载时必须遵守以下限制:①转载时必须全文转载,不得有任何修改,包括“权利声明”和“本书说明”部分 ② 仅限于网络转载,即最终结果公布于网络上。凡是不遵守以上两条的转载行为视为侵权行为。除非本人允许,任何人不得将本文内容用于任何的其他用途。】

1.1        NDK环境的准备

本篇的演示示例使用的是android-ndk-r8e版本,但理论上也适用于更新的NDK版本。为了让你的编译过程极其顺利,应该对NDK作以下改动:

进入目录 platforms/android-14/arch-arm/usr/lib

应该可以看到一些文件,例如 crtbegin_dynamic.o ,crtbegin_static.o  crtend_so.o , crtbegin_so.o ,crtend_android.o,等等。

把这个目录下的所有文件拷贝到

\toolchains\arm-linux-androideabi-4.6\prebuilt\linux-x86\lib\gcc\arm-linux-androideabi\4.6

否则在链接的时候ld会提示“找不到crtbegin_so.o和crtend_so.o”的错误。

应该把NDK的相关工具都把加PATH环境变量中,例如,


#!/bin/sh

export PATH=$PATH:/opt/ndk/android-ndk-r8e/

export PATH=$PATH: /opt/ndk/android-ndk-r8e/toolchains/arm-linux-androideabi-4.6/prebuilt/windows/bin/

1.2        FDK_AAC库的编译

如果你不打算使用AAC编码的功能,则可以略过本节。目前(2015年3月),fdk_aac的官方发布地址是在source_forge上,也许以后会变,作者可以自行搜索。目前地址为:

http://sourceforge.net/projects/opencore-amr/files/fdk-aac/

本文使用的版本是fdk-aac-0.1.3,为减少不必要的麻烦,读者也请下载这个包。

1.2.1         修改configure脚本

修改脚本的目的是去除目标库的版本号,以适应Android/NDK的对库的加载要求。简单地讲,这是因为在Android/NDK项目的java代码中,使用System.loadLibrary()函数来加载so文件时,动态库是不能加版本号的。

在fdk_aac的configure脚本里找到如下的行:


# This must be glibc/ELF.

linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*)

version_type=linux # correct to gnu/linux during the next big refactor

need_lib_prefix=no

need_version=no

  library_names_spec=‘${libname}${shared_ext}   ${libname}${shared_ext}   $libname${shared_ext}‘

  soname_spec=‘${libname}${shared_ext}‘

finish_cmds=‘PATH="\$PATH:/sbin" ldconfig -n $libdir‘

shlibpath_var=LD_LIBRARY_PATH

shlibpath_overrides_runpath=no

把粗体字部分替换为:


library_names_spec=‘$libname${shared_ext} $libname.a‘

1.2.2         新建配置脚本

在源码的根目录下建议一个myconfig.sh脚本。这是一个SHELL脚本,要求读者自己稍微了解一些SHELL脚本的写法。在这里只强调一点:SHELL脚本是以\n结尾的,如果你是在windows下面编辑的,那么应该用dos2unix来把文本的换行符转成unix格式。

为了避免不必要的麻烦,把NDK解压缩在/opt/ndk/android-ndk-r8e目录,并将FDK的输出目录--prefix设置在/opt/ndk/openlib目录下。读者第一遍操作时,不要擅自修改目录,必须在熟练掌握之后再自行修改目录。

myconfig.sh里面内容为:


#!/bin/sh

export CC=arm-linux-androideabi-gcc

export CXX=arm-linux-androideabi-g++

export AR=arm-linux-androideabi-ar

export LD=arm-linux-androideabi-ld

export AS=arm-linux-androideabi-gcc

export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 "

export CXXFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 "

export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib  -march=armv7-a -Wl,--fix-cortex-a8 "

./configure --enable-static --prefix=/opt/ndk/openlib --host=arm-linux

1.2.3         编译

如果你严格按照以上的操作进行,那么编译过程会非常简单。Linux下的开源软件一般都是分为三步编译 configure , make,make install,而fdk_aac也不例外。

1)   ./myconfig.sh

执行上述配置脚本,开始配置

2)  make

3)  make  install

一切正常,将在/opt/ndk/openlib下存放输出库及头文件,注意这个库是去掉版本号的libfdk-aac。显然,Android/NDK的程序员会更喜欢不带版本号的库。

1.3        LAME-MP3的编译

如果你不打算在项目中使用mp3编码,则略过本节。

本节介绍lame的编译,但遗憾的是,其动态库没有办法去掉版本号。所以本方法生成的目标动态库是带版本号的。

1.3.1         新建配置脚本

新建配置文件myconfig.sh,内容如下,


#!/bin/sh

export CC=arm-linux-androideabi-gcc

export CXX=arm-linux-androideabi-g++

export AR=arm-linux-androideabi-ar

export LD=arm-linux-androideabi-ld

export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm "

export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib  "

./configure --enable-static --prefix=/opt/ndk/openlib --host=arm-linux

1.3.2         编译

1)   ./myconfig.sh

执行上述配置脚本,开始配置

2)  make

3)  make  install

一切正常,将在/opt/ndk/openlib下存放输出库及头文件。

1.4        x264的编译

x264属于VLC的一部分,当前的源码位置为:

ftp://ftp.videolan.org/pub/videolan/x264/snapshots/

本篇使用的源码版本为x264-snapshot-20140723-2245-stable.tar.bz2

1.4.1         修改configure脚本

这一步的目的是使输出的库文件不带版本号。如果你坚持认为版本号不影响你的开发,则忽略本小节。

找到这一位置:


else

echo "SOSUFFIX=so" >> config.mak

echo "SONAME=libx264.so.$API" >> config.mak

echo "SOFLAGS=-shared -Wl,-soname,\$(SONAME) $SOFLAGS" >> config.mak

fi

将粗体字修改为:(即去掉$API后缀)


echo "SONAME=libx264.so" >> config.mak

1.4.2         新建配置脚本

新建myconfig.sh配置脚本,


#!/bin/sh

export CC=arm-linux-androideabi-gcc

export CXX=arm-linux-androideabi-g++

export AR=arm-linux-androideabi-ar

export LD=arm-linux-androideabi-ld

export AS=arm-linux-androideabi-gcc

export CFLAGS=" --sysroot=/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16"

export LDFLAGS=" -L/opt/ndk/android-ndk-r8e/platforms/android-14/arch-arm/usr/lib -march=armv7-a -Wl,--fix-cortex-a8 "

./configure --enable-static --enable-shared --prefix=/opt/ndk/openlib --host=arm-linux

1.4.3         编译

1)   ./myconfig.sh

执行上述配置脚本,开始配置

2)  make

3)  make  install

1.5        FFmpeg的编译

本示例使用的是FFmpeg2.1.3版本,可以从其官网ffmpeg.org上下载。如果不需要x264/aac/lame,可以直接进行本节的编译。

1.5.1         修改configure脚本

本节的目的是让输出的库不含有版本号。

先找到configure的如下位置:


SHFLAGS=‘-shared -Wl,-soname,$$(@F)‘

LIBPREF="lib"

LIBSUF=".a"

FULLNAME=‘$(NAME)$(BUILDSUF)‘

LIBNAME=‘$(LIBPREF)$(FULLNAME)$(LIBSUF)‘

SLIBPREF="lib"

SLIBSUF=".so"

SLIBNAME=‘$(SLIBPREF)$(FULLNAME)$(SLIBSUF)‘

SLIBNAME_WITH_VERSION=‘$(SLIBNAME).$(LIBVERSION)‘

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_VERSION=‘$(SLIBNAME)‘

SLIBNAME_WITH_MAJOR=‘$(SLIBNAME)‘

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

SLIB_INSTALL_NAME=‘$(SLIBNAME_WITH_VERSION)‘

SLIB_INSTALL_LINKS=

1.5.2         修改配置脚本

新建myconfig.sh


export NDK_ROOT=/opt/ndk

export TMPDIR=/tmp

./configure  --prefix=$NDK_ROOT/ffmpeg --sysroot=$NDK_ROOT/android-ndk-r8e/platforms/android-14/arch-arm  --cross-prefix=arm-linux-androideabi-  --target-os=linux --arch=arm   --extra-cflags="-I$NDK_ROOT/openlib/include -fPIC  " --extra-ldflags=-L$NDK_ROOT/openlib/lib  
--disable-programs --disable-doc --enable-shared --enable-cross-compile  --enable-gpl --enable-nonfree --enable-libx264 --enable-libmp3lame --enable-libfdk-aac

这个脚本中是把x264, fdk-aac, lame全部编译上了,你可以视自己的情况来修改。

1.5.3         编译

1)   ./myconfig.sh

执行上述配置脚本,开始配置

2)  make

3)  make  install

1.6        在Android.mk中引用FFmpeg库

1.6.1         使用静态库

推荐使用静态库。需要注意,FFmpeg库的静态库引用顺序是不能随便写的,为了避免不必要的麻烦,请照抄以下配置。

在你的Android.mk中添加以下几行(见黑体字部分)


LOCAL_LDLIBS    += -llog -lz

# ffmpeg

FFMPEG=/opt/ndk

LOCAL_CFLAGS += -I$(FFMPEG)/include

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavformat.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavcodec.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavdevice.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libswresample.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavdevice.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libswscale.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libpostproc.a

LOCAL_LDLIBS += -l$(FFMPEG)/lib/libavutil.a

 

# fdk_aac

LOCAL_LDLIBS += -l/opt/ndk/lib/libfdk-aac.a

LOCAL_LDLIBS += -l/opt/ndk/lib/libmp3lame.a

LOCAL_LDLIBS += -l/opt/ndk/lib/ libx264.a

include $(BUILD_SHARED_LIBRARY)

1.6.2         使用动态库

不推荐使用动态库,此过程过于复杂。要注意的有两点:①编译的时候,必须去除库的版本号 ② 在Java代码中加载的时候,要注意加载的顺序。

以下可以加在Android.mk中,但是仅供参考,遇到自己问题需要自己调试


# ffmpeg

FFMPEG=f:/Ndk/ffmpeg

LOCAL_CFLAGS += -I$(FFMPEG)/include

LOCAL_LDLIBS += -L$(FFMPEG)/lib

LOCAL_LDLIBS += -lavformat -lavcodec  -lswresample -lswscale  -lavutil -lavfilter

include $(BUILD_SHARED_LIBRARY)

1.6.3         在C++中使用ffmpeg

ffmpeg的库是按C编译的,里面的符号都是C格式,因此,若在C++中使用,还是要使用extern "C"这种技术。相关语法请参考《C/C++语法指南》(作者:邵发,官网http://www.afanihao.cn)。

为了大家的方便,在/opt/ndk/ffmpeg/include下新建一个ffmpeg.h,内容为:


#ifndef _FFMPEG_H

#define _FFMPEG_H

#ifdef __cplusplus

extern "C" {

#define INT64_C(val) val##LL

#define UINT64_C(val) val##ULL

#endif

#include <libavcodec/avcodec.h>

#include <libavformat/avformat.h>

#include <libswscale/swscale.h>

#include <libavutil/avutil.h>

#include <libavutil/opt.h>

#include <libavutil/imgutils.h>

#include <libswresample/swresample.h>

#include <libavutil/error.h>

#include <libavfilter/avfiltergraph.h>

#include <libavfilter/avcodec.h>

#include <libavfilter/buffersink.h>

#include <libavfilter/buffersrc.h>

#ifdef __cplusplus

}

#endif

#endif

然后在C++代码中直接#include "ffmpeg.h"就可以了。

时间: 2024-10-05 07:15:26

Android/NDK环境下FFmpeg及AAC,MP3,X264的编译的相关文章

Windows XP环境下 搭建Android NDK环境

搭建Android NDK环境 Windows XP环境下 1 一些下载 ① NDK r7:http://developer.android.com/sdk/ndk/index.html ② cygwin:http://www.cygwin.com/  (1.7.11-1)③ notepad++:http://notepad-plus-plus.org/download/v5.9.8.html 2 cygwin安装 ① 执行下载的setup.exe.点Next② 选择安装方式.选择在线安装.假设

windows下android NDK 环境配置

0.下载jdk并配置环境变量 下载最新jdk,百度搜索“jdk”就有了.安装完成后,配置环境变量(网上一搜,一堆,我这里仅作简要叙述)  计算机→属性→高级系统设置→高级→环境变量. 系统变量→新建 JAVA_HOME 变量 .变量值填写jdk的安装目录(本人是 D:\Program Files\Java\jdk1.7.0_45) 系统变量→新建 CLASSPATH 变量 变量值填写   .;%JAVA_HOME%\lib;%JAVA_HOME%\lib\tools.jar(注意最前面有一点)

Android NDK 环境搭建 + 测试例程

懒得废话一大堆概念,关于ADT.NDK的概念要是你不懂,怎么会搜到这里来?所以你只需要根据下面的步骤来,就可以完成NDK环境搭建了. 步骤:(假设你未安装任何相关开发工具,如果已经安装了,就可以跳过) 一. 环境搭建 1. 安装 jdk   安装完毕后配置好环境变量(我安装的是jdk1.7) JAVA_HOME = C:\Java\jdk1.7.0_51 PATH = C:\Java\jdk1.7.0_51\bin CLASSPATH = .;%JAVA_HOME%/lib/dt.jar;%JA

Android NDK 环境搭建 + 测试例程(转)

懒得废话一大堆概念,关于ADT.NDK的概念要是你不懂,怎么会搜到这里来?所以你只需要根据下面的步骤来,就可以完成NDK环境搭建了. 步骤:(假设你未安装任何相关开发工具,如果已经安装了,就可以跳过) 一. 环境搭建 1. 安装 jdk   安装完毕后配置好环境变量(我安装的是jdk1.7) JAVA_HOME = C:\Java\jdk1.7.0_51 PATH = C:\Java\jdk1.7.0_51\bin CLASSPATH = .;%JAVA_HOME%/lib/dt.jar;%JA

Android NDK环境搭建

在Android上要想开发出高效率的软件,还是需要用到C/C++语言,要想在Java上开发C/C++语言就需要在IDE上安装NDK:在Android的官网上SDK开发环境已经包含了ADT插件,最新的Android开发IDE可以到官网下载:http://developer.android.com/sdk/index.html 由于最近Android官网和google在国内经常进不去,我就把下载的放到网盘,有需要的可以去下载:http://pan.baidu.com/s/1hq3iBGw 准备的文件

Android Studio环境下代码混淆+签名打包

Android Studio环境下代码混淆+签名打包 作者 Mr_冯先生 关注 2016.08.21 01:10 字数 1040 阅读 734评论 5喜欢 34 注:本文使用的Android Studio版本是 2.1.2. 做公司项目,需要对项目进行代码混淆+签名打包,然后就各种搜集查看资料,算是小有成果吧.周末无事就想着总结一下以后再用可做参考.如有不对的地方烦请各位大神指导-- 一.代码混淆 android studio进行代码混淆需要在两个地方做配置:1.添加自己的混淆规则到对应Modu

【转】Windows环境下Android NDK环境搭建

原文网址:http://www.metsky.com/archives/525.html 前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员来讲,基本够用了,由于Linux系统的权限限制和Android封装架构限制,很多涉及底层设备.接口.驱动控制的应用开发,不得不使用到本文的NDK开发环境(基于Android源码或内核源码修改),开发语言使用C/C++,NDK开发更接近于Linux开发,需要更多关于Linux应用编程知识.本文就介绍一

Windows环境下Android NDK环境搭建

前面介绍Windows下Android 开发环境配置,主要是面向JAVA开发环境,对只做APK上层应用开发人员来讲,基本够用了,由于Linux系统的权限限制和Android封装架构限制,很多涉及底层设备.接口.驱动控制的应用开发,不得不使用到本文的NDK开发环境(基于Android源码或内核源码修改),开发语言使用C/C++,NDK开发更接近于Linux开发,需要更多关于Linux应用编程知识.本文就介绍一下NDK环境搭建及基础编程思想. 本文演示环境:Windows 7 Ultimate+Cy

Linux下Android NDK环境配置以及配合eclipse使用NDK

最近由于项目中经常用到jni,在这里将使用jni不步邹分享给大家! 一.下载NDK http://developer.android.com/sdk/ndk/index.html 目前最新版本是r8(android-ndk-r8-linux-x86.tar.bz2) 二.配置环境 从r7版本开始,Linux下直接解压就可以使用,在windows下cygwin也已经集成在NDK里面了,解压完配置下环境变量就可以使用了. 在~/.bashrc(Linux下配置环境变量的文件)文件末尾加上: expo