由于VS2010工程里面用到了FFMPEG,因此想自己用VS2010编译FFMPEG,就可以通过编译生成的DLL及PDB进行调试了。
主要难点:
1、目前FFMPEG(3.2.4)支持的是C99标准,坑爹的Microsoft 直到VS2013才支持。如果使用的是VS2013及以上编译,本点跳过。
2、如何编译第三方库。由于项目中用到了水印功能,需要使用第三方库文件libfreetype。
3、可能会遇到的问题及解决方法。
环境准备:
这方面网上有很多资料可供参考。如:http://www.cnblogs.com/xylc/p/3683203.html。
FFMPEG我下载的版本是3.2.4
Freetype我下载的版本是2.7.1
编译:
环境搭建好后,我们就可以开始编译了。
1、命令行进入目录:$Mingw\msys\1.0 运行编辑过的 msys_vs2010.bat
2、将下载好的freetype-2.7.1 复制到与ffmpeg-3.2.4同级的目录
3、进入freetype-2.7.1 目录,先编译它 ./configure make make install
4、然后进入ffmpeg-3.2.4目录然后运行编译命令
./configure --extra-ldflags=-static-libgcc --enable-debug --disable-iconv --enable-shared --disable-static --enable-memalign-hack --disable-decoders --disable-protocols --enable-encoder=pcm_alaw --enable-encoder=pcm_mulaw --enable-encoder=adpcm_g726 --enable-decoder=pcm_alaw --enable-decoder=pcm_mulaw --enable-decoder=adpcm_g726 --enable-decoder=h264 --enable-decoder=mpeg4 --enable-decoder=mjpeg --enable-w32threads --enable-runtime-cpudetect --enable-protocol=file --enable-muxer=avi --enable-demuxer=avi --enable-muxer=mov --enable-demuxer=mov --disable-dxva2 --disable-gpl --disable-version3 --disable-nonfree --enable-libfreetype --pkg-config-flags="--static" --extra-cflags="-I/local/include" --extra-ldflags="-L/local/lib" --disable-optimizations--toolchain=msvc
其中: --enable-libfreetype 打开水印功能(drawtext)
--disable-gpl --disable-version3 --disable-nonfree 关闭版权信息
--toolchain=msvc 使用msvc进行编译
--extra-cflags="-I/local/include" --extra-ldflags="-L/local/lib" 指定头文件及库文件的路径
完成以上操作后,然后再make make install就可以了。
后续更改:
--enable-debug=3 改为 --enable-debug。使用--enable-debug=3 编译出来的pdb在调试时跟不进去,改为--enable-debug正常。
--disable-optimizations 增加此选项,关闭优化信息。方便查看调试信息。
详见:http://www.cnblogs.com/lingdhox/p/5746170.html
--enable-memalign-hack 在Thu, 24 Mar 2016 19:55:19 +0000后的版本里不支持这个选项
Drop memalign hack
It no longer serves a useful purpose.
详见:
http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=4fb311c804098d78e5ce5f527f9a9c37536d3a08
为了方便改动,特意在libavutil文件夹下面增加了一个global_vs2010.h头文件,内容如下:
#if defined(_MSC_VER)
#define strtoll _strtoi64
#endif
#if defined(_MSC_VER)
#define strtoull _strtoui64
#endif
#define va_copy(dest, src)(dest = src)
在用到的文件前面都加上文件引用#include "libavutil/global_vs2010.h"
相关问题:
理想情况下以上的操作都没有什么问题就可以直接使用了,但现实很残酷。下面是我在编译ffmpeg时碰到的问题及解决方法,记录下来以后好少走弯路。
1、freetype2 not found
-- ffmpeg 在使用第三方库时,需要通过pkg-config告诉freetype的地址。去网上下载一个pkg-config.exe 然后复制到$Mingw\msys\1.0\bin目录下,然后在ffmpeg-3.2.4目录下执行 export PKG_CONFIG_PATH="/local/lib/pkgconfig" 其中 /local/lib/pkgconfig是包含freetype2.pc的路径,如果这个文件不在这里请自行修改。freetype2.pc文件是在编译freetype时生成的。
在指定路径时,不能使用"export PKG_CONFIG_PATH="$local/lib/pkgconfig",因为$local 代表local为一变量,路径取的是变量的值,而不是"local/lib/pkgconfig", 正确的应该是 export PKG_CONFIG_PATH="/local/lib/pkgconfig"
编译时,具体的错误原因可以查看 config.log。
2、编译选项中去掉 -- disable-optimizations ,要不然会出现以下错误
cpu.o : error LNK2019: unresolved external symbol ff_get_cpu_flags_aarch64 referenced in function av_get_cpu_flags
cpu.o : error LNK2019: unresolved external symbol ff_get_cpu_flags_arm referenced in function av_get_cpu_flags
cpu.o : error LNK2019: unresolved external symbol ff_get_cpu_flags_ppc referenced in function av_get_cpu_flags
float_dsp.o : error LNK2019: unresolved external symbol ff_float_dsp_init_aarch64 referenced in function avpriv_float_dsp_init
float_dsp.o : error LNK2019: unresolved external symbol ff_float_dsp_init_arm referenced in function avpriv_float_dsp_init
float_dsp.o : error LNK2019: unresolved external symbol ff_float_dsp_init_ppc referenced in function avpriv_float_dsp_init
float_dsp.o : error LNK2019: unresolved external symbol ff_float_dsp_init_mips referenced in function avpriv_float_dsp_init
-- 主要是因为snprintf 是c99的函数,vs2010不支持,虽然用了c99conv.exe及c99wrap.exe但是还是不能make通过,原因不详。解决方法:
在libavutil\common.h中增加
#if _MSC_VER
#define snprintf _snprintf
#endif
4、make 时 fetestexcept、feclearexcept 报lnk2019错误。
-- 将Vf_drawtext.c中的代码注释,保留 intval = res;
feclearexcept(FE_ALL_EXCEPT);
intval = res;
if ((ret = fetestexcept(FE_INVALID|FE_OVERFLOW|FE_UNDERFLOW))) {
av_log(ctx, AV_LOG_ERROR, "Conversion of floating-point result to int failed. Control register: 0x%08x. Conversion result: %d\n", ret, intval);
return AVERROR(EINVAL);
}
5、lnk2005 memove already defined in libcmt.lib
-- 使用VS2010编译freetype release版本,工程路径为:$\freetype-2.7.1\builds\windows\vc2010。同时需要做如下设置
1、将 Runtime Library由/MD 改为/MT
2、Ignore Specific Default Libraries中添加MSVCRT.lib LIBCMT.lib
3、将编译生成的freetype.lib复制到VS的lib目录下 C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\lib
然后再编译
6、编译 Freetype ./configure时出现 error: C compiler cannot create executables
通过查看config.log日志,发现少了文件
c:/mingw/bin/../lib/gcc/mingw32/4.8.1/../../../../mingw32/bin/ld.exe: cannot find crtbegin.o: No such file or directory
从别的机器复制过来就可以了。
7. make 时提示调用 strtoll方法失败,原因同1
修改方法:
在调用strtoll方法的地方前面加上
#if defined(_MSC_VER)
#define strtoll _strtoi64
#endif
查看 Config.log很重要。
make: Nothing to be done for `all' 解决方法
解决方法: make clean
make
Package freetype2 was not found in the pkg-config search path.
Perhaps you should add the directory containing `freetype2.pc'
to the PKG_CONFIG_PATH environment variable
--- export PKG_CONFIG_PATH="/local/lib/pkgconfig"
其中 /local/lib/pkgconfig 是包含freetype2.pc文件的路径。