Android NDK 下 FFMPEG 的编译选项详解

在Android NDK下编译FFMPEG,除了要编写Android.mk文件外,还需要编写Application.mk来指定编译选项

一. 指定编译目标cpu的类型,使用APP_ABI 选项

如: APP_ABI := armeabi

APP_ABI :=armeabiarmeabi-v7a

APP_ABI := x86

目前,在构建 NDK 库时,可以使用三种支持的应用二进制接口(ABI):

所有这些 ABI 选项均支持浮点运算。除非使用的是特定于 ARM* 的汇编指令,否则在将代码移植到 x86 时不会发生问题。其优势在于,如果碰巧您的应用仅针对‘armeabi’进行编译,而现在需要支持 x86,则您在进行大多数浮点运算时均能感觉到性能提升。

二. 指定优化级别,使用APP_OPTIM 选项

有release和debug两种选择,release表示输出二进制文件被优化,debug表示没有被优化,可以调试

如:APP_OPTIM := debug

三. 指定c,,c++编译选项,使用APP_CFLAGS 和APP_CPPFLAGS选项,还有APP_STL

一些常用的c,c++编译选项介绍

-O0:无优化(默认)

-O和-O1:使用能减少目标文件大小以及执行时间并且不会使编译时间明显增加的优化.在编译大型程序的时候会显著增加编译时内存的使用.

-O2: 包含-O1的优化并增加了不需要在目标文件大小和执行速度上进行折衷的优化.编译器不执行循环展开以及函数内联.此选项将增加编译时间和目标文件的执行性能.

-Os:专门优化目标文件大小,执行所有的不增加目标文件大小的-O2优化选项.并且执行专门减小目标文件大小的优化选项.

-O3: 打开所有-O2的优化选项并且增加 -finline-functions, -funswitch-loops,-fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize优化选项.

“branch out of range errors“Relocation value does not fit in 26 bits.具体用法可以参考

-ffast-math -ffast-math, -fno-fast-math 设定 -fno-math-errno, -funsafe-math-optimizations, -fno-trapping-math, -ffinite-math-only, -fno-rounding-math, 以及 -fno-signaling-nans 这几个选项,以及设定预先处理器的 __FAST_MATH__ 宏。这些技术虽然较快,但是违反 IEEE 或 ISO 的规则,并且很有可能让程序算出错误的数值。

浮点优化选项 -ffast-math:极大地提高浮点运算速度

具体的分析可以参考

-fprefetch-loop-arrays -fprefetch-loop-arrays, -fno-prefetch-loop-arrays 若目标机器支持,在存取大型数组循环执行之前预先将数组加载至内存。于 -Os 中关闭。 其实不太会有需要存取大型数组的循环 (多媒体、数据库、科学计算软件中才比较常见),所以您可以放心将此选项关闭。

-fforce-mem -fforce-addr -fforce-mem, -fno-force-mem -fforce-addr, -fno-force-addr 强制在运算前将内存中的数值 (mem) 或内存位置 (addr) 复制到缓存器中。启动这两个选项可以做出较好的程序代码。 这两个是好东西,启动它们!其中 -fforce-mem 已在 -O2, -O3, -Os 中启动,所以若您有用这三个选项的其中一个,只要 -fforce-addr 就够了。 -fomit-frame-pointer -fomit-frame-pointer, -fno-omit-frame-pointer 若非必要,不将函式的 frame pointer 放进缓存器中。这将避免您的程序储存、设定、以及还原 frame pointer;也在许多函式中省下一个缓存器。这个选项可能让某些平台上的除错工作变成不可能!。若平台支持不使用 frame pointer 除错,这个选项将在 -O, -O2, -O3, -Os 中启动。 很抱歉,x86 刚好是非这个不可才能除错的平台之一。但是… 您想对您的桌面进行除错吗?若答案为非,您可以放心启动这个选项。 -finline-functions -finline-functions, -fno-inline-functions 将所有简单的函式整合进呼叫他们的函式中。编译器会自动试探并决定那些函式值得被整合。于 -O3 时启动。 虽然这个选项会增加程序大小,但是他却是个增进效能的好东西。我建议您在这里启动它,然后使用下面一个指令指定 inline 条件。

-finline-limit -finline-limit=n n 为决定函式是否能被 inline 的伪指令长度。预设的值为 600。 这个数值越小,程序启动的速度越快,但是运算的速度越慢。作为桌面使用,我建议 -finline-limit=400。 -fmove-all-movables -freduce-all-givs -fmove-all-movables, -fno-move-all-moveables-freduce-all-givs, -fno-redduse-all-givs 这两个是循环最佳化技术,将无关循环内容的运算改在循环外执行。编译出的执行档可能更快也可能更慢,结果跟程序的写法有很大的关系。虽然说效能跟程序写法有关,但是大部份的状况下这两个选项会做出比较小与比较快的程序代码,所以我建议您启动他们! -freorder-blocks -freorder-functions -freorder-blocks, -fno-reorder-blocks-freorder-functions, -fno-reorder-functions 藉由重新编排程序区块来增进效能以及减少执行档大小。 这两个也是好东西,所以我建议您启动它们。缺点是会让编译时间变长。 -freorder-blocks 于 -O2, -O3 时启动,于 -Os 中关闭。-freorder-functions 于 -O2, -O3, -Os 时启动。 -fexpensive-optimizations -fexpensive-optimizations, -fno-expensive-optimizations 执行几个会加长编译时间的非主要最佳化程序。于 -O2, -O3, -Os 中预设开启。 虽然会增加编译时间,但是能增加效能也能减少执行档大小,所以建议启用。

人生最好的旅行,就是你在一个陌生的地方,

Android NDK 下 FFMPEG 的编译选项详解

相关文章:

你感兴趣的文章:

标签云: