FFmpeg3.0のQSV(H264)を拡張してみる

FFmpeg3.0からQSVまわりが少し変更になったようなので別記事に。
(FFmpeg3.1~FFmpeg3.3.1でも動作を確認しました。)

使いまわし多数ですがw

今回からソースはGitで取得した前提。
ZIPファイル等でダウンロードする場合はディレクトリ名が異なるので置き換えてください。

Windows版のビルド(拡張なし)

以前と同じくmfx_dispatchがあれば良いようです。

必要なツールの準備 (MSYS + MinGW + GCC)

今回もXhmikosR’s氏のを使わせていただきました。
(MSYS_MinGW-w64_GCC_530_x86-x64_Full.7z 2016-01-09版)

msys – XhmikosR’s Builds

展開して「MSYS」内の「msys.bat」を実行。以降CLIでの操作。
(「home」以下にユーザー名のディレクトリが作成されるので、ファイルはWindows側でそこに展開)

mfx_dispatchのビルド

lu-zero/mfx_dispatch

Windows側からGitで取得。

git clone https://github.com/lu-zero/mfx_dispatch.git

MSYS側でビルド。

$ cd ~/mfx_dispatch

$ autoreconf -fiv

$ PKG_CONFIG_PATH="/mingw/i686-w64-mingw32/lib/pkgconfig" \
./configure --prefix="/mingw/i686-w64-mingw32" \
--disable-shared \
--enable-static \
--enable-fast-install

$ make
$ make install

FFmpegのビルド

FFmpeg/FFmpeg at release/3.0

Windows側からGitで取得してrelease/3.0ブランチをチェックアウト。
(release/3.3でも動作を確認しました。)

git clone https://github.com/FFmpeg/FFmpeg.git
cd FFmpeg
git checkout release/3.0

あるいは公式サイトからダウンロードして展開。

Download FFmpeg

MSYS側でビルド。

$ cd ~/FFmpeg

$ PKG_CONFIG_PATH="/mingw/i686-w64-mingw32/lib/pkgconfig" \
./configure --prefix="/mingw/i686-w64-mingw32" \
--enable-gpl \
--enable-version3 \
--enable-libmfx \
--enable-w32threads \
--disable-dxva2 \
--disable-debug \
--disable-doc \
--disable-ffplay \
--disable-ffprobe \
--pkg-config-flags="--static" \
--extra-ldflags="-static" \
--extra-libs="-lsupc++ -lstdc++"

$ make

↓はなくてもビルドできたけど念の為・・・

--extra-libs="-lsupc++ -lstdc++"

QSVENC_H264の使い方

確認した使い方は次の通り。

ソースを眺めつつ使い方を少しまとめ直してみた。(ただし自信はない)
なお、FFmpegオプションのデフォルト値は、look_ahead=1、vcm=0。

・CBRの場合(ビットレート=上限・look_ahead=0)

ffmpeg -i in.ts -c:v h264_qsv -b:v 2000k -maxrate 2000k -look_ahead 0 out.mp4

・VBAの場合(ビットレート<>上限・look_ahead=0)

ffmpeg -i in.ts -c:v h264_qsv -b:v 2000k -maxrate 4000k -look_ahead 0 out.mp4

・AVBRの場合(ビットレート・look_ahead=0)

ffmpeg -i in.ts -c:v h264_qsv -b:v 2000k -look_ahead 0 out.mp4

・LAの場合(ビットレート)

ffmpeg -i in.ts -c:v h264_qsv -b:v 2000k out.mp4

・VCMの場合(ビットレート・look_ahead=0・vcm=1)

ffmpeg -i in.ts -c:v h264_qsv -b:v 2000k -look_ahead 0 -vcm 1 out.mp4

・CQPの場合(品質を指定・look_ahead=0)

ffmpeg -i in.ts -c:v h264_qsv -q:v 20 -look_ahead 0 out.mp4

・ICQの場合(global_qualityを指定・look_ahead=0)

ffmpeg -i in.ts -c:v h264_qsv -global_quality 20 -look_ahead 0 out.mp4

・LA_ICQの場合(global_qualityを指定)

ffmpeg -i in.ts -c:v h264_qsv -global_quality 20 out.mp4


Haswell以降のCPUを所有していないのでLA・VCM・ICQ・LA_ICQのコマンドは実際には試せていない。

詳しいヘルプは次のようにして見ることが可能。

ffmpeg -h encoder=h264_qsv

IvyBridgeでエラーになる

手元にある環境(IvyBridge)でh264_qsvを使用するとエラーを吐いてエンコードできなくなってた。。。

ソースを眺めてみるとQSVのバージョンが「1.9」、かつデフォルトで「-look_ahead」オプションが有効(1)になっており、IvyBridgeはlookaheadに未対応なのでこれが原因だと思われる。

オプションに「-look_ahead 0」を追加すると動作するようになった。

上記のまとめ直したコマンドに含まれる内容になりました。

IvyBridgeはlook_aheadに未対応の為に「-look_ahead 0」が必須。

さらにlook_aheadがデフォルトで有効の為に「-look_ahead 0」を含まないのコマンドは使えないということになるようです。

同じく未対応のSandyBridgeについては所有していないので検証できず。

SandyBridgeのPCを使う機会があったので試してみました。

結論から言うと使用できず。
3.0はおろか2.8もダメ。

スクリーンショット失念して詳しい内容は覚えていませんが、MFXの初期化の段階で何やらエラーを吐いていたような気がします。。

ちなみにどうしてもFFmpegのQSVをSandyBridgeで使いたい場合は、こちらの記事の非公式版2.7を使えば一応動くようです。

QSVENC_H264の拡張

QSVのCBRやVBRは画質的に評判がよろしくないので、IvyBridge以前でもそこそこの画質が得られるようにIフレーム、Pフレーム、BフレームのQP値を設定するCQPを使えるように拡張する。

ffmpeg_qsv_patch

3.0用のパッチをffmpegのディレクトリ内で適用。
(3.3でFAILEDになったので3.3用のパッチを別途準備しました。)

patch -p1 < ffmpeg-3.0_qsv.diff

これでlibmfxを有効にしたFFmpegをビルドしてあげれば、

ffmpeg -i in.ts -c:v h264_qsv -qpi 24 -qpp 26 -qpb 27 -look_ahead 0 out.mp4

こんな感じでエンコードできるようになる。

まとめ

とりあえず動くようにはできたが、現段階でQSVを使うのであれば画質や細かい設定にこだわるならQSVEnc、手軽さならHandBrakeあたりを使った方が楽ちんかもしれない。

それからIntel Graphics Driverが古い場合はアップデートしてみましょう。

追記

2017/05/22

FFmpeg3.1~FFmpeg3.3.1で動作を確認しました。

2017/05/10

FFmpeg3.3用のパッチを追加しました。

2016/06/13

SandyBridgeで試してみました。ダメでした。

2016/02/19

ソースをみて使い方のコマンドを整理しました。
パッチを修正しました。

スポンサーリンク

シェアする

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

フォローする

スポンサーリンク

コメント

  1. 匿名 より:

    この記事に従ってffmpegをコンパイルすると
    common.mak:166: *** missing separator. Stop.
    と言われたので

    http://mem-server.seesaa.net/article/376286170.html
    こちらを参考に

    $ git config –global core.autocrlf false
    $ git rm –cached -r .
    $ git reset –hard

    を実行したら正常にコンパイルすることができました。
    一応報告です。

  2. ぬっき~ より:

    匿名さま

    コメントありがとうございます。

    ご報告いただいた件は Git for Windows をデフォルト設定でインストールした場合におこる改行コードの自動変換が原因です。

    1行目の core.autoclrf false で自動変換を無効にしているので二回目以降エラーはでなくなると思います。

    こちらのサイトも参考になります。

    http://qiita.com/yokoh9/items/1ec8099696ade0c1f36e

    ちなみに私も以前同じところでハマりました・・・

  3. 匿名 より:

    ぬっき~様

    改行コードが問題でしたか。
    勉強になりました。
    ありがとうございます。

  4. 匿名 より:

    1つ質問させていただきます。

    当方スクリプトを組んで、あるフォルダ内の動画ファイルをエンコードさせているのですが、5回に1度程度エンコードが行われない場合があります。
    例えば

    ~省略~
    Stream mapping:
    Stream #0:0 -> #0:0 (mpeg2video (native) -> h264 (h264_qsv))
    Stream #0:1 -> #0:1 (aac (native) -> aac (libfdk_aac))
    Press [q] to stop, [?] for help

    の後、通常であればfpsや完了済みの時間が表示されますが、それらが表示されません。また、出力ファイルの容量も大きくならないのでエンコードが開始されていないと考えられます。しかしながらCPUは38%程度消費されています。
    これはffmpeg2.8及び3.0にて確認しました。

    このような状況はぬっき~様の環境でも起きていますか?

  5. ぬっき~ より:

    匿名さま

    コメントありがとうございます。

    ご質問の症状ですが過去に一度だけ遭遇したことがあります。
    が、その後発症しておらず残念ながら原因は不明のままです。

    FFmpegが限らずQSVEncやTMPGEncでQSVを使用した時にもフリーズや止まるという情報を見たことがあり、WindowsUpdateやIntel HD Graphicsのドライバアップデートなどで改善したという例があるようです。

    QSVはハードウェアエンコードということで、そういった問題や追加グラフィックボードとの相性などが出やすいのかもしれませんね。

  6. 匿名 より:

    ぬっき~様

    となるとコンパイルが問題な可能性は低そうですね。
    ドライバ周りもう一度見直してみます。

    ありがとうございます。

  7. 匿名 より:

    質問させてください。

    こちらのサイトのパッチをあてて-qpi、-qpp、-qpbを使うやり方と、-i_qoffset、-b_qoffsetを使うやり方に違いはありますか?

  8. ぬっき~ より:

    匿名さま

    コメントありがとうございます。

    ご質問の件ですが基本的に同じになります。

    パッチの意味合いとしては、公式FFmpegでQSVがサポートされる以前にあった「非公式のQSV対応FFmpeg」と同じオプションを使えるようにする、というコトです。

    加えてrigaya氏のQSVEncや拡張QSV出力でも同じようなニュアンスで指定できるので便利かなと(^ ^;

    ご指摘の通り-i_qoffsetなどを使えば同じことができます。

    -qpi 24 -qpp 26 -qpb 27

    をパッチなしで指定する場合は

    -q:v 26 -i_qfactor 1 -i_qoffset -2 -b_qfactor 1 -b_qoffset 1

    のようにすれば可能なようです。

    -loglevel verbose を指定すると両方とも QPI: 24; QPP: 26; QPB: 27 でエンコードされているのが確認できると思います。

  9. […] さらに追記 ffmpeg 2.8ではなく3.0の話ですが、こちらの記事(素晴らしい!) FFmpeg3.0のQSV(H264)を拡張してみる によると、look aheadがデフォルトでオンになってるせいで、look ahead非対応CPUに […]

  10. 匿名 より:

    ffmpeg3.1.3安定版がリリースされました。
    早速gitでダウンロードしてQSVENC_H264の拡張patchを当ててみましたが
    成功しません(パッチを当てようとすると止まったままになってしまいます)。

    ちなみにgitのcheckoutは
    git checkout refs/tags/`git tag -l ‘n*’ | sed -e /dev/d | tail -n 1`
    というコマンドを実行して3.1.3に設定しました。

  11. ぬっき~ より:

    匿名さま

    コメントありがとうございます。
    3.1.3リリースされてたんですね。気が付きませんでした。

    早速手元の環境でテストしてみたところ、問題なくパッチが適用されビルドまで完了しました。CQPのコマンドを使用してのQSVエンコードも正常に終了しています。

    >it checkout refs/tags/`git tag -l ‘n*’ | sed -e /dev/d | tail -n 1`
    >というコマンドを実行して3.1.3に設定しました。

    とのことでしたので、結果として取得されるn3.1.3タグと私が通常使用しているrelease/3.1ブランチの両方で試しましたがパッチは成功するようです。(オフセットのメッセージはでますが)

    gitについては詳しくないので原因はわかりかねますが、思い当たるとすればこのエントリーのコメント欄にもあるように改行問題でしょうか・・・・

  12. 匿名 より:

    ぬっき~様:

    申し訳ございませんでした。
    念のためffmpegをgitで再取得し、

    $ git -c core.autocrlf=false clone git://source.ffmpeg.org/ffmpeg.git ffmpeg

    明示的にv3.1.3にcheckoutを設定してみたところ、

    $ git checkout refs/tags/n3.1.3

    問題無くパッチが当たることを確認いたしました。
    私の早とちりです。
    お騒がせしまして大変申し訳ございませんでしたm(_ _)m

  13. ぬっき~ より:

    匿名さま

    ご報告ありがとうございます。

    core.autocrlf=falseでうまくいったということは、やはり改行が原因だったようですね。
    私もたまに忘れてハマったりするのですが、無事パッチが適用されたようで良かったです。

  14. Marius より:

    Have you confirmed it works properly with 3.3.x? I think there’s a bug in FFmpeg because the hardware acceleration is not really enabled. It compiles fine but it runs slow with high CPU load (i5-5575R). I’m experiencing this reported bug:
    https://trac.ffmpeg.org/ticket/6347

    FFmpeg 3.2.x crashes with segfault when converting. Last good option is 3.1.10 which works great so far. パッチをありがとう。