1. 程式人生 > >Windows下編譯可除錯的ffmpeg, 包含ffplay

Windows下編譯可除錯的ffmpeg, 包含ffplay

Windows下編譯可除錯的ffmpeg, 包含ffplay

作者:史正
郵箱:[email protected]
如有錯誤還請及時指正
如果有錯誤的描述給您帶來不便還請見諒
如需交流請傳送郵件,歡迎聯絡

文章目錄

簡述

作業系統: Windows10 64

編譯工具: MinGW+MSYS+yasm + SDL2.0

  • MinGW是Windows下模擬linux執行的庫、標頭檔案等的集合。
  • msys是Windows下模擬linux執行的最新系統, 可以通過類似於linux bash的命令列視窗進行程式碼編譯。
  • yasm是ffmpeg編譯時用到的彙編工具。
  • SDL2.0, ffmpeg編譯ffplay時需要的SDL2原始碼, 編譯時要生成ffpaly, 執行configure指令碼時比較加入--enable-sdl2

FFMPEG版本:ffmpeg-4.1

, 可從FFMPEG官方網址進行下載最新程式碼.

FFMPEG官方網址-http://ffmpeg.org/download.html

作者這裡使用的編譯器是QTCreator5.7.1 + MinGW, 同時有GitBash也可以模擬linux環境執行,但是執行完configure指令碼後發現make命令找不到, 所以乾脆按照其他教程使用MinGW+MSYS+yasm進行編譯。

本文的編譯環境安裝目錄為:D:\FFMPEGDir\MinGW

編譯環境搭建

Mingw+msys+yasm下載與安裝

MinGW+Msys+Yasm的下載與安裝可以參考以下部落格:

下載完成後配置資訊請切回本文繼續, 本文所述與以上部落格有輕微不同。
下載安裝完成後MinGW目錄結構如下(圖中的SDL目錄是後來放進去的):

在這裡插入圖片描述

將下載完成後的yasm-1.3.0-win64.exe改名為yasm.exe放置到D:\FFMPEGDir\MinGW\bin下面。

進入D:\FFMPEGDir\MinGW\msys\1.0執行msys.bat
輸入df -h

$ df -h
Filesystem            Size  Used Avail Use% Mounted on
C:\Users\shizh\AppData\Local\Temp
                      119G   82G   37G  69% /tmp
D:\FFMPEGDir\MinGW\msys\1.0
                      184G   33G  152G  18% /usr
D:\FFMPEGDir\MinGW\msys\1.0
                      184G   33G  152G  18% /
D:\FFMPEGDir\MinGW    184G   33G  152G  18% /mingw
c:                    119G   82G   37G  69% /c
d:                    184G   33G  152G  18% /d
e:                    151G   74G   77G  49% /e
f:                    301G  213G   88G  71% /f
g:                    150G   14G  137G   9% /g
h:                    148G  4.7G  144G   4% /h

可以看到將D:\FFMPEGDir\MinGW是掛載到了/mingw下面.

輸入gcc -v驗證gcc環境是否準備好。

$ gcc -v
Using built-in specs.
COLLECT_GCC=D:\FFMPEGDir\MinGW\bin\gcc.exe
COLLECT_LTO_WRAPPER=d:/ffmpegdir/mingw/bin/../libexec/gcc/mingw32/6.3.0/lto-wrapper.exe
Target: mingw32
Configured with: ../src/gcc-6.3.0/configure --build=x86_64-pc-linux-gnu --host=mingw32 --target=mingw32 --with-gmp=/mingw --with-mpfr --with-mpc=/mingw --with-isl=/mingw --prefix=/mingw --disable-win32-registry --with-arch=i586 --with-tune=generic --enable-languages=c,c++,objc,obj-c++,fortran,ada --with-pkgversion='MinGW.org GCC-6.3.0-1' --enable-static --enable-shared --enable-threads --with-dwarf2 --disable-sjlj-exceptions --enable-version-specific-runtime-libs --with-libiconv-prefix=/mingw --with-libintl-prefix=/mingw --enable-libstdcxx-debug --enable-libgomp --disable-libvtv --enable-nls
Thread model: win32
gcc version 6.3.0 (MinGW.org GCC-6.3.0-1)

如果提示gcc環境找不到, 手動設定下環境變數:export PATH="/mingw/bin:$PATH"

編譯SDL2.0

作者這裡是自己根據原始碼編譯的, 使用dev版本的SDL2.0執行ffmpeg的configure總是提示sdl2支援找不到.

下載SDL2.0原始碼:https://www.libsdl.org/download-2.0.php

解壓後進入相關資料夾

./configure --prefix=/d/FFMPEGDir/MingGW/SDL2/
make -j4 && make install

注意, 這裡的d/FFMPEGDir/MingGW/SDL2/一定要先建立好

make -j4是啟動多執行緒編譯, 4是執行緒數量, 但執行緒數量不一定越高越好, 作者使用make -j使用最高的執行緒數進行編譯(8個執行緒), 導致CPU佔用率過高, 電腦藍屏!!!

編譯ffmpeg

本文ffmpeg原始碼路徑位於:D:/FFMPEGDir/ffmpeg-4.1/ffmpeg-4.1

關閉防毒軟體, 作者在編譯執行configure指令碼時時沒有關閉360安全衛士, 一直提示出幾個編譯出的檔案是木馬軟體。網上有一些教程時不關防毒軟體會導致執行指令碼失敗, 這裡倒是沒有注意。

進入D:\FFMPEGDir\MinGW\msys\1.0, 執行msys.bat。

cd D:/FFMPEGDir/ffmpeg-4.1/ffmpeg-4.1
export PATH="/mingw/SDL2/bin/:$PATH"
 ./configure --enable-shared --disable-static --enable-debug --enable-sdl2 --extra-cflags='-I/mingw/SDL2/include/SDL2/' --extra-ldflags='-L/mingw/SDL2/lib/' --prefix=D:/FFMPEGDir/ffmpegExport
  • --enable-debug是啟動除錯, 若不加此命令編譯出的ffmpeg是無法進行除錯的, 就不會生成ffmpeg_g的這些檔案
  • --enable-sdl2啟動SDL環境, 只有啟用了sdl環境, 且配置指令碼檢測無誤才會編譯出ffplay
  • --extra-cflags, 額外的指定C編譯器尋找的Inlcude路徑, 這裡是指定SDL2的標頭檔案路徑
  • --extra-ldflags, 額外指定連結器尋找連結庫的路徑,這裡是指定SDL2的連結庫路徑
  • --prefix=D:/FFMPEGDir/ffmpegExport, 指定編譯出的ffmpeg可執行程式以及相關標頭檔案, 動態庫的存放位置

執行指令碼, 等待指令碼退出, 也可在ffmpeg原始碼的ffbuild路徑下執行跟蹤追蹤進度tail -100f ffbuild/config.log

若執行完後, 提示sdl2支援找不到, 那就是SDL庫的路徑不對, 或者是因為SDL2的dev版本無法使用。

正確執行完後, 在輸出的內容中尋找program, 看看有沒有ffplay, 正常的情況應該是ffmpeg ffprobe ffplay.

如果執行完後提示WARNING: pkg-config not found, library detection may fail.這個無需理會,這裡不會對編譯產生影響。

開始編譯ffmpeg.

make -j4 && make install

若編譯過程中出現如下錯誤, 開啟libavformat/os_support.h, 新增#include <winerror.h>

CC      libavformat/paf.o
In file included from libavformat/os_support.h:112:0,
                 from libavformat/os_support.c:29:
libavformat/os_support.c: In function 'ff_gai_strerror':
libavformat/os_support.c:194:10: error: 'ERROR_NOT_ENOUGH_MEMORY' undeclared (first use in this function)
     case EAI_MEMORY:
          ^
libavformat/os_suppCCort.clibavformat/pcm.o:1
:10: note: each undeclared identifier is reported only once for each function it appears in
make: *** [libavformat/os_support.o] Error 1
make: *** Waiting for unfinished jobs....

這裡作者不確定會不會出現這個問題, 因為第一天晚上編譯時就沒有報錯, 第二天就出現了這個問題。

編譯完成後需要將MinGWSDL2/bin/SDL2.dll放置D:/FFMPEGDir/ffmpegExport/bin/下, 否則執行ffplay會報
SDL2.dll找不到。

同時, 在cmd中使用ffmpeg與ffplay, ffprobe會報libiconv-2.dll找不到, 這時可以從以下網址進行下載, 放入D:/FFMPEGDir/ffmpegExport/bin/下。

ffplay問題

編譯後的ffplay執行時會提示如下警告

Warning: not compiled with thread support, using thread emulation

這是因為gcc版本導致的, 作者將gcc版本降級為5.3, 重新編譯ffmpeg就沒有出現這個警告了。

注意:

作者這裡編出的ffpaly播放任何視訊都會卡頓在第一幀, 音訊會連續播放, 同時移動播放視窗以及在畫面內連續點選會進行視訊幀的切換, 這裡懷疑是SDL的版本不適配導致的問題。

參考文章