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參數後面也會進行簡單的介紹。

下面主要是介紹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文件是否已經在連接器目錄中添加
  7. 有時候明顯不是x264或者libav相關的未定義引用時,可以考慮加入這幾個lib文件 advapi32.lib;Secur32.lib;ws2_32.lib;
  8. 如果要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參數如下
  3. make( 根據需要make clean)
  4. 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=<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文件
增加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文件做測試的,因此記得按開頭的將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()。

編譯成功

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