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下测试一下~~~~