使用ndk编译ffmpeg时学到的

使用ndk编译ffmpeg时学到的

由于一些原因,需要用ndk编译一个ffmpeg在安卓手机上进行mp4到gif的转换,在这个过程中学到了很多东西。

1、把一个视频存成MP4都比gif小很多。以前一直觉得gif格式是网络上传输非常好用的格式,还以为它体积很小。而且网络上能见到的动图基本都是gif格式的,包括QQ与微信等聊天软件发的表情也都是gif格式的,现在却发现gif格式的文件出奇的大。究其原因其实也很简单,gif保存的连续画面,每一帧都是单独的,没有用任何压缩算法,而mp4等视频都是有压缩算法的,再加上gif的画质明显不能满足需求,可以预见gif退出市场的那一天啊。imgur已经推出了gifv,拭目以待。

2、osx上的dyld和Linux上ld.so两个动态库装载器的区别

linux上动态链接库一般为.so文件,osx上一般为.dylib文件,两者都可以在相应平台上通过ld或者gcc生成。但是他们并不是只有平台不同这么简单,在生成过程和装载过程中都有些微的不同。

生成过程:

osx的gcc(实际就是clang)包含–install-name选项,在编译时,会将这个路径写入.dylib文件,当编译其它程序与该.dylib文件链接时,会把这个路径写入可执行程序中。这样运行可执行程序的时候,dyld实际上是直接到程序里面记录的路径去寻找动态链接库的,找不到才会搜索系统lib目录。这跟Linux中ld.so完全不同,ld.so在ld.so.conf中记录的路径中查找动态链接库,程序编译的时候也不会记录动态链接库的位置,而是仅记录名字。

以ffmpeg为例,先来看Mac,configure时指定了–prefix=/Users/ember/code/ffmpeg-2.5.3/mac和–enable-shared,make&&make install后查看ffmpeg的依赖如下

ffmpeg_on_mac

可以看到每一个动态链接库都是记录了绝对路径的。再看Linux,configure时指定了–prefix=/home/vagrant/ffmpeg和–enable-shared,make&&make install后查看ffmpeg依赖如下ffmpeg_on_linux

可以看到每个动态链接库都只记录了文件名。

装载过程:

这样的生成过程造成的差别是什么呢,对于osx的ffmpeg来说,已经可以直接运行了,./ffmpeg可以正常运行,因为所有的动态链接库都是绝对路径,dyld已经可以加载它们并且执行。而Linux上的ffmpeg无法正常运行,因为ld.so找不到ffmpeg需要的动态链接库,需要手动增加LD_LIBRARY_PATH才能正确执行。就这一点说,osx要方便多了,毕竟已经make&&make install了,Linux上程序竟然还不能运行,其实并不合理。

进一步来说,osx下的dyld基本是打酱油的,只负责链接就行了,不用负责搜索,因为动态库的绝对路径已经被指明了(当然绝对路径所指的文件不存在时dyld还是要搜索)。而ld.so则要负责找到动态库并链接。某种意义上来说,osx的做法是非常好的,编译与运行毕竟是一次编译终生运行的关系,将确定动态库路径的任务放到编译期显然是合算的。但这种做法也给后期的维护带来了开销,毕竟每次移动库的时候都不方便,osx提供了install_name_tool来做这件事。其实也可以感觉到,osx与Linux的两种方法其实体现了两种平台的价值观。

 

照例总结,就编译一个ffmpeg可以学到这么多可以说也是挺高兴的,虽然至我写这篇文章为止,Android上的ffmpeg还没跑起来。。。


未分类

发表评论

电子邮件地址不会被公开。 必填项已用*标注