web-dev-qa-db-ja.com

ffmpegによるビデオ圧縮-一定の品質

Ffmpegを使用してさまざまなビットレートで10秒のビデオを圧縮しようとしています。私の目的は、同じビデオをさまざまな品質(非常に低いものから非常に高いものまで)で取得することです。オーディオ部分には触れたくないので、ビデオコーデックとしてH264を使用しています。次のCLIを使用しています。

ffmpeg -i input.mkv -c:v libx264 -b:v $j'k' -c:a copy output.mkv

$ jは150から4000まで変化します。

私の問題は、10秒のビデオを圧縮しても、品質が常に一定ではないことです。次に例を示します。ビットレートが非常に低い($ j = 150)場合、最初(0〜3秒)ではビデオは非常に貧弱ですが、最後(8〜10秒)では品質は適切です。その上、ビデオを見ている間、人は時間を通してこの品質の増加を見ることができます。誰かが私にこの現象を説明できますか?一定の品質を得るには?

ありがとう '

1
MarAja

@LordNeckbeardがすでに指摘しているように、一定のビットレートは一定の品質と同じではありません。実際、それはまったく逆です。ビデオシーケンスの特定の部分は他の部分よりもエンコードが簡単で(必要なビット数が少ないという意味で簡単です)、他の部分はそうではありません。簡単な部分にすべてのビットを費やすと、難しい部分にはそれらが不足することになります。

そこで、一定の品質が重要になります。 x264には Constant Rate Factor があり、まさにそれを実行します。より多くの背景情報が必要な場合は、リンクされた記事を読むことをお勧めします。基本的に、CRFの範囲は0(ロスレス、ベスト)から51(ワースト)です。 ±6のステップは、ビットレートのほぼ2倍または半分に相当します。

したがって、スクリプトを適応させるには、次のようなことを行うだけです。

for i in $(seq 0 5 51); do 
  ffmpeg -i input.mkv -c:v libx264 -crf $i -c:a copy output-$i.mkv
done

スケール自体は、私が誤解していない限り、品質の点で対数に近いため、seq呼び出しの代わりにそれに基づいてステップを計算できます。


ビットレートが非常に低い($ j = 150)場合、最初(0〜3秒)ではビデオは非常に貧弱ですが、最後(8〜10秒)では品質は適切です。その上、ビデオを見ている間、人は時間を通してこの品質の増加を見ることができます。誰かが私にこの現象を説明できますか?

一定のビットレートを実行することは、エンコーダにとって簡単な作業ではありません。使用する特定の値を指定します。 「毎秒150kBitをくれ」と言っても、エンコーダーは次のフレームで何をエンコードするのかさえ知りません。

それで、それはこのフレームにいくら費やすべきですか?次はいくらですか?上記のように、エンコードが簡単で数キロビットしかかからないフレームもあれば、それ以上かかるフレームもあります。しかし、エンコーダーは実際には、将来の画像に合わせてスケーリングするために、過去にエンコードされたものだけを見ることができます。 さまざまな画像タイプ も考慮に入れてください。

アルゴリズム的には、固定ビットレートを実行することは非常に困難であり、x264が提供するレート制御モードの中で最悪でもあります。特に短いクリップの場合、エンコーダーは2パスエンコーディングを実行しないと何が期待できるかわからないため、説明のとおり、品質が10秒間で大幅に変化することに気付くかもしれません。しかし、150 kBit/sは、とにかくある程度まともなサイズのビデオには実際には十分ではありません。

2
slhck