(注意:请务必先阅读:七,后记补充:)
ffmpeg是一个开源的多媒体库,使用非常广泛。
在linux下编译ffmpeg非常简单,而在windows下编译就不是那么容易了。一般在windows下使用MinGW的gcc toolchain进行编译,这样的话,因为ffmpeg的导出函数均是C风格,因而gcc编译的lib可以被vs链接。但是gcc的debug符号与vs的debug符号(*.pdb)是无法兼容的,因此我们用vs来开发基于ffmpeg的程序时无法深入ffmpeg内部进行debug,这不管对于学习还是工程使用都不是那么友好。因而,使用同一套编译系统好处多多。
本篇博文向你展示从头到尾怎么在windows下用vs2010编译ffmpeg,以及一个基于ffmpeg的栗子。同样适合于vs2012/vs2013等。
注:请不要用这篇博文的方法去尝试在VS2010以下版本编译ffmpeg,我试过在vs2005中编译,各种问题!官方也没有在vs2010以下版本中进行过编译测试。
一,下载ffmpeg及第三方程序:
1,ffmpeg官网:http://ffmpeg.org/
2,ffmpeg git 地址 : git://source.ffmpeg.org/ffmpeg.git (注意:clone代码之前先在git命令行中设置!!!:git config --global core.autocrlf false )
3,MinGW : http://www.mingw.org/ ,运行下载的MinGW安装管理器,包含msys。假设安装好后MinGW路径为:d:/MinGW ,则msys路径应为:d:/MinGW/msys 。将:d:/MinGW/bin和d:/MinGW/msys/1.0/bin加到系统path环境变量中;
4,yasm : http://yasm.tortall.net/ , 改名叫yasm.exe,复制到:d:/MinGW/msys/1.0/bin 目录下;
/********************如果是vs2013 + ,则下面两个(5,6)不需要安装 ***********************/
5,c99-to-c89 : https://github.com/libav/c99-to-c89/downloads , 将c99conv.exe和c99wrap.exe复制到:d:/MinGW/msys/1.0/bin 目录下;
6,C99头文件inttypes.h和stdint.h : http://code.google.com/p/msinttypes/downloads/list ,将此两个头文件复制到: D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include 目录下(自行修改为自己的安装目录);
二,编译之前的设置:
1,复制:d/MinGW/msys/1.0/msys.bat 到同目录下,改名叫做msys_vs2010.bat,在msys_vs2010.bat开头部分添加:call "D:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat" ;
2,重命名 d:/MinGW/msys/1.0/bin/link.exe 为link_renamed.exe ,这一步是防止这个link.exe与vc的link.exe发生冲突,编译完成之后记得修改回来;
2,打开msys_vs2010.bat,切换到ffmpeg目录下。
到这里为止,所有的编译之前的工作就完成了。
三,配置编译:
1,配置:ffmpeg编译配置选项很丰富,详细请运行“./configure --help > ffmpegcfg.txt ”查看其选项。这里我的选项是:
静态库:./configure --enable-static --prefix=./vs2010_build --toolchain=msvc
动态库:./configure --enable-shared --prefix=./vs2010_build --toolchain=msvc
2,编译:make & make install ;
3,修改回来重命名的 d:/MinGW/msys/1.0/bin/link_renamed.exe 为 link.exe 。
编译时间与机器性能相关,可能会很慢。
至此在vs2010_build就生成了编译好的ffmpe库,有4个目录,bin、include、lib、share 。
四,一个栗子:
OK,ffmpeg编译成功,让我们以一个栗子结束这次编译体验。
在 vs2010_build/share/ffmpeg/examples 目录下有若干个示例。
我们随便找一个 avio_reading.c 拖到我们的test_ffmpeg工程(vs2010),记得在这之前要配置include与lib路径(很简单,就不详细说了)。
链接库中加入: ws2_32.lib;libavcodec.a;libavdevice.a;libavfilter.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;
编译,链接,运行,OK!
五,注意:
1,在C++源文件中include ffmpeg头文件时需要加上:
#ifdef __cplusplus
extern "C"{
#endif
//… includes
#ifdef __cplusplus
}
#endif,
2,ffmpeg使用的是C99,但是坑爹微软直到vs2012好像都还是C89,所以不排除使用中会有些头文件中宏、函数会出编译错误。
常见错误:(此处为骗搜索流量记,严格按照本篇博文步骤的童鞋应该不会出现如下错误)
1, configure时出现“c99wrap cl is unable to create an executable file.” 且在config.log中最后发现“Command line error D8021 : invalid numeric argument”,你可能在用vs2010以下版本。官方未对此版本进行测试,所以,最好还是用新版本的vs。
2, configure时出现“c99wrap cl is unable to create an executable file.” 且在config.log中最后发现“link: invalid option -- o”,是因为msys/1.0/bin/link.exe与vs的link.exe冲突,将msys/1.0/link.exe临时改下名字,比如link_gnu.exe,编译完成后再改回来。
六,参考:
1,http://ffmpeg.org/platform.html#Microsoft-Visual-C_002b_002b-or-Intel-C_002b_002b-Compiler-for-Windows
2,http://stackoverflow.com/questions/17218902/connect-ffmpeg-to-visual-studio-2008
3,https://github.com/xylcbd/ffmpeg_study
4,https://trac.ffmpeg.org/ticket/2610
七,后记补充:
很遗憾的告诉大家,ffmpeg源代码还是蛮坑的,充斥着类似于下面的代码:
if (CONFIG_H264_VDPAU_DECODER && h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) ff_vdpau_h264_picture_start(h);
这里,CONFIG_H264_VDPAU_DECODER是一个宏,在configure时关掉这个宏,那么ff_vdpau_h264_picture_start函数应该是永远不可能执行到,然后这段会被编译器给优化掉。但,如果你想debug进去看ffmpeg的代码,那你就不应该打开编译器的优化选项(设置:--disable-optimizations),如此以来将使得编译器在这个obj中加上外部ff_vdpau_h264_picture_start符号,但实际上因为configure设置,外部某个包含此符号的cpp并没有被编译,链接时链接器试图查找这个符号,没有找到,则产生link error。
打开优化选项,同时enable debug(--disable-optimizations --enable-debug=3)。可以进行debug,但可能看的很不爽,有的函数进不去,有的函数会跳来跳去(单步debug时)。
大家,三思。