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

(FFmpeg4.0に対応した記事はこちら

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

使いまわし多数ですが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

パッチをffmpegのディレクトリ内で適用。
(3.3用のパッチ ⇒ ffmpeg 3.3 ~)
(3.0用のパッチ ⇒ ffmpeg 3.0 ~ 3.2)

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/10/20

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

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. パッチをありがとう。

  15. 774 より:

    QSVのインストールでは日頃よりお世話になっております。
    さて、ffmpegのバージョンも4.0にメジャーアップデートされました。
    さっそく3.3用のパッチを当ててみたのですが、

    MINGW32: /tmp1/ffmpeg (release/4.0)
    $ patch -p1 < ffmpeg-3.3_qsv.diff
    patching file libavcodec/qsvenc.c
    Hunk #1 succeeded at 273 (offset 5 lines).
    Hunk #2 FAILED at 281.
    Hunk #3 succeeded at 536 with fuzz 2 (offset 93 lines).
    1 out of 3 hunks FAILED — saving rejects to file libavcodec/qsvenc.c.rej
    patching file libavcodec/qsvenc.h
    Hunk #1 succeeded at 132 (offset 20 lines).
    patching file libavcodec/qsvenc_h264.c
    Hunk #1 succeeded at 141 with fuzz 2 (offset 4 lines).

    1箇所パッチ当てに失敗してしまったようです。
    お時間のあるときで結構ですのでffmpeg4.0にも対応したパッチを作成していただけますとうれしいです。

  16. ぬっき~ より:

    774さま

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

    4.0用のパッチは早々に作っていたのですが、別記事にしようとしたら忙しくて放置状態になってしまいました。
    取り急ぎパッチをOneDriceにアップしておきますのでお試しください。

  17. 774 より:

    ぬっき~さま:

    早速4.0用パッチをダウンロードしてみました。
    ffmpeg4.0にて問題無くパッチが当たることを無事確認いたしました。
    お忙しい中迅速に対応していただきまして誠にありがとうございました。