MinGW32編譯ffmpeg+libsrt

前言

國內關於SRT協議的資料,幾乎爲0,沒什麼人用srt協議去編譯過ffmpeg,而且這東西在Windows下面編各種坑,整整搞了我十幾天,網上資料幾乎都是英文的,有些錯誤也查不到,就很絕望,在鄭師傅的幫助下,跌跌撞撞把這個東西編出來了。(如果你不想編,可以直接下我編好的srt庫,但是授人以魚不如授人以漁)

爲什麼不採用cygwin編譯,cygwin編譯srt的時候有選項use-cygwin-posix,意思就是使用cygwin提供的posix標準的那一套線程庫,導致編出來只能在cygwin下面用,不能在powershell下面跑,放在別人電腦上只能在他人也安裝了cygwin的情況下跑,非常麻煩,我的目標是編譯出可以在他人電腦上直接執行的.exe文件,因此cygwin無法達成目標,轉用MinGW

MinGW安裝

這個不多贅述了,基本組件就可以了,網上關於安裝的說明非常多,不贅述了,裝好基本的MinGW之後,需要打開msys去裝如下的幾個包的有:

具體怎麼裝可以自行百度搜索,這裏不過多描述,這不是本篇的重點。

SDL可以自己編譯也可以自己下一個,MinGW installer沒有SDL庫,所以去官網下載,需要其他版本SDL可以在網址後面加上release即可,不想編譯可以下載下圖中的該版本。
SDL不需要自己編譯
按照官方文檔描述,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,我這裏只裝了最基本的包
vs安裝

支持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位,然後按照官方文檔前面寫的說明,我應該選擇的是releasex64編出來的線程庫。

這個時候問題來了,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編譯中不出現問題,所以實際應該和我下圖貼出來的一樣去編譯

pthread庫編譯
最新的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文件裏面存放了庫的配置信息,比如頭文件放在哪,庫文件放在哪等等。
由於我們的庫都在不同的地方,因此需要我們自己去指定opensslSDLsrt的路徑。
比如,我的庫的位置是在/usr/local下面的三個文件,那麼我的配置應該是

  $ export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/SDL/lib/pkgconfig:/usr/local/srt/lib/pkgconfig:/usr/local/openssl/lib/pkgcongig

務必要把所有需要用到的庫包含進去,這個目錄要根據自己的情況寫,之後用以下命令查看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下測試一下~~~~
測試

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章