首页 > 代码库 > 又是正版!Win下ffmpeg源码调试分析二(Step into ffmpeg from Opencv for bugs in debug mode with MSVC)

又是正版!Win下ffmpeg源码调试分析二(Step into ffmpeg from Opencv for bugs in debug mode with MSVC)

最近工作忙一直没时间写,但是看看网络上这方面的资源确实少,很多都是linux的(我更爱unix,哈哈),而且很多是直接引入上一篇文章的编译结果来做的。对于使用opencv但是又老是被ffmpeg库坑害的朋友们,可能又爱又恨,毕竟用它处理和分析视频是第一选择,不仅是因为俩者配合使用方便,而且ffmpeg几乎囊括了我所知道的所有解编码器,但是正是因为这个导致了一些bug很难定位,所以有必要考虑一下如何快速定位你的ffmpeg bug。

sorry,废话多了。首先给个思路:

1.使opencv 的highgui project能Link到上文build出来的ffmpeg 文件(lib,dlls。。。)

2.然后尝试在MSVC下debug时,完成宏的修改,使其在vc下可用。

3.完成cap_ffmpeg.cpp 的修改,使其正确加载ffmpeg 的动态库,这样程序才可以debug到source。这一步,网上很少提到,只能自己开动脑筋了。

ok,进入正题:

1.LNK property 配置:

右键--》项目--》属性,在debug mode(当然你也可以是全模式下),进入VC++ Directories ,设置"你的ffmpeg的/bin路径" 到 Executable Directories,当然你最好也把这个路径放到计算机的PATH中,有时候vc找不到。如果还不行,就提出所有dll,扔到system下(注意要放对位置,system有2种)

进入C/C++,设置include 路径,ok。

然后进入其下面的Preprocessor下的Difintions中,加入

USE_FFMPEG
__STDC_CONSTANT_MACROS

(为什么加这个,其实就是为了让MSVC认识 gcc中一些特有的宏,这在上一篇文章中都有解释过编译核心的选择问题)

进入Linker--》General:设置Additional Libaray Directories ,为了让MSVC可以不被ffmpeg原生的gcc宏影响,这里要使用到MinGW的gcc库,同时要让opencv看到你的ffmpeg libs,dlls,所以加入:

C:\MinGW\lib\gcc\mingw32\4.8.1

F:\ffmpeg-dev\bin(这里就是libs和dlls)

进入Input,设置所有ffmpeg的libs,把他们在Additional Dependencies中一一列出。

注:这里如果你要配置static库用来debug的话,为了防止Image Safe的erro,可以关闭Linker下Advanced的"Image Has Safe Exception Handlers".

ok,至此。我们就完成了highgui的配置。

下面做第二步:

要从git上下载两个header files:(直接gg 第一个文件名就可以了)

inttypes.h 

stdint.h(不要把它与vc下的混淆,这个文件的一些int类型定义是针对上面的文件的)

这里的2文件主要定义了ffmpeg的gcc形式的macro和basic data type。

然后扔到ffmpeg的include folder下。

ok,接着就开启 opencv的 ffmpeg impl接口,我们以前见过的opencv_ffmpegxxx.dll的函数原型都封装于此,具体你可以到dll中看看。

下面贴一下我对这个文件的modify:

#include "precomp.hpp"

#if defined HAVE_FFMPEG //&& !defined WIN32//修改
#include "cap_ffmpeg_impl.hpp"
#else
#include "cap_ffmpeg_api.hpp"
#endif

第二个更改:

icvInitFFMPEG()
{
#if 0//defined WIN32 || defined _WIN32//修改
# ifdef HAVE_WINRT
const wchar_t* module_name = L"opencv_ffmpeg"
CVAUX_STRW(CV_MAJOR_VERSION) CVAUX_STRW(CV_MINOR_VERSION) CVAUX_STRW(CV_SUBMINOR_VERSION)
#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__)
L"_64"
#endif
L".dll";

icvFFOpenCV = LoadPackagedLibrary( module_name, 0 );

# else
const char* module_name = "opencv_ffmpeg"

CVAUX_STR(CV_MAJOR_VERSION) CVAUX_STR(CV_MINOR_VERSION) CVAUX_STR(CV_SUBMINOR_VERSION)

#if (defined _MSC_VER && defined _M_X64) || (defined __GNUC__ && defined __x86_64__)
"_64"
#endif
".dll";

icvFFOpenCV = LoadLibrary( module_name );
# endif

ok,保存。

下面修改,cap_ffmpeg_impl.cpp,这就是opencv和ffmpeg的链接核心,

第一部分要修改的:


#include "cap_ffmpeg_api.hpp"
#include <assert.h>
#include <algorithm>
#include <limits>
///Ek
#if _MSC_VER//修改
#define snprintf _snprintf
#endif
///end

这个就是为了让MSVC躲避gcc语法的编译麻烦。

第二部分:


#ifdef __GNUC__
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#define __STDC_CONSTANT_MACROS ///ek修改
#ifdef __cplusplus
extern "C" {
#endif

到此,所有的修改都完成了,保存,F5.你就进入了一个神奇的ffmpeg世界。

Thanks from EK,enjoy it。

注:转载请注明,谢谢。

下一次,会找点时间,写一下ffmpeg的源码分析。。。。