ffmpeg在windows下使用MinGW+msys+VS2015编译(x86或64版本,链接x264库,VS2015中可debug调试)

参照官网链接: https://trac.ffmpeg.org/wiki/CompilationGuide/MSVC部分修改

本文主要介绍使用MSVC工具链配合MinGW编译ffmpeg等相关库,供VS调用。使用VS2015作为样板,实际中,VS2013也是可行的(可以参照之前一篇,年代久远,有一些小错误,不再那篇基础上进行更新了)

需要了解的是:
MinGW本身的目的就是使用GCC的工具链可以编译出windows环境可以执行的exe文件,因此,如果只是需要编译出ffmpeg可执行文件,不需要vs调试,在下文中----toolchain=msvc或者CC=cl这样的语句删除即可。即:可按照官网等其他文章的介绍,按照linux的环境直接编译。对于FFmpeg链接x264时,需要指定库目录以及include目录 【–extra-ldflags=-L[lib目录地址] --extra-cflags=-I[include目录地址]】,-L与目录间无空格,具体的编译configure参数后面也会进行简单的介绍。

####注意,下面的关于mingw与msys的介绍都是较老版本的。关于msys2与minGW64移步备份 或者 [原文]
####下面主要是介绍x86版本的编译
64位的编译主要参照x86版本,基本相同,只用修改以下几点:

  1. msys.bat里面改为 call “C:\software\Microsoft Visual Studio 14.0\VC\bin\amd64\vcvars64.bat”
  2. 然后就可以正常按x86的命令编译了,不用特别的加–arch=x8_64或–host之类
  3. 遇到x264lib找不到时,x86版本是将lib文件放到C:\software\Microsoft Visual Studio 14.0\VC\lib,而x64是放到C:\software\Microsoft Visual Studio 14.0\VC\lib\ amd64 \中 用完记得删掉

####注意事项
####把后面编译生成的库文件使用可能出现的问题都提前说明一下,因为大家找到这些文章主要目的也是自己已经参照别人的记录遇到了问题编译不通过,可能看到这些错误原因就不用往下看了,节省大家时间

  1. ffmpeg链接x264库时,编译时可能会出现找不到libx264的问题,因为网上有些资料可能会有错误,主要是因为使用MSVC工具链进行链接是编译选项是–extra-ldflags=-LIBPATH:[lib路径]而不是简单的-L,-L是GUN的工具链的编译选项。

  2. 此外,授人以渔,在msys窗口内看到编译不通过只是一句找不到x264而已,但是我们可以通过打开ffmpeg目录下的config.log查看错误原因,比如有时候是找不到.h文件,那就是就是–extra-cflags路径配置错误,有时候明明–extra-ldflags也配置好了,也使用了-LIBPATH但是还是错误,打开文件可以看到它默认是在lib目录下查找libx264.lib,差一个字都不对,而如果x264使用MSVC动态编译时,出来的libx264.dll.lib,这时就需要改名

  3. 另外一个可能的原因是ffmpeg在配置编译时仿照x264使用了CC=cl而不是toolchain=msvc,通过查看configure文件可以看出toolchain不仅改了CC=cl,而且修改了链接器。因此,如果只是强制使用CC=cl,会使得链接器仍然使用MinGW内的ld.exe。在链接libx264.lib时它会首先去寻找x264而不是libx264(这里也是通过查看config.log发现的),因此提示找不到lib,然而手动重命名修改为x264.lib后,仍然不行,因为GCC的链接器不能链接MSVC编译出来的内容。所以必须一开始就使用toolchain=MSVC链接MSVC编译出来的x264文件。当然,如果x264文件就是使用GCC编译的,那可以使用ld链接。

  4. msys全部编译通过后,在vs工程导入相应库文件,然后编译example时,比如leixiaohua的一些例子可能会发生申明否决,修改方案为:VS属性->C/C+±>SDL检查改为否。可以临时编译通过,但是最好情况是重新修改函数,因为那个函数已经不用了

  5. 有时会遇到error LNK2001 unresolved external symbol _winmain这样的错误,VS属性->连接器->系统->子系统改为 控制台 (/SUBSYSTEM:CONSOLE)

  6. 发生未定义引用时,注意检查

  • 是否在x64平台使用刚刚编译的x86的库文件
  • 是否是CPP文件使用了C的库然后include头文件没有加extern “C”{ }
  • dll文件是否已经在系统环境变量或者copy到工程目录,lib文件是否已经在连接器目录中添加
  1. 有时候明显不是x264或者libav相关的未定义引用时,可以考虑加入这几个lib文件 advapi32.lib;Secur32.lib;ws2_32.lib;
  2. 如果要step进入函数内部,使用动态编译的库,如x264,需要把libx264-148.dll,libx264-148.pdb都复制到工程目录下

准备工作

  1. 下载ffmpeg 代码与x264代码:
    ffmpeg 代码:http://ffmpeg.org/
    x264代码:http://www.videolan.org/developers/x264.html
    其他ffmpeg第三方库的资源获取:
    http://ffmpeg.zeranoe.com/builds/

  2. MinGW+msys下载:
    通过MinGW安装器安装
    http://www.mingw.org/
    http://sourceforge.net/projects/mingw/files/latest/download?source=files
    选择以下的几个package进行安装,在Installation菜单下点击Apply Changes,这样msys1.0会默认安装在MinGW目录下/msys目录
    这里写图片描述

  3. 下载yasm(如果在编译时–disable-asm可以不用下载):
    下载地址: http://yasm.tortall.net/ ;注意不要下载vs版的,下载32位版即可,下载后yasm-1.3.0-win32.exe改名为yasm.exe,复制到**[::minGW安装目录]**\msys\1.0\bin\目录下;

  4. 配置**[::minGW安装目录]**/msys/1.0/msys.bat,在此文件的最前面(@echo off之后)添加一行如下内容:
    call “D:\Microsoft Visual Studio 14.0\VC\bin\vcvars32.bat” (依实际安装路径修改路径。双引号不用删除);

  5. 重命名 [::minGW安装目录]/msys/1.0/bin/link.exe 为link_renamed.exe (依实际安装选择路径),这一步是防止这个link.exe与vc的link.exe发生冲突

  6. 配置完后双击打开msys.bat,验证编译器与连接器是否都已选择为VS路径中的工具链
    未配置正确
    未配置正确对应图
    配置完成
    配置完成图

MinGW编译x264

  1. 在msys.bat中cd到x264的下载目录(有makefile的目录),注意此时其实是模拟linux环境,复制目录时路径分隔符 \ 要转为 \\,或使用/
  2. 进行configure,configure参数如下
  3. make( 根据需要make clean)
  4. make install
configure根据需要任选下面一种

* **0使用VS2015工具链编译,生成动态链接库,关闭汇编优化,打开debug(主要使用这个)**
CC=cl ./configure ----enable-shared ----disable-opencl ----disable-lavf ----enable-debug ----disable-asm ----prefix=./vs2015_build_shared_noyasm

* 1使用VS2015工具链编译,生成静态链接库,关闭汇编优化,打开debug
CC=cl ./configure ----enable-static ----disable-opencl ----disable-lavf ----enable-debug ----disable-asm ----prefix=./vs2015_build_noyasm

* 2使用VS2015工具链编译,生成动态链接库,打开汇编优化(需要前面yasm.exe放置正确),release模式
CC=cl ./configure ----enable-shared ----disable-opencl ----disable-lavf ----prefix=./vs2015_build_release

* 3使用GCC工具链编译,生成静态链接库,打开汇编优化,使用release
./configure ----enable-static ----disable-opencl ----disable-lavf ----prefix=./GCC_release


对于编译有一定了解的人一定可以看出,CC=cl这一编译参数使得是否选择MinGW自带的GUN工具链还是MSVC工具链,如果希望获得的libx264能够在VS中进行debug调用,应该选择方案0,方案1。上述的几种方案都会在x264下载目录下生成一个--prefix=所指定的文件夹,里面有include目录以及lib目录。如果需要后续使用ffmpeg链接x264,并且x264会进行算法修改,推荐使用动态链接库,因为这样只用重新编译x264即可,ffmpeg不用重新编译。

在官网链接中提到--extra-cflags="-DNO_PREFIX",不过我这里没有使用这个编译选项,目前测试在后续的ffmpeg链接没有问题,如果出现问题可以考虑注意这一问题的存在。
##### **可选步骤**

##### 如果只是为了修改x264的相关技术方案,或者不需要用到ffmpeg的容器封装解码等函数,此时就可以利用configure方案1或者2生成出来的lib导入VS进行调试验证了。注意如果修改了x264内部的函数,需要按刚刚步骤使用msys重新编译而不是在VS里面重新编译 
##### 1. 在任意位置新建一个vs工程,将原本x264源码目录下的example.c加入

##### 2. 增加include目录与lib目录:C++->常规->附加包含目录增加 [x盘://x264目录下的]/vs2015_build_noyasm/include 
#####  链接器附加lib目录类似include目录
##### 3. 在lib中增加:libx264.lib
#####(如果是动态编译库,如configure1,需要将dll以及pdb文件放到工程目录下)
##### 即可编译打断点step进入函数内部

--------------------------


#### **MinGW编译FFmpeg并链接x264**
1. msys.bat中cd到ffmpeg的目录
2. 进行configure,configure参数如下
2. make( 根据需要make clean)
3. make install
configure根据需要任选下面一种

* 0使用VS2015工具链编译,生成静态链接库,关闭汇编优化,打开debug,不关联x264
./configure ----enable-static ----disable-yasm ----disable-memalign-hack ----prefix=./vs2015_build_noyasm_nox264 ----enable-debug ----toolchain=msvc

* **1使用VS2015工具链编译,生成静态链接库,关闭汇编优化,打开debug,关联x264 config0(目的用于调试,主要使用这个)**
./configure ----enable-libx264 ----disable-libspeex ----enable-nonfree ----enable-gpl ----disable-shared ----enable-static ----disable-yasm ----disable-memalign-hack ----prefix=./vs2015_build_noyasm_x264 ----enable-debug ----toolchain=msvc ----extra-ldflags=-LIBPATH:D:/x264-snapshot-20161024-2245-stable/vs2015_build_shared_noyasm/lib ----extra-cflags=-ID:/x264-snapshot-20161024-2245-stable/vs2015_build_shared_noyasm/include

* 2使用VS2015工具链编译,生成静态链接库,打开汇编优化(需要前面yasm.exe放置正确),生成release,链接release的x264库,目的是前面调试完成代码,通过这个config生成可以实际使用的release库,保证运行速度
./configure ----enable-libx264 ----disable-libspeex ----enable-nonfree ----enable-gpl ----disable-shared ----enable-static ----disable-debug mak----prefix=./vs2015_build_release ----toolchain=msvc ----extra-ldflags=-LIBPATH:D:/x264-snapshot-20161024-2245-stable/vs2015_build_release/lib ----extra-cflags=-ID:/x264-snapshot-20161024-2245-stable/vs2015_build_release/include

* 3使用GCC工具链编译,生成静态链接库,打开汇编优化,使用release,不关联x264
./configure ----disable-shared ----enable-static ----disable-debug ----prefix=./GCC_release_nox264

* 4使用GCC工具链编译,生成静态链接库,打开汇编优化,使用release,关联x264(这里目的是为了输出一个直接可以使用的exe,x264推荐使用上述configure3的配置)
./configure ----enable-libx264 ----disable-libspeex ----enable-nonfree ----enable-gpl ----disable-shared ----enable-static ----disable-debug ----prefix=./GCC_release ----extra-ldflags=-LD:/x264-snapshot-20161024-2245-stable/GCC_release/lib ----extra-cflags=-ID:/x264-snapshot-20161024-2245-stable/GCC_release/include

###**注意点:**
1 在最开头已经说过,动态生成的libx264.dll.lib需要改为libx264.lib才可以与ffmpeg链接成功(GCC工具链生成的不用)
**2 一般的编译配置是:**
**debug模式:x264使用configure0,ffmpeg使用configure1**
**release模式:x264使用configure2,ffmpeg使用configure2**
**release模式GCC:x264使用configure3,ffmpeg使用configure4**

**这几个组合的编译参数保证是无问题的,因为我已经从博客中直接复制参数,可以编译通过,其他排列组合方案可能在写博客时有笔误,如果你们发现了欢迎留言。如果ffmpeg链接x264 configure参数设定好没问题,但是在make时依然报错找不到.h或者.lib文件时(可能是bug)。**
**解决方案1:**
x264编译时加上--extra-cflags="-DNO_PREFIX",使用make install-lib-shared
```
CC=cl ./configure --enable-shared --prefix= --extra-cflags="-DNO_PREFIX"
make
make install-lib-shared
```
**解决方案2:**手动将对应文件夹内放到对应目录吧,然后编译好记得,删掉避免代码污染——MSVC工具链就将那些文件放到[VS2015安装目录]/VC/include或lib,GUN工具链就将那些文件放到[MinGW安装目录]/include或lib**

**FFmpeg我这里基本没有使用动态链接生成,主要目的是**:
1 本身ffmpeg已经是一个独立的库了,不同于x264,x264直接生成一遍,将dll重新放到工程目录覆盖很快就可以完成,因为动态库是运行时链接,所以不用重新编译ffmpeg。而ffmpeg本身编译时间就很长,且不会与其他库combine,因此不必动态
2 动态生成的ffmpeg会遇到很多奇怪的问题,比如上面提到的,链接configure1生成的动态x264库时,已经指定好路径了,configure可以通过,但在make时还是找不到路径,因此我试着将lib放到VS安装目录/VC/lib里面 这样才可以编译通过

---------
创建一个工程ffmepg_test
在share/example中随便找一个文件,如avio_reading.c放到项目内
或复制leixiaohua的示例工程
http://blog.csdn.net/leixiaohua1020/article/details/25430425
[github文件](https://github.com/leixiaohua1020/simplest_ffmpeg_video_encoder/blob/master/simplest_ffmpeg_video_encoder/simplest_ffmpeg_video_encoder.cpp)
增加include目录与lib目录:C++->常规->附加包含目录增加include 链接器目录加入ffmpeg/lib目录以及x264lib目录
在lib中增加:
【libx264.lib(根据不同编译选项生成的lib修改)】;
advapi32.lib;Secur32.lib;ws2_32.lib;libavcodec.a;libavdevice.a;libavfilter.a;libavformat.a;libavutil.a;libswresample.a;libswscale.a;
如果动态链接库需要将x264的dll与pdb文件放到相应目录
我这里用的是[github文件](https://github.com/leixiaohua1020/simplest_ffmpeg_video_encoder/blob/master/simplest_ffmpeg_video_encoder/simplest_ffmpeg_video_encoder.cpp)做测试的,因此记得按开头的将SDL选为否
编译成功,步进可以进入x264内部

-----------------------------------------------
如果使用VS2013,编译时会遇到inline的错误,因为VS2013使用的是自己的_inline,解决方案:
在某个文件中  #define inline _inline

然后遇到默认库“MSVCRTD”与其他库的使用冲突等
解决方案:
属性-》C++->代码生成-》运行库修改为多线程/MT
当然,也可以debug模式选MTd  然后在linker的命令行加入如下的参数:/NODEFAULTLIB:libcmt.lib 以消除warning

遇到avcodec_alloc_frame()函数报错
解决方法为:
将 avcodec_alloc_frame() 替换为 av_frame_alloc()。

编译成功
展开阅读全文

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