FFmpegのQSV(H264)を拡張してみる

最近は 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 関連のエラーが発生して音声が出力されないので、ネット上にあった解決法をパッチにしてみた。

ffplay_sdl2_patch

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を使えるように拡張する拙作のパッチ。不要ならスルーしてもよいが、一応この記事のメインディッシュ。

ffmpeg_qsv_patch

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 で動作を確認しました。

スポンサーリンク

シェアする

  • このエントリーをはてなブックマークに追加

フォローする

スポンサーリンク