FFmpeg, H.264 エンコーディングガイド

原本 : FFmpeg and H264 Encoding Guide
閲覧 : 2016/03/28

FFmpeg, H.264 エンコーディングガイド

このガイドの目的は、x264エンコーダを使って高品質なH.264動画をどのように作るかを新規ユーザに伝えることです。

一般的な利用のために通常すすめられる2つのビットレートの制御手法があり、 それらはConstant Rate Factor(CRF)2-Pass ABRです。 ビットレート制御は各フレームにどれだけのビット数が使われるかを決定する方法です。 これが動画ファイルのサイズと画質を決定します。

もしもlibx264のコンパイルとインストールに関するヘルプが必要であれば、 FFmpeg, x264 コンパイルガイドのうちの 1つを参照してください。

Constant Rate Factor(CRF)

この手法は、ファイルサイズがそこまで重要でない時に、 エンコーダにファイル全体にわたってある画質の出力を達成するように試みるのを許します。 CRFは1パスエンコーディングで最大の圧縮効率を提供します。 各フレームには要求された画質を維持するのに必要なビットレートが与えられます。 欠点は、CRFエンコーダにある一定のファイルサイズを出力させたり、 あるファイルサイズやビットレートを超えないようにさせたりできないことです。

1. CRF値を選ぶ

クオンタイザ(quantizer, 量子化器)のスケールの範囲は0から51で、0ではロスレス、23がデフォルト、51は下の下です。 より小さい値ではよりよい画質となり、主観的に妥当と思われる範囲は18から28です。 視覚的に劣化がないかそれに近いもののためには18を検討してください。 また、それらが入力と同じもしくはほぼ同じに見えたとしても、それは技術的には無劣化ではありません。

スケールの範囲は指数的なので、CRF値を6増やすことはビットレートを半分にすることと大雑把に同じで、 また、CRF値を6減らすことはビットレートを2倍することと大雑把に同じです。 一般的な使い方は満足な画質を提供してくれるCRF値のうちで最も大きい物を選ぶことです。 もしも出力の画質が良ければその時はより大きい値を試して、 もしも画質が悪ければより小さい値を選ぶようにします。

注釈
このページで言及されているCRFクオンタイザのスケールは8ビットx264にのみ適用されるものです (10ビットx264のクオンタイザのスケールは0から63です)。 ffmpegコマンドのコンソール出力を参照することで何が使われているかがわかります。 「yuv420p」やそれに似た出力があれば8ビットで、「yuv420p10le」やそれに似た出力があれば10ビットです。 8ビットが一般に使われています。

2. プリセットを選ぶ

プリセットは圧縮率に対するある特定のエンコード速度を提供するオプションの集まりです。 より遅いプリセットはよりよい圧縮率(ファイルサイズに対する画質の良さ)を提供します。 これは、例えば、もしあなたがある特定のファイルサイズや一定のビットレート目指していたとすると、 より遅いプリセットを使うほうがよりよい画質を得ることができるということを意味します。 同様に、一定の画質のエンコーディングのためでも、 遅いプリセットを選択して単にビットレートを節約するのもよいでしょう。

一般的な指針はその遅さをあなたが我慢できる中で最も遅いプリセットを使うことです。 現在のプリセットはエンコード速度の降順で、 「ultrafast」、「superfasut」、「veryfast」、「faster」、「fast」、「medium」、 「slow」、「slower」、「veryslow」、「placebo」です。 デフォルトのプリセットはmediumになっています。 実用的でないので、placeboは無視してください(FAQを参照)。 現在のプリセットのリストは「-preset help」で見ることができます(下記の例も参照)。 そして、それらがどのような設定を適用するかは「x264 --fullhelp」で見られます。

あなたの入力の詳細に基づく設定を変更するために任意で「-tune」を使うことができます。 現在のチューニングは、「film」、「animation」、「grain」、「stillimage」、 「psnr」、「ssim」、「fastdecode」、「zerolatency」を含んでいます。 例えば、入力がアニメであればその時はanimationチューニングを使ってください。 また、粒度を維持したい時はgrainチューニングを使ってください。 もしも、何を使えばいいか自身が持てなかったり、入力がどのチューニングにも合致しないのであれば、 その時は「-tune」オプションを省略してください。 現在のチューニングのリストは「-tune help」で見ることができ、 それらによってどのような設定が適用されるかは「x264 --fullhelp」で見ることができます。

もう1つの任意の設定は、出力を特定のH.264のプロファイルに制限する「-profile:v」です。 これは、対象としている再生デバイスがある特定のプロファイルをサポートしているだけでない限り、 一般に省略することができます(互換性を参照)。 現在のプロファイルは、 「baseline」、「main」、「high」、「high10」、「high422」、「high444」を含んでいます。 「-profile:v」の使用はロスレスエンコーディングと両立しないことに気をつけてください。

使うことのできる内部プリセットとチューニングの一覧を表示するには以下を実行してください。
ffmpeg -f lavfi -i nullsrc -c:v libx264 -preset help -f mp4 -

注釈
Windowsのユーザは「NUL」を「-」の代わりに出力として使う必要があるでしょう。

3. 設定を使う

さらにエンコードをするのであれば、一度選択をすれば選択された設定はそれらを残りのビデオにも適用します。 これはそれらの動画がだいたい同じ画質になることを保証します。

CRFの例

ffmpeg -i input -c:v libx264 -preest slow -crf 22 -c:a copy output.mkv

この例では入力ファイルのオーディオストリームが 単に出力ファイルへコピーされるストリームであり、 再エンコードされないということに注意してください。

2-Pass

この手法は一般に特定のファイルサイズが目標で、フレーム間の質はさほど重要でない場合に用いられます。 実例が一番わかり易いでしょう。 あなたの動画は10分(600秒)の長さがあり、50MBの出力が欲しいとします。

(ビットレート) = (ファイルサイズ) / (長さ)
なので、
(50MB * 8192 [MBをキロビットに変換]) / 600秒 = ~683 キロビット/秒 (全体のビットレート)
683k - 128k (必要な音声部分のビットレート) = 555k (動画部分のビットレート)
となります。

2-Passの例

ffmpeg -y -i input -c:v libx264 -preset medium -b:v 555k -pass 1 -c:a libfdk_acc -b:a 128k -f mp4 /dev/null &&
ffmpeg -i input -c:v libx264 -preset medium -b:v 555k -pass 2 -c:a libfdk_acc -b:a 128k output.mp4

注釈
Windowsユーザは「/dev/null」の代わりに「NUL」を使うべきです。

CRFと同様に、我慢できる中で最も遅いプリセットを選びましょう。

1パス目では2パスめの出力フォーマットと同じフォーマットを("-f"で)指定してください。 また、1パス目では2パス目で使うオーディオコーデックを指定するようにしてください。 ほとんどの場合、1パス目で"-an"を使ってもうまく動作しません。

高品質なDVD動画のMPEG-4("DivX")リップの作成を読んでください。 これはMEncoderのガイドですが、ストレージの容量を考慮しなくてはならなくて すべてのビットを効率的に使いたい時に2-Passを使うことがどれだけ重要かについての見識を与えてくれるでしょう。

ロスレス H.264

ロスレス出力を得るために「-qp 0」または「-crf 0」を使うことができます。 8ビットと10ビットのx264ではロスレスエンコーディングに異なった「-crf」の値を使っているため、 ロスレスエンコーディングでは「-crf」よりも「-qp」を使用するのが推奨されます。 また、普通は高速なエンコード速度か最良の圧縮率のどちらかが最も重要な要因となるので、 この場合に有用なプリセットは「ultrafast」と「veryslow」です。 ほとんどのFFmpegベースでない動画プレイヤーはロスレスをデコードすることができません(YouTubeはできます)。 そのため、もしも互換性が問題となる場合はロスレスを使用しないようにすべきです。

ロスレスの例(最速のエンコード速度)
ffmpeg -i input -c:v libx264 -preset ultrafast -qp 0 output.mkv

ロスレスの例(最良の圧縮率)
ffmpeg -i input -c:v libx264 -preset veryslow -qp 0 output.mkv

デフォルトのプリセット設定の上書き

「x264opts」オプションまたは「x264-params」オプション、 もしくはlibx264のプライベートオプション(「ffmpeg -h encoder=libx264」の出力を参照)」)を使って デフォルトのプリセット設定を上書きすることができます。 何をするかを知らないのであれば、上書きをすることはおすすめしません。 プリセットはx264の開発者によって作られており、 よりよい出力を得るために値を微調整することは一般に時間の無駄です。


ffmpeg -i input -c:v libx264 -preset slow -crf 22 -x264opts keyint=123:min-keyint=20 -c:a copy output.mkv

追加の情報とヒント

ABR (Average Bit Rate, 平均ビットレート)

ffmpeg -i input -c:v libx264 -b:v 1000k output.mp4

これはちょっとした移動平均の目標のようなものを提供し、 最終的な目的はエンコード後のファイル全体の平均の数値がこの数値と一致するようにすることです。 (そのため、基本的に、もしも大量の黒いフレームがあった場合、それらは僅かなコストしかかからず、 所望のビットレート未満の値でエンコードされるでしょう。 しかし、次の数秒間に(黒でない)フレームがあったとすれば、 平均値を所望のビットレートと一致させるために、それらのフレームは非常に高い画質でエンコードされるでしょう。) 2-Passを使うことはこの手法がより有効に働くことを助けます。 ビットレートの変動を抑止するために「最大ビットレート」の設定と組み合わせてABRを使うこともできます。

CBR (Constant Bit Rate, 固定ビットレート)

本来のCBRモードは存在しませんが、 ABRのパラメータを調整することで固定ビットレートの設定を「シミュレートする」ことができます。

ffmpeg -i input -c:v libx264 -b:v 4000k -minrate 4000k -maxrate 4000k -bufsize 1835k out.m2v

上記の例では、「-bufsize」は「レート制御バッファ」のサイズなので、 動画の1835k相当の部分それぞれでビットレートが要求された「平均」(ここでは4000k)になるのを強要します。 そのため、基本的に動画を受け取るプログラムや末端の動画プレイヤーはそれだけのデータをメモリに確保するので、 その範囲で変動することは問題ではありません。

もちろん、入力のすべてが単にからや黒のフレームである場合には、 上記の例のような大きいビットレートの値でなくても間に合います。 ですが、エンコーダはcrfレベルまでの範囲で可能な限り画質レベルを上げるでしょう。

最大ビットレート付きのCRF

ffmpeg -i input -c:v libx264 -crf 20 -maxrate 400k -bufsize 1835k output.mp4

これは効果的にcrf20を目標としますが、 この場合、出力が400キロビット/秒を超えた場合にはcrf20未満に動画の品質を下げます。

低レイテンシ

libx264は「-tune zerolatency」オプションを提供しています。 ストリーミングガイドを参照してください。

互換性

すべてのデバイス

もしも動画に(古いiOSのバージョンやすべてのAndroid端末などの)再生対象のデバイスと最高の互換性を持たせたい場合には以下を使ってください。

-profile:v baseline -level 3.0

これはいくつかの先進的な特徴のある機能を無効にしますがよりよい互換性を提供します。 一般的にはこの設定をする必要はないでしょう (そしてそれゆえに「-profile:v」と「-level」を使うのは避けてください)。 しかし、もしもこの設定を使ったならば、 上位のプロファイルで同じ画質を達成するのに必要なビットレートと比較して、 かなりのビットレートの増加が起こるでしょう。

iOS

iOSとの互換性(ソース)
プロファイルレベルデバイスオプション
Baseline3.0すべて-profile:v baseline -level 3.0
Baseline3.1iPhone 3G以降、iPod toudh第2世第以降-profile:v baseline -level 3.1
Main3.1iPad(全機種)、Apple TV 2以降、iPhone 4以降-profile:v main -level 3.1
Main4.0Apple TV 3以降、iPad 2以降、iPhone 4s以降-profile:v main -level 4.0
High4.0Apple TV 3以降、iPad 2以降、iPhone 4s以降-profile:v high -level 4.0
High4.1iPad 2以降、iPhone 4s以降、iPhone 5c以降-profile:v high -level 4.1
High4.2iPad Air以降、iPhone 5s以降-profile:v high -level 4.2

Apple QuickTime

Apple QuickTimeは、H.264動画については、 4:2:0クロマサブサンプリングのYUV Planar色空間(「-pix_fmt yuv420p」を使ってください)のみをサポートしています。 追加の制約に関する情報についてはQuickTime互換のエンコーディングを参照してください。

訳注
上記リンクは現在リンク切れ。Internet Archive Wayback machineによるログはこちらから。

Blu-ray

x264を用いた専門のブルーレイディスクの作成を参照してください。

設定を事前に試す

出力がどのような見た目かについての大体の見解を素早く得るためには、 「-ss」と「-t」オプションを使って動画全体の代わりに適当な動画の一部をエンコードするのがよいです。

Web動画のための「faststart」オプション

もしもエンコードした動画をブラウザで視聴するつもりであれば、 「-movflags +faststart」を出力オプションとして追加することができます。 これは、動画の先頭にいくらかの情報を移動させ、 動画プレイヤーが動画を完全にダウンロードする前に動画の再生を開始することを可能にします。 動画をYouTubeのようなサービスで使うつもりであれば、このオプションは必要ありません。

カスタムプリセットファイル

「-fpre」または「-vpre」出力オプションを追加してください。

最初にFFmpegは以下に示す順番で「[引数].ffpreset」というファイル名のファイルを探します。

  1. 「$FFMPEG_DATADIR」で設定されているディレクトリ(設定されていなければ省略)
  2. 「$HOME/.ffmpeg」
  3. ビルド時の設定で定められたデータディレクトリ(普通は PREFIX/share/ffmpeg)
  4. 実行ファイルと同じ階層にあるffpresetsフォルダ(win32のみ)
例えば、引数が「libx264-1080p」であれば、探すファイル名は「libx264-1080p.ffpreset」となります。

FAQ

2-PassはCRFよりも良い画質を提供してくれますか?

いいえ。 ですが、2-Passは出力ファイルサイズをより正確に目標に近づけてはくれます。

なぜ「placebo」は時間の無駄なのですか?

「placebo」はとても長いエンコード時間がかかりますがよくても「veryslow」と比べて1%程度の向上しかありません。 これはだんだん小さくなっていくもので、 「veryslow」は「slower」と比べて約3%の向上、「slower」は「slow」と比べて約5%の向上、 そして、「slow」は「medium」と比べて約5から10%の向上があります。

なぜ私のロスレスは無劣化に見えないのですか?

RGBからYUV色空間への変換が原因です。 変換先がyuv444であればまだ無劣化に見えるはずです(そしてこれがデフォルト設定です)。

グラフィックカードはx264のエンコードをより高速にしてくれますか?

必ずしもそうではありません。 いくつかのlookahead演算のためにx264はOpenCLをサポートしています(リンク切れ)。 GPUを利用していうるプロプライエタリなエンコーダもいくつかあります。 しかし、おそらくエンコード速度はより早いですが、それらが十分に最適化されているということではありません。 そして、それらはごく平凡なx264よりも性能が悪いかもしれず、ことによるとより遅いかもしれません。 それに関係なく、libx264の外部では、今日のFFmpegはGPUエンコーディングの手段を何もサポートしていません。

賢くないプレイヤーのためのエンコーディング

QuickTimeやその他のほとんどのプレイヤーで出力した動画が再生されるようにするために、 「-pix_fmt yuv420p」オプションを使う必要があるでしょう。 それらのプレイヤーは4:2:0クロマサブサンプリングのYUV Planar色空間のH.264動画をサポートしているだけです。 さもなくば、入力の動画に依存して、 ffmpegはそれらのプレイヤーと互換性のないピクセルフォーマットを出力してしまうかもしれません。

追加資料