約30ギガバイトのビデオ(主にMP4、一部のMKVおよびwebm)があります。さまざまな入力コーデック(AACオーディオ; H264、VP8、 H265/HEVC、およびおそらく他のいくつかのビデオコーデック)。私の最も強力なシステムでは、低解像度のビデオのトランスコードには、ビデオの長さの2倍の時間がかかります。 Linuxではffmpeg
を引数ffmpeg -i input -c:v libvpx-vp9 -lossless 1 -c:a FLAC -preset veryslow output.mkv
とともに使用して、ハードウェアの支援なしでビデオをトランスコードします。しかし、最近、私の友人が自分のPC用にIntel i5 Kaby Lake CPUを入手し、ビデオをトランスコードすることを提案してくれました。 Wikipedia およびその references によると、新しいKaby Lake CPUは、すべての入力コーデックのハードウェアデコードと8ビットVP9のエンコードをサポートしています。だから私は2つの質問があります:
友人がMKVコンテナでビデオをVP9に、オーディオをFLACにトランスコードするために使用できるffmpeg
引数は何ですか?それらはWindowsで動作しますか?そうでない場合は、Windows 10-Linuxのデュアルブートを使用しているため、問題ありません。
最高の圧縮を得るには、veryslow
プリセットがまだ必要ですか?
この質問に対する答えを他の場所で見つけようとしましたが、H264やJPEGなどのコーデックをエンコードするための例しか見つかりませんでした。
2017年8月3日の更新:ユーザー林正浩による新しい回答によると、ffmpegはVAAPIを介したVP9エンコーディングをサポートするようになりました。私はまだこれをテストするために必要なハードウェアを持っていないので、私の答えは限られた助けになります。以下のソフトウェアでVP9をエンコードする方法についての私の元の答えを残しておきます。
何らかの理由で、FFmpegはIntelのQuickSyncハードウェアエンコーダーでのVP9エンコーディングをサポートしていません H.264とHEVCをサポートしていますが 。 FFmpegソースコードリポジトリを検索すると、無効になっていることすら問題ではなく、機能がまだ実装されていないことがわかります。ただし、将来のある時点で使用可能になった場合は、他のQuickSyncエンコーダーと同様の方法で使用できるはずです。-c:v vp9_qsv
の代わりに-c:v libvpx-vp9
のようなスイッチがその役割を果たします。
FFmpegコマンドラインの使用法はすべてのプラットフォームで同じですが、Windowsユーザーが2パスエンコードの最初のパスで出力に/dev/null
ではなくNUL
を使用する必要があることを知っている1つの注目すべき例外があります。ただし、1パスでロスレスを実行しているため、これが影響することはありません。
エンコードを高速化したい場合は、-speed
スイッチを使用してエンコード速度の値を設定することをお勧めします。推奨値は0から4までの数値で、0は本当に非常に遅いですが(x264では-preset placebo
と考えてくださいが、もっと悪いです)、高品質で4は高速ですが低品質です。 ffmpegはデフォルトで-speed 1
を使用します。これは、不可逆エンコーディングの品質と速度のトレードオフとして優れています。ただし、速度値を変えてロスレスエンコーディングをすばやくテストしたところ、ロスレスエンコーディングで-speed 1
から-speed 0
に移行すると、ファイルサイズが32%減少することに気付きました。ただし、エンコード時間は3倍になるため、0を使用する価値があるかどうかはあなた次第です。 -speed 4
によって生成されたファイルは、-speed 1
によって生成されたファイルよりもわずか1.1%大きく、43%高速にエンコードされました。したがって、ロスレスで-speed 0
が遅すぎる場合は、-speed 4
を使用することをお勧めします。
もう1つの重要なエンコーディングパフォーマンスの向上は、-threads
スイッチを使用してマルチスレッドをオンにすることです。 libvpxは複数のスレッドを自動的に使用しないため、これはユーザーが手動で設定する必要があります。また、-tile-columns
スイッチを使用してタイル列の数を設定する必要があります。このオプションにより、libvpxはビデオを複数のタイルに分割し、これらのタイルを並列にエンコードして、マルチスレッドを改善します。タイルの列とスレッドの量の推奨数は、 GoogleのVP9エンコーディングガイド の「タイルとスレッドの推奨事項」セクションにあります。ご覧のとおり、使用されるスレッドの数はタイルの数とともに増加します。つまり、使用可能なCPUコアの数によっては、サブHD解像度のビデオのエンコード中にプロセッサが完全に飽和しない場合があります。主に低解像度のビデオをエンコードする場合は、複数のファイルを同時にエンコードすることを検討してください。
ただし、VP9エンコーディングを高速化するさらに別の方法があります。-row mt 1
でオンにできる単一の列タイル内のマルチスレッドです。 。 4月4日(2017、こんにちは未来の人々)の時点で、それはlibvpxのリリースされたバージョンの一部ではありませんが、libvpx1.6.2にある可能性が高いです。次のリリースの前に試してみたい場合は、libvpxとffmpegの最近のgitバージョンをソースからコンパイルする必要があります。選択したディストリビューションについては FFmpegのコンパイルガイド に従ってください。ただし、リリースtarballをダウンロードして抽出する代わりに、git pull https://chromium.googlesource.com/webm/libvpx
を実行してください。
veryslow
プリセットに関しては、x264とx265でのみ使用されます。 libvpxは、-speed
スイッチに加えて、-quality best
、-quality good
、または-quality realtime
オプションを使用して、エンコーダーがフレームのエンコードに費やすことができる時間を定義します。デフォルトは-quality good
です。これは、-quality best
が非常に遅いため使用できず、-quality realtime
はビデオ通話やライブストリーミングなどのタイムクリティカルなアプリケーションに使用されることを目的としているためです。
現在、VAAPIを使用してFFmpegを構築することが可能です。これにより、サポートされているシステムで、Intel統合GPUでVP9をエンコードできます。
Ffmpegが VAAPIサポートでコンパイルされた の場合、新しいエンコーダーはvp9_vaapi
と呼ばれます。
エンコーダーの調整時に使用できるオプションを確認するには、次のコマンドを実行します。
ffmpeg -hide-banner -h encoder=vp9_vaapi
出力:
Encoder vp9_vaapi [VP9 (VAAPI)]:
General capabilities: delay
Threading capabilities: none
Supported pixel formats: vaapi_vld
vp9_vaapi AVOptions:
-loop_filter_level <int> E..V.... Loop filter level (from 0 to 63) (default 16)
-loop_filter_sharpness <int> E..V.... Loop filter sharpness (from 0 to 15) (default 4)
Skylakeのように、サポートされていないハードウェアでこれを実行しようとするとどうなりますか?
以下のサンプル出力を参照してください。
[Parsed_format_0 @ 0x42cb500] compat: called with args=[nv12]
[Parsed_format_0 @ 0x42cb500] Setting 'pix_fmts' to value 'nv12'
[Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'w' to value '1920'
[Parsed_scale_vaapi_2 @ 0x42cc300] Setting 'h' to value '1080'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'video_size' to value '3840x2026'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pix_fmt' to value '0'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'time_base' to value '1/1000'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'pixel_aspect' to value '1/1'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'sws_param' to value 'flags=2'
[graph 0 input from stream 0:0 @ 0x42cce00] Setting 'frame_rate' to value '24000/1001'
[graph 0 input from stream 0:0 @ 0x42cce00] w:3840 h:2026 pixfmt:yuv420p tb:1/1000 fr:24000/1001 sar:1/1 sws_param:flags=2
[format @ 0x42cba40] compat: called with args=[vaapi_vld]
[format @ 0x42cba40] Setting 'pix_fmts' to value 'vaapi_vld'
[auto_scaler_0 @ 0x42cd580] Setting 'flags' to value 'bicubic'
[auto_scaler_0 @ 0x42cd580] w:iw h:ih flags:'bicubic' interl:0
[Parsed_format_0 @ 0x42cb500] auto-inserting filter 'auto_scaler_0' between the filter 'graph 0 input from stream 0:0' and the filter 'Parsed_format_0'
[AVFilterGraph @ 0x42ca360] query_formats: 6 queried, 4 merged, 1 already done, 0 delayed
[auto_scaler_0 @ 0x42cd580] w:3840 h:2026 fmt:yuv420p sar:1/1 -> w:3840 h:2026 fmt:nv12 sar:1/1 flags:0x4
[hwupload @ 0x42cbcc0] Surface format is nv12.
[AVHWFramesContext @ 0x42ccbc0] Created surface 0x4000000.
[AVHWFramesContext @ 0x42ccbc0] Direct mapping possible.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000001.
[AVHWFramesContext @ 0x42c3e40] Direct mapping possible.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000002.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000003.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000004.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000005.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000006.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000007.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000008.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x4000009.
[AVHWFramesContext @ 0x42c3e40] Created surface 0x400000a.
[vp9_vaapi @ 0x409da40] Encoding entrypoint not found (19 / 6).
Error initializing output stream 0:0 -- Error while opening encoder for output stream #0:0 - maybe incorrect parameters such as bit_rate, rate, width or height
[AVIOContext @ 0x40fdac0] Statistics: 0 seeks, 0 writeouts
[aac @ 0x40fcb00] Qavg: -nan
[AVIOContext @ 0x409f820] Statistics: 32768 bytes read, 0 seeks
Conversion failed!
興味深いのは、vainfoの出力で確認されているように、この特定のプラットフォームにVP9エンコーディングがないことに対するエントリポイントの警告です。
libva info: VA-API version 0.40.0
libva info: va_getDriverName() returns 0
libva info: Trying to open /usr/local/lib/dri/i965_drv_video.so
libva info: Found init function __vaDriverInit_0_40
libva info: va_openDriver() returns 0
vainfo: VA-API version: 0.40 (libva 1.7.3)
vainfo: Driver version: Intel i965 driver for Intel(R) Skylake - 1.8.4.pre1 (glk-alpha-71-gc3110dc)
vainfo: Supported profile and entrypoints
VAProfileMPEG2Simple : VAEntrypointVLD
VAProfileMPEG2Simple : VAEntrypointEncSlice
VAProfileMPEG2Main : VAEntrypointVLD
VAProfileMPEG2Main : VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointVLD
VAProfileH264ConstrainedBaseline: VAEntrypointEncSlice
VAProfileH264ConstrainedBaseline: VAEntrypointEncSliceLP
VAProfileH264Main : VAEntrypointVLD
VAProfileH264Main : VAEntrypointEncSlice
VAProfileH264Main : VAEntrypointEncSliceLP
VAProfileH264High : VAEntrypointVLD
VAProfileH264High : VAEntrypointEncSlice
VAProfileH264High : VAEntrypointEncSliceLP
VAProfileH264MultiviewHigh : VAEntrypointVLD
VAProfileH264MultiviewHigh : VAEntrypointEncSlice
VAProfileH264StereoHigh : VAEntrypointVLD
VAProfileH264StereoHigh : VAEntrypointEncSlice
VAProfileVC1Simple : VAEntrypointVLD
VAProfileVC1Main : VAEntrypointVLD
VAProfileVC1Advanced : VAEntrypointVLD
VAProfileNone : VAEntrypointVideoProc
VAProfileJPEGBaseline : VAEntrypointVLD
VAProfileJPEGBaseline : VAEntrypointEncPicture
VAProfileVP8Version0_3 : VAEntrypointVLD
VAProfileVP8Version0_3 : VAEntrypointEncSlice
VAProfileHEVCMain : VAEntrypointVLD
VAProfileHEVCMain : VAEntrypointEncSlice
VAProfileVP9Profile0 : VAEntrypointVLD
VP9プロファイル0のVLD(可変長デコード用)エントリポイントは、VP9ハードウェアアクセラレーションの観点からSkylakeが最も遠いところにあります。
これらはKabylakeテストベッドで、これらのエンコードテストを実行して報告します:-)