的移植
FFmpeg是一个集录制、转换、音/视频编码解码功能为一体的完整的开源解决方案。但本文中播放器只需要FFmpeg中对文件解封装及音视频解码部分的功能,若将FFmpeg整个解决方案全部移植到目标平台上会造成大量的代码冗余。并且FFmpeg代码的开发时基于Linux操作系统的,并没有考虑到手机平台的处理能力小,能源不足等限制,因此针对手机上特定功能需求将FFmpeg代码进行修剪及优化是十分重要的。
3.1FFmpeg修剪及优化
从FFmpeg如此庞大并且代码结构复杂的源代码中找出本文需要的代码确实是一项非常艰难的
工作。在Linux下编译运行FFmpeg代码时需要经过configure、make、makeinstall三步才能将FFmpeg正确的编译到Linux系统当中。其中configure阶段会生成一个configure.h和make文件,从这两个文件中可以查找出该次编译都编译了那些文件。经研究发现在configure源代码的时候可以加入很多配置参数,其中参数分为基本选项参数、高级选项参数还有专门提供的优化参数。优化参数主要负责配置在编译时需编译的内容。对FFmpeg的修剪也恰是将本系统中不需要的文件去除,因此本文利用选择适当的优化参数的方法找出播放器所需文件。对这些参数仔细研究后,得出编译时设置的参数如下:./configure--enable-version3--disable-encoders--enable-encoder=h263--enable-encoder=amr_nb--disable-parsers--disable-bsfs--enable-muxer=tgp--disable-protocols--enable-protocol=file。以上面所示的参数配置编译源文件时,系统只将h263、amr_nb的编码方法和3gp的文件封装格式及其所有的解码格式、解封装文件的源代码部分编译到了链接库。此时被编译到链接库的源代码集合即为本文所需的源代码有效集,通过查找configure.h和make文件中的后缀名为.o文件,后缀名为.o的文件是编译.c代码时生成的目标文件,每一个被编译的.c文件都会生成.o文件,所以通过查看所有的后缀名为.o的文件名,便可得知在该配置参数下被编译源文件有哪些,因此可以得出本文所需编译的源文件最小集合。FFmpeg开源代码虽然能够跨平台编译运行,但其代码的设计都是针对于PC机而言的,PC机和手机从CPU处理能力、能源、内存等各方面的资源都具有很多大差异,本文中针对手机的特点主要从以下几个方面优化代码:1.去除冗余代码、规范
程序结构、减少if-else的判断、调整局部和全局变量、使用寄存器变量代替局部变量,减少不必要的代码冗余,去除FFmpeg调试过程中的打印语句;2.用逻辑移位运算代替乘除操作,因为乘除运算指令的执行时间远远大于逻辑移位指令,尤其是除法指令,使用逻辑移位运算可以减少指令的运行时间;3.注意循环函数的调用,尽量减少多重循环的使用,编写代码时尽量减弱上次循环与
下次循环的相关性,减少不必要的代码计算量;4.设置合理的缓存。针对FFmpeg移植的目标平台Android平台,设置适合此本台的缓存大小;。这里对具体代码的修改就不一一重复了。
3.2FFmpeg移植
Google发布的NDK的makefile文件即Android.mk文件语法和普通的makefile文件有很多不同之处,在跨平台编译FFmpeg源代码时并不能使用原有的makefile文件。所以移植的先决条件就是将FFmpeg里的makefile文件全部替换为NDK中的Android.mk文件。通过分析FFmpeg的模块结构得知avutil是基础模块,avcodec模块的编译基于已经编译好的avutil模块,avformat基于前两者,按照这种模块结构本文编译移植的顺序为avutil、avcoedec、avformat,编译的步骤详细说明如下:1.关于config.h和config.mak首先说明一下FFmpeg自带的makefile的框架,FFmpeg在经过configure命令之后会产生一个config.h文件和一个