Windows下使用Visual Studio 2010 编译ffmpeg全过程

(注意:请务必先阅读:七,后记补充:)

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/vs2017等。

注:请不要用这篇博文的方法去尝试在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" ;(若是vs2017则路径为 C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvars32.bat,不同的vs版本vcvars32.bat所在路径可能有差异,具体用everything搜即可)

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 ;

若make 报错 common.mak:139: *** missing separator. Stop. 表示没有 git config --global core.autocrlf false,解决:

git config --global core.autocrlf false
#然后运行下面的命令删除ffmpeg代码,并重新获取一下即可
git rm --cached -r .
git reset --hard

3,修改回来重命名的 d:/MinGW/msys/1.0/bin/link_renamed.exe 为 link.exe 。

编译时间与机器性能相关,可能会很慢。

至此在vs2017_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,编译完成后再改回来。

3.
fftools/cmdutils.c(1119): error C2065: “slib”: 未声明的标识符 
fftools/cmdutils.c(1119): error C2296: “%”: 非法,左操作数包含“char [138]”类型 
fftools/cmdutils.c(1119): error C2059: 语法错误:“数字上的错误后缀” 
fftools/cmdutils.c(1119): error C2059: 语法错误:“%” 
fftools/cmdutils.c(1119): error C2017: 非法的转义序列 
fftools/cmdutils.c(1119): error C2001: 常量中有换行符 
fftools/cmdutils.c(1150): error C2143: 语法错误: 缺少“)”(在“*”的前面) 
fftools/cmdutils.c(1150): error C2143: 语法错误: 缺少“{”(在“*”的前面) 
fftools/cmdutils.c(1150): error C2059: 语法错误:“)” 
fftools/cmdutils.c(1151): error C2054: 在“options”之后应输入“(” 
fftools/cmdutils.c(1252): error C2143: 语法错误: 缺少“)”(在“*”的前面) 
fftools/cmdutils.c(1252): error C2143: 语法错误: 缺少“{”(在“*”的前面) 
fftools/cmdutils.c(1252): error C2059: 语法错误:“)” 
fftools/cmdutils.c(1253): error C2054: 在“avclass”之后应输入“(” 
fftools/cmdutils.c(1261): error C2275: “AVInputFormat”: 将此类型用作表达式非法 
打开ftools/ffprobe.c fftools/cmdutils.c ,搜索CC_IDENT这个宏(这个宏有问题),注释掉

//av_log(NULL, level, "%sbuilt with %s\n", indent, CC_IDENT);
//print_str("compiler_ident", CC_IDENT);

六,参考:

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时)。

大家,三思。

 

你可能感兴趣的:(FFmpeg)