最近は MSYS2 + MINGW で FFmpeg をビルドしているので改めて記事にしてみる。
(FFmpeg5.1.1で動作を確認しました。)
MSYS2の準備
MSYSとの違いはネット上に情報が溢れているので割愛。
個人的には pacman でパッケージ管理ができて楽な反面、己の知識不足が原因で依存関係にハマることも多い。という印象。
MSYS2のダウンロード
まずはWindows側での作業。下のサイトからダウンロードしてくる。
MSYS2 – Browse /Base at SourceForge.net
32ビットOSならi686。64ビットOSならどちらでも可。
今回は64ビット版をポータブル環境で使いたいので
・msys2-base-x86_64-xxxxxxxx.tar.xz
を採用。
32ビット版なら
・msys2-base-i686-xxxxxxxx.tar.xz
を使い、以降の「msys64」の部分を「msys32」に置き換える。
7zipあたりで展開して念のため日本語を含まないパスに保存。
今回は C:\msys64 にした。
MSYS2の調整
自分の環境ではWindowsの環境変数に HOME が設定されており、MSYS2でもそちらが優先されてしまう。標準的な msys64\home 以下のユーザー名ディレクトリを使いたいので調整する。
msys2.ini、mingw32.ini、mingw64.ini の各ファイルに次の一行を追加。
HOME=/home/%USERNAME%
MSYS2の起動
MSYS2の実行ファイルは3つある。今回の使い分けとしては次のとおり。
・mingw32.exe ⇒ 32ビット版をビルトする時
・mingw64.exe ⇒ 64ビット版をビルトする時
・msys2.exe ⇒ 使わない
記事内では32ビット版FFmpegビルドを前提にするので、64ビット版をビルドしたい場合は
・mingw32 ⇒ mingw64
・i686 ⇒ x86_64
に脳内変換のこと。
ちなみに32ビット版のMSYS2(msys32)を使用する場合は mingw64.exe から64ビット版のビルドはできない(はず、たぶん)。
というわけで mingw32.exe を実行。
はじめて起動する場合には初期化が走る。
また、字が小さくて読みにくいのでフォントサイズを11ptにするw
ビルドの準備
既存パッケージの更新
まずは既存のパッケージを更新するためコマンドを打つ。
pacman -Syuu
パッケージの衝突が見つかった場合は[Y]を選択して対象を削除しないと継続できないので素直に[Y]を押す。
pacman 自体やターミナル(mintty)などに更新があると、次のようなメッセージが表示されることがある。
警告: terminate MSYS2 without returning to shell and check for updates again 警告: for example close your terminal window instead of calling exit
この場合は Ctrl + C で中断させて、コンソール右上の[×]でウィンドウを閉じ、再度 mingw32.exe を起動して
pacman -Syuu
をもう一度実行する。
ビルド用パッケージのインストール
pacman でビルド作業に必須なパッケージをインストール。
pacman -S base-devel
デフォルトの all で全てインストールする。(autotools など)
つづいて git・yasm・unzip をインストール。
pacman -S git yasm unzip
git はソースの取得に必要。
yasm は FFmpeg ビルド時に必要なアセンブラ。
unzip は パッチの展開(解凍)で使用。
次に minw-w64 をインストール。
pacman -S mingw-w64-i686-toolchain
こちらもデフォルトの all で全てインストール。(gcc など)
FFmpeg用ライブラリの準備
ここからは FFmpeg に組み込むライブラリの準備。
今回追加するライブラリは以下のとおり。
・librtmp
・libx264
・libmp3lame
・libfdk-aac
・libmfx (QSV)
他のライブラリも追加可能だが、多すぎると依存関係で苦労するハメになる。(体験談)
なので必要最低限を採用。
パッケージでインストール
・最新版のライブラリじゃなきゃイヤだ
・ビルド時に最適化して少しでも速くしたい
・全部自分でやらなければ気が済まない
などのこだわりがなければ、準備されているパッケージを使うのが手っ取り早い。
(バージョンもそれなりの速さで更新されているようだし、自前でビルドした libx264 と比較してみたがエンコード速度は差がなかったし・・・)
というワケで、SDL2、x264、lame、fdk-aac をパッケージでインストール。
pacman -S mingw-w64-i686-{SDL2,x264,lame,fdk-aac}
SDL2 は FFplay のビルドに必要。
rtmpdumpのビルド
やっとビルドらしいビルドをする。
pacman にも rtmpdump が準備されているが、FFmpeg のビルド時に gnutls やら p11-kit やらの依存関係がうまく処理できなかったのでソースからビルドすることに。
#git clone "git://git.ffmpeg.org/rtmpdump" git clone "https://gitlab.com/JudgeZarbi/RTMPDump-OpenSSL-1.1.git" "rtmpdump" cd ./rtmpdump make prefix="/mingw32/i686-w64-mingw32" SYS="mingw" SHARED="no" XLDFLAGS="-s" XLIBS="-lcrypt32" -j$(nproc) cd ./librtmp make install prefix="/mingw32/i686-w64-mingw32" SYS="mingw" SHARED="no" cd ../..
$(nproc) には使用可能な最大プロセス数が返る。
~追記~
pacman でパッケージをアップデートしたところ openssl のバージョンが 1.1.1 になっておりビルドに失敗。対応された rtmpdump のソースを Git で見つけたので試したところ成功(上の2行目)。make に XLIBS=”-lcrypt32″ も追加
mfx_dispatchのビルド
QSVを使うために必要。
こちらはパッケージが準備されていないので必然的にソースから。
git clone "https://github.com/lu-zero/mfx_dispatch.git" cd ./mfx_dispatch autoreconf -fiv ./configure --prefix="/mingw32/i686-w64-mingw32" \ --enable-static \ --disable-shared \ --enable-fast-install \ --build="i686-w64-mingw32" make -j$(nproc) make install cd ..
AviSynthPlusのビルド
FFmpeg4.3から別途必要になったようなのでヘッダーのみインストールする。
git clone "https://github.com/AviSynth/AviSynthPlus.git" cd ./AviSynthPlus mkdir ./build && cd ./build cmake -G "MSYS Makefiles" ../ \ -DCMAKE_INSTALL_PREFIX="/mingw32/i686-w64-mingw32" \ -DHEADERS_ONLY:bool=on make make install cd ../..
FFmpegのビルド
ようやく FFmpeg のビルド。
ソースのダウンロード
何はともあれソースをダウンロードしてバージョン 5.0 をチェックアウト。
git clone "git://source.ffmpeg.org/ffmpeg.git" cd ./ffmpeg git checkout -b "n5.0" "refs/tags/n5.0"
FFplay用パッチの適用
このままビルドすると FFplay 使用時に WASAPI 関連のエラーが発生して音声が出力されないので、ネット上にあった解決法をパッチにしてみた。
unzip ffplay-4.0_sdl2_patch.zip patch -p1 < ffplay-4.0_sdl2_patch.diff
そのうち修正される気がするけど、とりあえず応急処置として。
(SDL2 を自前でビルドする場合はバージョンを 2.0.5 にすればパッチ不要)
バージョン4.2以降では問題なさそうでスルー可(たぶん)。
H264QSV拡張用パッチの適用
H264QSVで、Iフレーム、Pフレーム、BフレームのQP値を設定するCQPを使えるように拡張する拙作のパッチ。不要ならスルーしてもよいが、一応この記事のメインディッシュ。
unzip ffmpeg-5.0_qsv_patch.zip patch -p1 < ffmpeg-5.0_qsv_patch.diff
FFmpegのビルド
やっとメインのビルド。
PKG_CONFIG_PATH="/mingw32/i686-w64-mingw32/lib/pkgconfig" \ ./configure --prefix="/mingw32/i686-w64-mingw32" \ --enable-gpl \ --enable-version3 \ --enable-nonfree \ --enable-avisynth \ --enable-openssl \ --enable-librtmp \ --enable-libx264 \ --enable-libmp3lame \ --enable-libfdk-aac \ --enable-libmfx \ --enable-opengl \ --disable-debug \ --disable-doc \ --pkg-config-flags="--static" \ --extra-ldflags="-L/mingw32/i686-w64-mingw32/lib -static" \ --extra-cflags="-I/mingw32/i686-w64-mingw32/include -march=native -mtune=native" \ --optflags="-O3 -finline-functions" \ --cpu="i686" make -j$(nproc)
avisynth と opengl もオマケで追加。
~追記~
パッケージのx264に依存するrtmpdumpが優先されてconfigureがエラーになるので、PKG_CONFIG_PATHとライブラリ・インクルードの検索パスを指定するようにした。
しばらく時間がかかるがエラーがなければ
・FFmpeg.exe
・FFplay.exe
・FFprobe.exe
の3つができている。(_g はデバッグ情報付きらしい)
openssl と fdk-aac が追加されているので再配布はできないのでご注意を。
その他
SandyBridge で FFmpeg の QSV を使いたい場合はこちらを参照。
雑感
環境さえ整えてしまえばビルドそのものは比較的簡単だと思う。
個人的には mingw-w64-i686-toolchain を使用せずに、スレッドモデル Win32 の mingw-w64 を自前で組み込んでビルドしているけど、この手軽さならアリかな~と思った。
追記
2022/09/02
FFmpeg5.1.1 で動作を確認しました。
2022/01/19
FFmpeg5.0 で動作を確認しました。
2021/05/04
FFmpeg4.4 で動作を確認しました。
2021/02/25
FFmpeg4.3.2 で動作を確認しました。
2020/07/02
FFmpeg4.3 で動作を確認しました。
AviSynthPlusを追加しました。
エスケープ文字の不具合を修正しました。
2020/05/29
FFmpeg4.2.3 で動作を確認しました。
2019/08/08
FFmpeg4.2 で動作を確認しました。
20190524版のMSYS2でテストしました。
FFmpegのconfigureオプションを変更しました。
2019/07/19
FFmpeg4.1.4 で動作を確認しました。
2018/11/08
FFmpeg4.1 で動作を確認しました。
FFmpeg4.0.3 で動作を確認しました。
openssl1.1.1 でのrtmpdumpビルドエラーに対応しました。
2018/07/27
FFmpeg4.0.2 で動作を確認しました。