MinGW32编译ffmpeg+libsrt

Posted kn-zheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MinGW32编译ffmpeg+libsrt相关的知识,希望对你有一定的参考价值。

MinGW编译带srt库的ffmpeg
前言
MinGW安装
CMAKE安装
Visual Studio 2017安装
支持windows的线程库
SRT库的编译
openssl的安装
SRT编译
MinGW下的SDL和openssl
openssl
SDL
ffmpeg编译
PKG-CONFIG配置
ffmpeg


前言
国内关于SRT协议的资料,几乎为0,没什么人用srt协议去编译过ffmpeg,而且这东西在Windows下面编各种坑,整整搞了我十几天,网上资料几乎都是英文的,有些错误也查不到,就很绝望,在郑师傅的帮助下,跌跌撞撞把这个东西编出来了。(如果你不想编,可以直接下我编好的srt库,但是授人以鱼不如授人以渔)

为什么不采用cygwin编译,cygwin编译srt的时候有选项use-cygwin-posix,意思就是使用cygwin提供的posix标准的那一套线程库,导致编出来只能在cygwin下面用,不能在powershell下面跑,放在别人电脑上只能在他人也安装了cygwin的情况下跑,非常麻烦,我的目标是编译出可以在他人电脑上直接执行的.exe文件,因此cygwin无法达成目标,转用MinGW

MinGW安装
这个不多赘述了,基本组件就可以了,网上关于安装的说明非常多,不赘述了,装好基本的MinGW之后,需要打开msys去装如下的几个包的有:

SDL库(2.0.9) : https://www.libsdl.org/download-2.0.php
openssl(1.0.2r) : https://www.openssl.org/source/
pkg-config : http://ftp.gnome.org/pub/gnome/binaries/win32/dependencies/
glib : http://ftp.gnome.org/pub/gnome/binaries/win32/glib/
具体怎么装可以自行百度搜索,这里不过多描述,这不是本篇的重点。

SDL可以自己编译也可以自己下一个,MinGW installer没有SDL库,所以去官网下载,需要其他版本SDL可以在网址后面加上release即可,不想编译可以下载下图中的该版本。

按照官方文档描述,1.0.2r版本openssl可以用,后面如果更新了的话请按照最新文档下载,虽然MinGW提供openssl,但是经过验证之后发现配置信息并不全,方便起见直接编译就好了,也可以前往github下载:https://github.com/openssl/openssl。
pkg-config为包管理的一个组件,可以通过.pc配置文件找到库和头文件的位置,将其放在MinGW的bin目录下即可。
pkg-config需要libglib-2.0-0.dll,拷贝该文件到bin目录下面和pkg-config放在一起即可。

CMAKE安装
这个没啥好说的,贴好链接大家自己下载
https://cmake.org/download/

Visual Studio 2017安装
这个也没啥说的,就是安装就完事了。为什么要装VS,因为后面我们需要vs的cl.exe和cmake组合去帮我们构建srt项目,编译出库。
https://visualstudio.microsoft.com/zh-hans/downloads/
社区版是免费的,没有必要装专业版,社区版就够用,记得装上Windows SDK,我这里只装了最基本的包


支持windows的线程库
如果你不想听我啰嗦,我的结论就是需要编译win32的线程库,所以直接用VS编译release的Win32线程吧,不能和文档说的编译出来一个x64的库,那样在MinGW下面无法使用。

按照SRT官方文档的说法,需要用vs编译windwos可以用的线程库,于是从文档中找到这个pthread库,下载,按照文档给出的方法编译出库,放到指定路径即可。
线程库地址:https://github.com/GerHobbelt/pthread-win32

按照官方文档给出的解释:

a. Using Visual Studio 2013, please open this file:
pthread_lib.2013.vcxproj

b. Make sure to select configuration: Release and x64.

(They are in the toplevel directory, there are actually no meaningful subdirs here) (NOTE: the win32 is part of the project name. It will become 32 or 64 depending on selection)

什么意思呢,就是这个默认位置的文件夹命名是pthread-win32,win32仅仅是名字,根据选择他会变成32位或者64位,然后按照官方文档前面写的说明,我应该选择的是release的x64编出来的线程库。

这个时候问题来了,MinGW使用./configure之后调用去cmake构建srt项目后,默认构建的项目是win32,使用的工具链也是vs的,然后用vs去打开项目编译srt发现很多pthread找不到标识符的错误。

一开始以为是MinGW的问题,没有找到这个库,遂用cygwin去编译,发现这个线程库在用cygwin确实能识别当前是32位还是64位,使用cygwin64编出来的东西就是x64的,使用cygwin编出来就是i386的,但是VS编译的时候居然找不到标识符,后来发现这个玩意在VS里面压根就不会自动选择是32位还是64位,要是64位的库,我去构建win32的库压根无法识别pthread_lib.lib里面的内容。

解释完了,意思就是这个线程库,MinGW去构建不能像文档说的编出x64的库去用,而是需要选择win32去编译这个线程库,才能在之后的srt编译中不出现问题,所以实际应该和我下图贴出来的一样去编译


最新的SRT v1.4.1的文档我注意到,说明已经修改了,文档写的是

Copy include files to C:\\pthread-win32\\include (pthread.h, sched.h, and semaphore.h are in the toplevel directory. There are no meaningful subdirs here). Note that win## is part of the project name. It will become win32 or win64 depending on the selection.

这就清楚多了,需要编64位,就写win64,32位就写win32,取决于编的版本,之前的说明感觉理解上有歧义

SRT库的编译
SRT库下载地址:https://github.com/Haivision/srt

SRT文档中对SRT编译前置条件描述:

cmake (as build system)
Tcl 8.5 (optional for user-friendly build system)
OpenSSL
Pthreads (for POSIX systems it’s builtin, for Windows there’s a library)
其中tcl如果没有安装的话,直接去MinGW的安装文件里面去找一个叫tclsh的包,勾选安装即可,这个在configure的时候用得到

openssl的安装
这东西需要openssl支持,所以在编译之前需要先把openssl给弄好。

http://slproweb.com/products/Win32OpenSSL.html
从官方文档提供的网址下一个Windows可以直接安装的版本,不需要自己编译,一样,用的1.0.2r,之后如果版本更新了,请按照文档来,这里下载的还是32位的,为了防止出现各种幺蛾子,统一用32位。

这个为什么还要再装一个呢,目的是为了给vs编译srt用,等会ffmpeg编译的时候也会用到openssl,那个openssl用的是编译出来的,两个放的目录不一样,为了我们之后的方便,Windows装一个放到默认目录省事,不用自己去指定目录,默认目录是C:\\OpenSSL-Win32。

当然,如果你想用源码编译一份,完全可以,用vs编译openssl看这:https://blog.csdn.net/sky101010ws/article/details/51682725

SRT编译
然后正式进入srt编译,MinGW没有自己的cmake,因此只能使用cmake提供的gui,srt协议编译库需要使用configure文件。

这里我犯了一个错误,由于我发现configure文件里面在一系列检测之后还是调用了cmake,所以我就直接使用cmake -G"Unix Makefiles" .去生成makefile文件,然后出现了一大堆错误,后来在hook的指导下,才知道这样越过configure文件是错误的编译方式,configure文件会帮我们配置一些环境,直接跳过configure去cmake显然不可取。

./configure --enable-static --disable-shared

可能会出现tclsh没有找到的问题,原因是configure文件第一行写的是#!/usr/bin/tclsh,然而我们的tclsh并没有装在/usr/bin,我的tclsh是在/MinGW/bin目录下,修改一下即可。

完成之后,使用VS去编译SRT库,注意,默认使用MinGW配合CMake生成的VS项目应该是32位的(Win32),确认后用VS生成项目即可,生成完毕后会得到一些.lib、.exp、.dll和.exe文件。

编译好的SRT按照下面给出的地方放置到/usr/local下,给出/usr/loacl我的参考路径——E:\\MinGW32\\msys\\1.0\\local\\srt,在SRT的目录中将需要的文件移到/usr/local下面

srt/
├── bin
│   ├── srt.dll
│   ├── srt-file-transmit.exe
│   ├── srt-live-transmit.exe
│   └── srt-multiplex.exe
├── include
│   └── srt
│       ├── in6addr.h
│       ├── logging_api.h
│       ├── platform_sys.h
│       ├── srt.h
│       ├── srt4udt.h
│       ├── udt.h
│       ├── version.h
│       ├── win
│       │   ├── syslog_defs.h
│       │   └── unistd.h
│       ├── winapifamily.h
│       └── ws2ipdef.h
└── lib
    ├── pkgconfig
    │   ├── haisrt.pc
    │   └── srt.pc
    ├── srt.exp
    ├── srt.ilk
    ├── srt.lib
    ├── srt.pdb
    ├── srt_static.lib
    ├── srt_static.pdb
    ├── srt-file-transmit.exp
    ├── srt-file-transmit.ilk
    ├── srt-file-transmit.lib
    ├── srt-file-transmit.pdb
    ├── srt-live-transmit.exp
    ├── srt-live-transmit.ilk
    ├── srt-live-transmit.lib
    ├── srt-live-transmit.pdb
    ├── srt-multiplex.exp
    ├── srt-multiplex.ilk
    ├── srt-multiplex.lib
    └── srt-multiplex.pdb

6 directories, 35 files


MinGW下的SDL和openssl
为什么要自己编译openssl前面已经说过了,MinGW自带的openssl配置信息有误

openssl
openssl编译前置条件

  * make
  * Perl 5
  * an ANSI C compiler
  * a development environment in form of development libraries and C header files
  * a supported Unix operating system

装好make和perl 5后开始编译,请按照INSTALL文件提供的方法去编译

  $ ./config
  $ make
  $ make test
  $ make install

SDL
这里我就不编译库了,直接拿官方安装好的库去使用,执行以下命令即可,文件将会移到默认位置

  $ make native

ffmpeg编译
PKG-CONFIG配置
pkg-config是通过PKG_CONFIG_PATH这个环境变量进行查找包的,比如:SDL2库有SDL2.pc这个文件,.pc文件里面存放了库的配置信息,比如头文件放在哪,库文件放在哪等等。
由于我们的库都在不同的地方,因此需要我们自己去指定openssl、SDL、srt的路径。
比如,我的库的位置是在/usr/local下面的三个文件,那么我的配置应该是

  $ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/SDL/lib/pkgconfig:/usr/local/srt/lib/pkgconfig:/usr/local/openssl/lib/pkgcongig
1
务必要把所有需要用到的库包含进去,这个目录要根据自己的情况写,之后用以下命令查看pkg-config是否能找到这几个库

  $ pkg-config --list-all


ffmpeg
准备工作结束,正式编译ffmpeg,可以看到有些文章编译ffmpeg之前装过nasm/yasm这个交叉编译的汇编器,但是我测试的时候发现如果使用yasm去编译,最后出来得ffmpeg根本无法使用,因此使用--disable-x86asm选项,--enable-sdl2是为了确保肯定会去检测SDL2,以便编译出ffplay,在configure的help说明中,sdl2是自动检测的,这里写出来只是为了确保一定会去尝试使用sdl2去编译ffplay。

./configure --enable-static --disable-shared --enable-libsrt --disable-x86asm --enable-sdl2

成功生成makefile之后的情况

可以看到有SDL2出现,表示最后能够生成ffplay

可以看到Enabled protocols里面,存在一个libsrt在其中,可以说成功了一半。
之后便是make的过程了,直接执行

  $ make -j8

make过程中,会出现几个问题,首先是一个重定义的问题,srt.h中重定义了几个类型,需要我们去注释掉他。

然后是一个MinGW自己的bug,winsock2.h在winsock.h之后引用的问题。
之后是一个:libformat/os_support.c : error : ‘ERROR_NOT_ENOUGH_MEMORY’ undeclared ( first use in this function) case EAI_MEMORY.
这两个问题在他人博客中都有解决方法,我就直接引用了,以下是链接:
https://blog.csdn.net/kl794756707/article/details/82808514

编译完毕

解决掉上述问题之后,成功编译出ffmpeg、ffprobe、ffplay,在powershell下测试一下~~~~

windows 7下mingw+msys编译ffmpeg

1-->下载安装MingW,mingw-get-inst-20120426.exe  http://sourceforge.net/projects/mingw/

安装路径 默认C:\MinGW 。勾选了 <1> C Compiler  <2> C++ Compiler <3>MSYS Basic System <4>MinGW Developer ToolKit

其中 <3>就安装了 msys。这样安装需要联网,自动下载mingw项目下一些工具文件。

安装完成后,为了方便VS200X以及VS2010调用ffmpeg的动态库,可以通过配置让ffmpeg编译时产生windows下调用dll对应的lib。根据我的VS2010安装目录,用noteplus notepad++ ue等支持Uinux换行的文本工具打开 C:\MinGW\msys\1.0\msys.bat

在最最前面加上下面一行

call "C:\Program Files\Microsoft Visual Studio 10.0\VC\bin\vcvars32.bat"

将 msys.bat发送到桌面快捷方式,就可以方便打开命令窗口了,一个简单的linux shell。

这样 cd /e/ffmpeg/ 就切换到E:/ffmpeg/目录下

2--->下载安装yasm,因为编译ffmpeg里面的汇编代码需要yasm.exe,没有这个的话,也能编译通过,可能使用的时候,效率没有那么高。 http://yasm.tortall.net

Win32 VS2010 .zip (for use with VS2010 on 32-bit Windows) Version 1.2.0 Release: October 31, 2011

为了减少配置环境变量的麻烦,解压后把 vsyasm.exe 文件名修改成:yasm.exe,并放到系统目录下:C:WINDOWS\system32\下。

3--->下载安装ffmpeg。 http://www.ffmpeg.org Version 1.1 Release:January 7, 2013

4--->编译X264(项目需求)

http://www.videolan.org/developers/x264.html  下载 解压 得 x264-snapshot-20130114-2245

打开 msys.bat,命令行

1.$ cd e/ffmpeg/x264-snapshot-20130114-2245/

2.$ ./configure --enable-shared --disable-asm

3.$ make

4.$ make install

这样就把编译结果复制到 C:\MinGW\msys\1.0\local 下 bin include lib这三个文件夹下面。

输入命令有个技巧,可以复制后,在msys.bat的命令行窗口标题栏点击右键,以此选择--‘‘编辑--粘贴(P)‘‘。类似DOS,标记后即是复制。

如果编译失败或者重新编译,先运行make distclean或者make clean,再执行上面1--2--3--4

5--->下载SDL。没有SDL编译出来的ffplay.exe不能播放视频。

http://www.libsdl.org/download-1.2.php 最后有一个 win32 SDL-devel-1.2.15-mingw32.tar.gz (Mingw32)

解压后 bin include lib文件夹内容对应拷贝到C:\MinGW\msys\1.0\local 下 bin include lib这三个文件夹下。

使用UltraEdit打开刚刚拷贝的C:\MinGW\msys\1.0\local\bin下的 sdl-config文件
    把 prefix=/usr/*******  该成: prefix=c:/mingw
其中:c:/mingw 为 mingw的安装路径,请根据你的安装进行修改。为了编译时msys能识别sdl并开启 SDL support yes 进行编译。

以上是关于MinGW32编译ffmpeg+libsrt的主要内容,如果未能解决你的问题,请参考以下文章

用mingw32编译ffmpeg2.7

Ubuntu下使用mingw-w64交叉编译ffmpeg

[ffmpeg 扩展第三方库编译系列] 关于 mingw32 下编译libcaca

[ffmpeg 扩展第三方库编译系列] frei0r mingw32 下编译问题

libsrt+ffmpeg推拉流

libsrt+ffmpeg推拉流