使用mingw编译可以让VC使用的动态链接库的ffmpeg

1,下载编译环境 msys & mingw (可以到google code  中找,有支持中文的合集)
解压下来就可以直接用了
2,配置 msys & mingw 在 etc 目录中 找到 fstab 文件 添加 mingw目录项 如 C:\MSYS\mingw  /mingw
3, 在msys.bat  开头加上 VC的环境设置  如 Call "D:\Program Files\VC6.0\VC98\Bin\VCVARS32.BAT"
4,在网上找yasm.exe 并把他复制到mingw  的bin 目录下
5,使用bash  切换到ffmpeg的目录下
键入命令./configure --enable-shared --disable-static --enable-memalign-hack --enable-w32threads --prefix=d:/ffmpeg
 
这里的--enable-w32threads 是因为我的phread 库编译失败 ,也不知道是什么原因,就先用这个了
 
完成,并没有错误后
键入命令 make
而后 make install
 
 然后你就发现在你指定的目录 D:\ffmpeg 中的头文件 lib库 dll等都在这里面了,这样ffmpeg的编译环境就帮我生成了一个SDK,这个SDK在linux上用C来开发是没有问题的,我们需要使这个SDK在MS Visual Studio 开发环境中能用,编译的时候会碰到一大堆问题。我的环境是VS2008。
 
建立工程:
我们用ffplay验证我们的SDK,如果发现SDK问题,就可以得到及时的解决。建立一个ffplay的空工程,把ffplay.c,cmdutils.c,cmdutils.h,config.h导入这个空工程中,然后在VS2008中配置头文件目录和lib库目录(注意:ffplay需要用sdl,把sdl也加进入)
 
编译并排错
下面是在VS2008中,编译ffplay出现的错误,有些错误时ffplay中出现的,有些事sdk的问题。
fatal error C1083: 无法打开包括文件:“inttypes.h”: No such file or directory
在vs2008下没有这个文件,实际上这个文件无非也就是一些整形定义而已,可以直接注释掉这个包含,自己创建这个文件,放到inclue\libavutil下,include改为#include "libavutil/inttypes.h"
 
fatal error C1083: 无法打开包括文件:“stdint.h”: No such file or directory
copy C:\MSYS\include下的stdint.h到libavutil中。修改#include <stdint.h>为#include “stdint.h”
 
fatal error C1083: 无法打开包括文件:“libavdevice/avdevice.h”: No such file or directory
用不着,直接注释
 
ffplay.cpp中报错
fatal error C1083: 无法打开包括文件:“libavcodec/audioconvert.h”: No such file or directory
fatal error C1083: 无法打开包括文件:“libavcodec/colorspace.h”: No such file or directory
make install安装的头文件不全,从libavcodec中copy这两个头文件
 
fatal error C1083: 无法打开包括文件:“unistd.h”: No such file or directory
许多在Linux下开发的C程序都需要头文件unistd.h,但VC中没有个头文件,
所以用VC编译总是报错。把下面的内容保存为unistd.h,可以解决这个问题。
 
 
 
#ifndef _UNISTD_H
#define _UNISTD_H
 
#include <io.h>
#include <process.h>
 
#endif
 
提示
static int wanted_stream[AVMEDIA_TYPE_NB]={
    [AVMEDIA_TYPE_AUDIO]=-1,
    [AVMEDIA_TYPE_VIDEO]=-1,
    [AVMEDIA_TYPE_SUBTITLE]=-1,
};语法错误
 
VC的标准C++不支持这个赋值方式,我们改为
static int wanted_stream[AVMEDIA_TYPE_NB]=
{
     -1,
     -1,
     0,
     -1,
     0
};
 
error C3861: “rint”: 找不到标识符
rint函数是个四舍五入的方法,我们自己实现
inline long rint(double x)
{
if(x >= 0.)
 return (long)(x + 0.5);
else
return (long)(x - 0.5);
}
 
指示FFTSample data[2][2*nb_freq];表达式错误
我们知道标准C++不支持动态数组。修改为
FFTSample *data[2];
data[1] = malloc(sizeof(FFTSample) * 2*nb_freq);
data[0] = malloc(sizeof(FFTSample) * 2*nb_freq);
最后释放
free(data[0]);
free(data[1]);
 
error C3861: “usleep”: 找不到标识符
VC中没有usleep,usleep是微妙级别的,所以需要把代码改为
usleep(is->audio_st && is->show_audio ? rdftspeed*1000 : 5000);
to
Sleep (is->audio_st && is->show_audio ? rdftspeed*1 : 5);
 
指出    ap->time_base= (AVRational){1, 25};语法错误。
还是标准C++不支持这种语法,修改为
ap->time_base.num = 1;
ap->time_base.den = 25;
 
error C2054: 在“inline”之后应输入“(”
这是因为c不支持inline,我们把cmdutils.c改为cmdutils.cpp,把ffplay.c改为ffplay.cpp。
 
链接错误:
现在编译可以通过,但是现实一大堆库没有链接(好像有77个链接错误),把
avcodec-52.lib
avformat-52.lib
avutil-50.lib
swscale-0.lib
加进去还是没用,发现是我们用了ffplay.cpp,需要在ffmpeg所有头文件中加。
#ifdef  __cplusplus
extern "C" {
#endif
 

#ifdef  __cplusplus
}
#endif
这样就可以正确链接了。
 
最后可以正确编译出ffplay.exe。我们把include、lib和ffmpeg编译出来的dll打包,就可以发布了。
展开阅读全文

没有更多推荐了,返回首页