用VC编译ffmpeg(包括汇编优化) 的心得和体会

来源:互联网 发布:python抓取微信朋友圈 编辑:程序博客网 时间:2024/06/07 05:22


用了几年的ffmpeg,感觉ffmpeg真是博大精深,很多播放器,转码工具都离不开它。之前一直是用MinGW来编译windows下用的ffmpeg,调试虽然有GDB,但是感觉还是很不方便,就下决心要用VC编译出一个版本。(当然网上有很多VC版本的ffmpeg,网友分享的,包括ffdshow里面的,但这些都是不带汇编优化的,这样ffmpeg的编解码效率很低很多很多)。从开始做到最后做完,差不多经过一个月的时间,遇到的bug也差不多修改完了。现在ffmpeg.exe 还有ffplay.exe都可以单步调试了,除了用GCC和yasm编译的个别文件,其他的文件都能完全调试,简单说下我的过程,希望对大家有帮助

一,需要intel编译器,主要是因为VC不知道C99,所以结构体赋值啊,用变量定义数组啊,所有变量的定义必须放在使用之前啊 这类问题,用intel编译器是可以解决这些问题的。
二,需要GCC,主要是很多_mmx.c的文件里面内嵌了汇编,这种汇编是AT&T语法的汇编,与intel语法的汇编有很大差异,所以必须用GCC来编译这些文件。
三,需要yasm.exe,这个就不多说了,主要是用来编译*.asm汇编文件的。
四,最关键的需要下载一份ffmpeg的代码了。我下载的是最新的ffmpeg-0.10版本。

有了这些工具,就完事具备,只欠下功夫了,哈哈

一、先用Mingw编译一次整个ffmpeg工程,生成了很多.o文件和.d文件,有些文件就没有生成对应的o文件,那是因为有的文件不需要编译或者这个.c文件被包含到其它文件里了,例如一些_template的C文件。这样你在新建VC工程的时候就知道什么文件改加入到工程,什么文件不应该加入。另外就是 configure脚本生成的config.h在VC编译时也需要它。

二、建立好libavutil 、libavcodec、libswscale、libavformat,ffmpeg、ffplay等工程后,就逐个编译了,最开始需要先编译libavutil.。因为其它库都需要依赖它。我当时编译的时候是逐个文件单独编译,再逐个工程编译,编译过程中会遇到很多很多编译错误和链接错误,慢慢来解决。

三、用变量定义数组在链接时候会提示找不到chk_stk符号,找了半天,发现Mingw把这个函数放在 libgcc.a里,所以链接的时候把这个库给包含进来就好了。另外由于VC的debug版本是不带优化的,所以ffmpeg代码中有很多if(宏) {某函数} 这种代码,当宏的值为 0的时候,GCC会把{ }里这些代码优化掉,就不去编译了,而VC在Debug模式下,会去链接这个函数,而往往这个宏为0的时候这个函数是不需要编译,也不用链接的,所以会提示找不到符号。这样可以把这种代码修改成#if  {某函数 }的形式,也可以把debug下“优化”选项修改成O1,这样就好了。编译和链接过程中越到很多问题,现在想不起来了,等想起来再来补充吧。

四、运行时的错误及修改。
1)编译除了ffmpeg.exe,非常激动,赶紧跑个文件试试,哈哈,果然一跑就崩溃了,找了找原因,发现ffmpeg里关于数学运算的很多函数算出来的值都不对,重新定义修改后才可以。类似sqrt.、 lrint之类的函数,估计是intel编译器的原因吧。
2)汇编优化是ffmpeg解码器速度快的主要原因,mmx sse sse2 avx等等,但是这些函数在用GCC 或者yasm编译自后会各种崩溃,后来发现 SSE代码运算时的所有数据必须是16字节对齐的。而VC调用函数时对齐方式(4字节自己)和GCC(16字节对齐)不同,这样在VC调用GCC编译的SSE相关代码的函数时,就会出现崩溃问题,最后在函数前加了attribute_align_arg后搞定。

还有很多问题,等想明白了再上来补充吧,目前ffmpeg.exe ffplay.exe运行的还算正常,哈哈

补充一下,我用的Visula studio 是2010。intel编译器是Intel(R) C++ Composer XE 2011 ,只有这个版本以上的才支持VC2010,
具体版本是 w_ccompxe_ia32_2011.9.300。目前单步调试 运行 都没有问题。



大家如果遇到问题,需要问的可以联系我
1923666095@qq.com   用QQ或者邮件联系都可以。


0 0
原创粉丝点击